From 8cc72361481f00253f1e468ade5795427386d593 Mon Sep 17 00:00:00 2001 From: Wai Yew CHAY Date: Thu, 14 May 2009 08:05:58 +0200 Subject: ALSA: SB X-Fi driver merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Sound Blaster X-Fi driver supports Creative solutions based on 20K1 and 20K2 chipsets. Supported hardware : Creative Sound Blaster X-Fi Titanium Fatal1ty® Champion Series Creative Sound Blaster X-Fi Titanium Fatal1ty Professional Series Creative Sound Blaster X-Fi Titanium Professional Audio Creative Sound Blaster X-Fi Titanium Creative Sound Blaster X-Fi Elite Pro Creative Sound Blaster X-Fi Platinum Creative Sound Blaster X-Fi Fatal1ty Creative Sound Blaster X-Fi XtremeGamer Creative Sound Blaster X-Fi XtremeMusic Current release features: * ALSA PCM Playback * ALSA Record * ALSA Mixer Note: * External I/O modules detection not included. Signed-off-by: Wai Yew CHAY Singed-off-by: Ryan RICHARDS Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/cthw20k1.c | 2230 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2230 insertions(+) create mode 100644 sound/pci/ctxfi/cthw20k1.c (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c new file mode 100644 index 000000000000..53572d92ef5d --- /dev/null +++ b/sound/pci/ctxfi/cthw20k1.c @@ -0,0 +1,2230 @@ +/** + * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. + * + * This source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + * @File cthw20k1.c + * + * @Brief + * This file contains the implementation of hardware access methord for 20k1. + * + * @Author Liu Chun + * @Date Jun 24 2008 + * + */ + +#include "cthw20k1.h" +#include "ct20k1reg.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bits */ + +struct hw20k1 { + struct hw hw; + spinlock_t reg_20k1_lock; + spinlock_t reg_pci_lock; +}; + +static u32 hw_read_20kx(struct hw *hw, u32 reg); +static void hw_write_20kx(struct hw *hw, u32 reg, u32 data); +static u32 hw_read_pci(struct hw *hw, u32 reg); +static void hw_write_pci(struct hw *hw, u32 reg, u32 data); + +/* + * Type definition block. + * The layout of control structures can be directly applied on 20k2 chip. + */ + +/* + * SRC control block definitions. + */ + +/* SRC resource control block */ +#define SRCCTL_STATE 0x00000007 +#define SRCCTL_BM 0x00000008 +#define SRCCTL_RSR 0x00000030 +#define SRCCTL_SF 0x000001C0 +#define SRCCTL_WR 0x00000200 +#define SRCCTL_PM 0x00000400 +#define SRCCTL_ROM 0x00001800 +#define SRCCTL_VO 0x00002000 +#define SRCCTL_ST 0x00004000 +#define SRCCTL_IE 0x00008000 +#define SRCCTL_ILSZ 0x000F0000 +#define SRCCTL_BP 0x00100000 + +#define SRCCCR_CISZ 0x000007FF +#define SRCCCR_CWA 0x001FF800 +#define SRCCCR_D 0x00200000 +#define SRCCCR_RS 0x01C00000 +#define SRCCCR_NAL 0x3E000000 +#define SRCCCR_RA 0xC0000000 + +#define SRCCA_CA 0x03FFFFFF +#define SRCCA_RS 0x1C000000 +#define SRCCA_NAL 0xE0000000 + +#define SRCSA_SA 0x03FFFFFF + +#define SRCLA_LA 0x03FFFFFF + +/* Mixer Parameter Ring ram Low and Hight register. + * Fixed-point value in 8.24 format for parameter channel */ +#define MPRLH_PITCH 0xFFFFFFFF + +/* SRC resource register dirty flags */ +union src_dirty { + struct { + u16 ctl:1; + u16 ccr:1; + u16 sa:1; + u16 la:1; + u16 ca:1; + u16 mpr:1; + u16 czbfs:1; /* Clear Z-Buffers */ + u16 rsv:9; + } bf; + u16 data; +}; + +struct src_rsc_ctrl_blk { + unsigned int ctl; + unsigned int ccr; + unsigned int ca; + unsigned int sa; + unsigned int la; + unsigned int mpr; + union src_dirty dirty; +}; + +/* SRC manager control block */ +union src_mgr_dirty { + struct { + u16 enb0:1; + u16 enb1:1; + u16 enb2:1; + u16 enb3:1; + u16 enb4:1; + u16 enb5:1; + u16 enb6:1; + u16 enb7:1; + u16 enbsa:1; + u16 rsv:7; + } bf; + u16 data; +}; + +struct src_mgr_ctrl_blk { + unsigned int enbsa; + unsigned int enb[8]; + union src_mgr_dirty dirty; +}; + +/* SRCIMP manager control block */ +#define SRCAIM_ARC 0x00000FFF +#define SRCAIM_NXT 0x00FF0000 +#define SRCAIM_SRC 0xFF000000 + +struct srcimap { + unsigned int srcaim; + unsigned int idx; +}; + +/* SRCIMP manager register dirty flags */ +union srcimp_mgr_dirty { + struct { + u16 srcimap:1; + u16 rsv:15; + } bf; + u16 data; +}; + +struct srcimp_mgr_ctrl_blk { + struct srcimap srcimap; + union srcimp_mgr_dirty dirty; +}; + +/* + * Function implementation block. + */ + +static int src_get_rsc_ctrl_blk(void **rblk) +{ + struct src_rsc_ctrl_blk *blk; + + *rblk = NULL; + blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + *rblk = blk; + + return 0; +} + +static int src_put_rsc_ctrl_blk(void *blk) +{ + kfree((struct src_rsc_ctrl_blk *)blk); + + return 0; +} + +static int src_set_state(void *blk, unsigned int state) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_STATE, state); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_bm(void *blk, unsigned int bm) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_BM, bm); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_rsr(void *blk, unsigned int rsr) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_RSR, rsr); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_sf(void *blk, unsigned int sf) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_SF, sf); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_wr(void *blk, unsigned int wr) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_WR, wr); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_pm(void *blk, unsigned int pm) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_PM, pm); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_rom(void *blk, unsigned int rom) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_ROM, rom); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_vo(void *blk, unsigned int vo) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_VO, vo); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_st(void *blk, unsigned int st) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_ST, st); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_ie(void *blk, unsigned int ie) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_IE, ie); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_ilsz(void *blk, unsigned int ilsz) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_ILSZ, ilsz); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_bp(void *blk, unsigned int bp) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ctl, SRCCTL_BP, bp); + ctl->dirty.bf.ctl = 1; + return 0; +} + +static int src_set_cisz(void *blk, unsigned int cisz) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ccr, SRCCCR_CISZ, cisz); + ctl->dirty.bf.ccr = 1; + return 0; +} + +static int src_set_ca(void *blk, unsigned int ca) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->ca, SRCCA_CA, ca); + ctl->dirty.bf.ca = 1; + return 0; +} + +static int src_set_sa(void *blk, unsigned int sa) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->sa, SRCSA_SA, sa); + ctl->dirty.bf.sa = 1; + return 0; +} + +static int src_set_la(void *blk, unsigned int la) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->la, SRCLA_LA, la); + ctl->dirty.bf.la = 1; + return 0; +} + +static int src_set_pitch(void *blk, unsigned int pitch) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->mpr, MPRLH_PITCH, pitch); + ctl->dirty.bf.mpr = 1; + return 0; +} + +static int src_set_clear_zbufs(void *blk, unsigned int clear) +{ + ((struct src_rsc_ctrl_blk *)blk)->dirty.bf.czbfs = (clear ? 1 : 0); + return 0; +} + +static int src_set_dirty(void *blk, unsigned int flags) +{ + ((struct src_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff); + return 0; +} + +static int src_set_dirty_all(void *blk) +{ + ((struct src_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0); + return 0; +} + +#define AR_SLOT_SIZE 4096 +#define AR_SLOT_BLOCK_SIZE 16 +#define AR_PTS_PITCH 6 +#define AR_PARAM_SRC_OFFSET 0x60 + +static unsigned int src_param_pitch_mixer(unsigned int src_idx) +{ + return ((src_idx << 4) + AR_PTS_PITCH + AR_SLOT_SIZE + - AR_PARAM_SRC_OFFSET) % AR_SLOT_SIZE; + +} + +static int src_commit_write(struct hw *hw, unsigned int idx, void *blk) +{ + struct src_rsc_ctrl_blk *ctl = blk; + int i = 0; + + if (ctl->dirty.bf.czbfs) { + /* Clear Z-Buffer registers */ + for (i = 0; i < 8; i++) + hw_write_20kx(hw, SRCUPZ+idx*0x100+i*0x4, 0); + + for (i = 0; i < 4; i++) + hw_write_20kx(hw, SRCDN0Z+idx*0x100+i*0x4, 0); + + for (i = 0; i < 8; i++) + hw_write_20kx(hw, SRCDN1Z+idx*0x100+i*0x4, 0); + + ctl->dirty.bf.czbfs = 0; + } + if (ctl->dirty.bf.mpr) { + /* Take the parameter mixer resource in the same group as that + * the idx src is in for simplicity. Unlike src, all conjugate + * parameter mixer resources must be programmed for + * corresponding conjugate src resources. */ + unsigned int pm_idx = src_param_pitch_mixer(idx); + hw_write_20kx(hw, PRING_LO_HI+4*pm_idx, ctl->mpr); + hw_write_20kx(hw, PMOPLO+8*pm_idx, 0x3); + hw_write_20kx(hw, PMOPHI+8*pm_idx, 0x0); + ctl->dirty.bf.mpr = 0; + } + if (ctl->dirty.bf.sa) { + hw_write_20kx(hw, SRCSA+idx*0x100, ctl->sa); + ctl->dirty.bf.sa = 0; + } + if (ctl->dirty.bf.la) { + hw_write_20kx(hw, SRCLA+idx*0x100, ctl->la); + ctl->dirty.bf.la = 0; + } + if (ctl->dirty.bf.ca) { + hw_write_20kx(hw, SRCCA+idx*0x100, ctl->ca); + ctl->dirty.bf.ca = 0; + } + + /* Write srccf register */ + hw_write_20kx(hw, SRCCF+idx*0x100, 0x0); + + if (ctl->dirty.bf.ccr) { + hw_write_20kx(hw, SRCCCR+idx*0x100, ctl->ccr); + ctl->dirty.bf.ccr = 0; + } + if (ctl->dirty.bf.ctl) { + hw_write_20kx(hw, SRCCTL+idx*0x100, ctl->ctl); + ctl->dirty.bf.ctl = 0; + } + + return 0; +} + +static int src_get_ca(struct hw *hw, unsigned int idx, void *blk) +{ + struct src_rsc_ctrl_blk *ctl = blk; + + ctl->ca = hw_read_20kx(hw, SRCCA+idx*0x100); + ctl->dirty.bf.ca = 0; + + return get_field(ctl->ca, SRCCA_CA); +} + +static unsigned int src_get_dirty(void *blk) +{ + return ((struct src_rsc_ctrl_blk *)blk)->dirty.data; +} + +static unsigned int src_dirty_conj_mask(void) +{ + return 0x20; +} + +static int src_mgr_enbs_src(void *blk, unsigned int idx) +{ + ((struct src_mgr_ctrl_blk *)blk)->enbsa = ~(0x0); + ((struct src_mgr_ctrl_blk *)blk)->dirty.bf.enbsa = 1; + ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32)); + return 0; +} + +static int src_mgr_enb_src(void *blk, unsigned int idx) +{ + ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32)); + ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32)); + return 0; +} + +static int src_mgr_dsb_src(void *blk, unsigned int idx) +{ + ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] &= ~(0x1 << (idx%32)); + ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32)); + return 0; +} + +static int src_mgr_commit_write(struct hw *hw, void *blk) +{ + struct src_mgr_ctrl_blk *ctl = blk; + int i = 0; + unsigned int ret = 0; + + if (ctl->dirty.bf.enbsa) { + do { + ret = hw_read_20kx(hw, SRCENBSTAT); + } while (ret & 0x1); + hw_write_20kx(hw, SRCENBS, ctl->enbsa); + ctl->dirty.bf.enbsa = 0; + } + for (i = 0; i < 8; i++) { + if ((ctl->dirty.data & (0x1 << i))) { + hw_write_20kx(hw, SRCENB+(i*0x100), ctl->enb[i]); + ctl->dirty.data &= ~(0x1 << i); + } + } + + return 0; +} + +static int src_mgr_get_ctrl_blk(void **rblk) +{ + struct src_mgr_ctrl_blk *blk; + + *rblk = NULL; + blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + *rblk = blk; + + return 0; +} + +static int src_mgr_put_ctrl_blk(void *blk) +{ + kfree((struct src_mgr_ctrl_blk *)blk); + + return 0; +} + +static int srcimp_mgr_get_ctrl_blk(void **rblk) +{ + struct srcimp_mgr_ctrl_blk *blk; + + *rblk = NULL; + blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + *rblk = blk; + + return 0; +} + +static int srcimp_mgr_put_ctrl_blk(void *blk) +{ + kfree((struct srcimp_mgr_ctrl_blk *)blk); + + return 0; +} + +static int srcimp_mgr_set_imaparc(void *blk, unsigned int slot) +{ + struct srcimp_mgr_ctrl_blk *ctl = blk; + + set_field(&ctl->srcimap.srcaim, SRCAIM_ARC, slot); + ctl->dirty.bf.srcimap = 1; + return 0; +} + +static int srcimp_mgr_set_imapuser(void *blk, unsigned int user) +{ + struct srcimp_mgr_ctrl_blk *ctl = blk; + + set_field(&ctl->srcimap.srcaim, SRCAIM_SRC, user); + ctl->dirty.bf.srcimap = 1; + return 0; +} + +static int srcimp_mgr_set_imapnxt(void *blk, unsigned int next) +{ + struct srcimp_mgr_ctrl_blk *ctl = blk; + + set_field(&ctl->srcimap.srcaim, SRCAIM_NXT, next); + ctl->dirty.bf.srcimap = 1; + return 0; +} + +static int srcimp_mgr_set_imapaddr(void *blk, unsigned int addr) +{ + struct srcimp_mgr_ctrl_blk *ctl = blk; + + ctl->srcimap.idx = addr; + ctl->dirty.bf.srcimap = 1; + return 0; +} + +static int srcimp_mgr_commit_write(struct hw *hw, void *blk) +{ + struct srcimp_mgr_ctrl_blk *ctl = blk; + + if (ctl->dirty.bf.srcimap) { + hw_write_20kx(hw, SRCIMAP+ctl->srcimap.idx*0x100, + ctl->srcimap.srcaim); + ctl->dirty.bf.srcimap = 0; + } + + return 0; +} + +/* + * AMIXER control block definitions. + */ + +#define AMOPLO_M 0x00000003 +#define AMOPLO_X 0x0003FFF0 +#define AMOPLO_Y 0xFFFC0000 + +#define AMOPHI_SADR 0x000000FF +#define AMOPHI_SE 0x80000000 + +/* AMIXER resource register dirty flags */ +union amixer_dirty { + struct { + u16 amoplo:1; + u16 amophi:1; + u16 rsv:14; + } bf; + u16 data; +}; + +/* AMIXER resource control block */ +struct amixer_rsc_ctrl_blk { + unsigned int amoplo; + unsigned int amophi; + union amixer_dirty dirty; +}; + +static int amixer_set_mode(void *blk, unsigned int mode) +{ + struct amixer_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->amoplo, AMOPLO_M, mode); + ctl->dirty.bf.amoplo = 1; + return 0; +} + +static int amixer_set_iv(void *blk, unsigned int iv) +{ + /* 20k1 amixer does not have this field */ + return 0; +} + +static int amixer_set_x(void *blk, unsigned int x) +{ + struct amixer_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->amoplo, AMOPLO_X, x); + ctl->dirty.bf.amoplo = 1; + return 0; +} + +static int amixer_set_y(void *blk, unsigned int y) +{ + struct amixer_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->amoplo, AMOPLO_Y, y); + ctl->dirty.bf.amoplo = 1; + return 0; +} + +static int amixer_set_sadr(void *blk, unsigned int sadr) +{ + struct amixer_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->amophi, AMOPHI_SADR, sadr); + ctl->dirty.bf.amophi = 1; + return 0; +} + +static int amixer_set_se(void *blk, unsigned int se) +{ + struct amixer_rsc_ctrl_blk *ctl = blk; + + set_field(&ctl->amophi, AMOPHI_SE, se); + ctl->dirty.bf.amophi = 1; + return 0; +} + +static int amixer_set_dirty(void *blk, unsigned int flags) +{ + ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff); + return 0; +} + +static int amixer_set_dirty_all(void *blk) +{ + ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0); + return 0; +} + +static int amixer_commit_write(struct hw *hw, unsigned int idx, void *blk) +{ + struct amixer_rsc_ctrl_blk *ctl = blk; + + if (ctl->dirty.bf.amoplo || ctl->dirty.bf.amophi) { + hw_write_20kx(hw, AMOPLO+idx*8, ctl->amoplo); + ctl->dirty.bf.amoplo = 0; + hw_write_20kx(hw, AMOPHI+idx*8, ctl->amophi); + ctl->dirty.bf.amophi = 0; + } + + return 0; +} + +static int amixer_get_y(void *blk) +{ + struct amixer_rsc_ctrl_blk *ctl = blk; + + return get_field(ctl->amoplo, AMOPLO_Y); +} + +static unsigned int amixer_get_dirty(void *blk) +{ + return ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data; +} + +static int amixer_rsc_get_ctrl_blk(void **rblk) +{ + struct amixer_rsc_ctrl_blk *blk; + + *rblk = NULL; + blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + *rblk = blk; + + return 0; +} + +static int amixer_rsc_put_ctrl_blk(void *blk) +{ + kfree((struct amixer_rsc_ctrl_blk *)blk); + + return 0; +} + +static int amixer_mgr_get_ctrl_blk(void **rblk) +{ + /*amixer_mgr_ctrl_blk_t *blk;*/ + + *rblk = NULL; + /*blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + *rblk = blk;*/ + + return 0; +} + +static int amixer_mgr_put_ctrl_blk(void *blk) +{ + /*kfree((amixer_mgr_ctrl_blk_t *)blk);*/ + + return 0; +} + +/* + * DAIO control block definitions. + */ + +/* Receiver Sample Rate Tracker Control register */ +#define SRTCTL_SRCR 0x000000FF +#define SRTCTL_SRCL 0x0000FF00 +#define SRTCTL_RSR 0x00030000 +#define SRTCTL_DRAT 0x000C0000 +#define SRTCTL_RLE 0x10000000 +#define SRTCTL_RLP 0x20000000 +#define SRTCTL_EC 0x40000000 +#define SRTCTL_ET 0x80000000 + +/* DAIO Receiver register dirty flags */ +union dai_dirty { + struct { + u16 srtctl:1; + u16 rsv:15; + } bf; + u16 data; +}; + +/* DAIO Receiver control block */ +struct dai_ctrl_blk { + unsigned int srtctl; + union dai_dirty dirty; +}; + +/* S/PDIF Transmitter register dirty flags */ +union dao_dirty { + struct { + u16 spos:1; + u16 rsv:15; + } bf; + u16 data; +}; + +/* S/PDIF Transmitter control block */ +struct dao_ctrl_blk { + unsigned int spos; /* S/PDIF Output Channel Status Register */ + union dao_dirty dirty; +}; + +/* Audio Input Mapper RAM */ +#define AIM_ARC 0x00000FFF +#define AIM_NXT 0x007F0000 + +struct daoimap { + unsigned int aim; + unsigned int idx; +}; + +/* I2S Transmitter/Receiver Control register */ +#define I2SCTL_EA 0x00000004 +#define I2SCTL_EI 0x00000010 + +/* S/PDIF Transmitter Control register */ +#define SPOCTL_OE 0x00000001 +#define SPOCTL_OS 0x0000000E +#define SPOCTL_RIV 0x00000010 +#define SPOCTL_LIV 0x00000020 +#define SPOCTL_SR 0x000000C0 + +/* S/PDIF Receiver Control register */ +#define SPICTL_EN 0x00000001 +#define SPICTL_I24 0x00000002 +#define SPICTL_IB 0x00000004 +#define SPICTL_SM 0x00000008 +#define SPICTL_VM 0x00000010 + +/* DAIO manager register dirty flags */ +union daio_mgr_dirty { + struct { + u32 i2soctl:4; + u32 i2sictl:4; + u32 spoctl:4; + u32 spictl:4; + u32 daoimap:1; + u32 rsv:15; + } bf; + u32 data; +}; + +/* DAIO manager control block */ +struct daio_mgr_ctrl_blk { + unsigned int i2sctl; + unsigned int spoctl; + unsigned int spictl; + struct daoimap daoimap; + union daio_mgr_dirty dirty; +}; + +static int dai_srt_set_srcr(void *blk, unsigned int src) +{ + struct dai_ctrl_blk *ctl = blk; + + set_field(&ctl->srtctl, SRTCTL_SRCR, src); + ctl->dirty.bf.srtctl = 1; + return 0; +} + +static int dai_srt_set_srcl(void *blk, unsigned int src) +{ + struct dai_ctrl_blk *ctl = blk; + + set_field(&ctl->srtctl, SRTCTL_SRCL, src); + ctl->dirty.bf.srtctl = 1; + return 0; +} + +static int dai_srt_set_rsr(void *blk, unsigned int rsr) +{ + struct dai_ctrl_blk *ctl = blk; + + set_field(&ctl->srtctl, SRTCTL_RSR, rsr); + ctl->dirty.bf.srtctl = 1; + return 0; +} + +static int dai_srt_set_drat(void *blk, unsigned int drat) +{ + struct dai_ctrl_blk *ctl = blk; + + set_field(&ctl->srtctl, SRTCTL_DRAT, drat); + ctl->dirty.bf.srtctl = 1; + return 0; +} + +static int dai_srt_set_ec(void *blk, unsigned int ec) +{ + struct dai_ctrl_blk *ctl = blk; + + set_field(&ctl->srtctl, SRTCTL_EC, ec ? 1 : 0); + ctl->dirty.bf.srtctl = 1; + return 0; +} + +static int dai_srt_set_et(void *blk, unsigned int et) +{ + struct dai_ctrl_blk *ctl = blk; + + set_field(&ctl->srtctl, SRTCTL_ET, et ? 1 : 0); + ctl->dirty.bf.srtctl = 1; + return 0; +} + +static int dai_commit_write(struct hw *hw, unsigned int idx, void *blk) +{ + struct dai_ctrl_blk *ctl = blk; + + if (ctl->dirty.bf.srtctl) { + if (idx < 4) { + /* S/PDIF SRTs */ + hw_write_20kx(hw, SRTSCTL+0x4*idx, ctl->srtctl); + } else { + /* I2S SRT */ + hw_write_20kx(hw, SRTICTL, ctl->srtctl); + } + ctl->dirty.bf.srtctl = 0; + } + + return 0; +} + +static int dai_get_ctrl_blk(void **rblk) +{ + struct dai_ctrl_blk *blk; + + *rblk = NULL; + blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + *rblk = blk; + + return 0; +} + +static int dai_put_ctrl_blk(void *blk) +{ + kfree((struct dai_ctrl_blk *)blk); + + return 0; +} + +static int dao_set_spos(void *blk, unsigned int spos) +{ + ((struct dao_ctrl_blk *)blk)->spos = spos; + ((struct dao_ctrl_blk *)blk)->dirty.bf.spos = 1; + return 0; +} + +static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk) +{ + struct dao_ctrl_blk *ctl = blk; + + if (ctl->dirty.bf.spos) { + if (idx < 4) { + /* S/PDIF SPOSx */ + hw_write_20kx(hw, SPOS+0x4*idx, ctl->spos); + } + ctl->dirty.bf.spos = 0; + } + + return 0; +} + +static int dao_get_spos(void *blk, unsigned int *spos) +{ + *spos = ((struct dao_ctrl_blk *)blk)->spos; + return 0; +} + +static int dao_get_ctrl_blk(void **rblk) +{ + struct dao_ctrl_blk *blk; + + *rblk = NULL; + blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + *rblk = blk; + + return 0; +} + +static int dao_put_ctrl_blk(void *blk) +{ + kfree((struct dao_ctrl_blk *)blk); + + return 0; +} + +static int daio_mgr_enb_dai(void *blk, unsigned int idx) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + if (idx < 4) { + /* S/PDIF input */ + set_field(&ctl->spictl, SPICTL_EN << (idx*8), 1); + ctl->dirty.bf.spictl |= (0x1 << idx); + } else { + /* I2S input */ + idx %= 4; + set_field(&ctl->i2sctl, I2SCTL_EI << (idx*8), 1); + ctl->dirty.bf.i2sictl |= (0x1 << idx); + } + return 0; +} + +static int daio_mgr_dsb_dai(void *blk, unsigned int idx) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + if (idx < 4) { + /* S/PDIF input */ + set_field(&ctl->spictl, SPICTL_EN << (idx*8), 0); + ctl->dirty.bf.spictl |= (0x1 << idx); + } else { + /* I2S input */ + idx %= 4; + set_field(&ctl->i2sctl, I2SCTL_EI << (idx*8), 0); + ctl->dirty.bf.i2sictl |= (0x1 << idx); + } + return 0; +} + +static int daio_mgr_enb_dao(void *blk, unsigned int idx) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + if (idx < 4) { + /* S/PDIF output */ + set_field(&ctl->spoctl, SPOCTL_OE << (idx*8), 1); + ctl->dirty.bf.spoctl |= (0x1 << idx); + } else { + /* I2S output */ + idx %= 4; + set_field(&ctl->i2sctl, I2SCTL_EA << (idx*8), 1); + ctl->dirty.bf.i2soctl |= (0x1 << idx); + } + return 0; +} + +static int daio_mgr_dsb_dao(void *blk, unsigned int idx) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + if (idx < 4) { + /* S/PDIF output */ + set_field(&ctl->spoctl, SPOCTL_OE << (idx*8), 0); + ctl->dirty.bf.spoctl |= (0x1 << idx); + } else { + /* I2S output */ + idx %= 4; + set_field(&ctl->i2sctl, I2SCTL_EA << (idx*8), 0); + ctl->dirty.bf.i2soctl |= (0x1 << idx); + } + return 0; +} + +static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + if (idx < 4) { + /* S/PDIF output */ + switch ((conf & 0x7)) { + case 0: + set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 3); + break; /* CDIF */ + case 1: + set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 0); + break; + case 2: + set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 1); + break; + case 4: + set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 2); + break; + default: + break; + } + set_field(&ctl->spoctl, SPOCTL_LIV << (idx*8), + (conf >> 4) & 0x1); /* Non-audio */ + set_field(&ctl->spoctl, SPOCTL_RIV << (idx*8), + (conf >> 4) & 0x1); /* Non-audio */ + set_field(&ctl->spoctl, SPOCTL_OS << (idx*8), + ((conf >> 3) & 0x1) ? 2 : 2); /* Raw */ + + ctl->dirty.bf.spoctl |= (0x1 << idx); + } else { + /* I2S output */ + /*idx %= 4; */ + } + return 0; +} + +static int daio_mgr_set_imaparc(void *blk, unsigned int slot) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + set_field(&ctl->daoimap.aim, AIM_ARC, slot); + ctl->dirty.bf.daoimap = 1; + return 0; +} + +static int daio_mgr_set_imapnxt(void *blk, unsigned int next) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + set_field(&ctl->daoimap.aim, AIM_NXT, next); + ctl->dirty.bf.daoimap = 1; + return 0; +} + +static int daio_mgr_set_imapaddr(void *blk, unsigned int addr) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + + ctl->daoimap.idx = addr; + ctl->dirty.bf.daoimap = 1; + return 0; +} + +static int daio_mgr_commit_write(struct hw *hw, void *blk) +{ + struct daio_mgr_ctrl_blk *ctl = blk; + int i = 0; + + if (ctl->dirty.bf.i2sictl || ctl->dirty.bf.i2soctl) { + for (i = 0; i < 4; i++) { + if ((ctl->dirty.bf.i2sictl & (0x1 << i))) + ctl->dirty.bf.i2sictl &= ~(0x1 << i); + + if ((ctl->dirty.bf.i2soctl & (0x1 << i))) + ctl->dirty.bf.i2soctl &= ~(0x1 << i); + } + hw_write_20kx(hw, I2SCTL, ctl->i2sctl); + mdelay(1); + } + if (ctl->dirty.bf.spoctl) { + for (i = 0; i < 4; i++) { + if ((ctl->dirty.bf.spoctl & (0x1 << i))) + ctl->dirty.bf.spoctl &= ~(0x1 << i); + } + hw_write_20kx(hw, SPOCTL, ctl->spoctl); + mdelay(1); + } + if (ctl->dirty.bf.spictl) { + for (i = 0; i < 4; i++) { + if ((ctl->dirty.bf.spictl & (0x1 << i))) + ctl->dirty.bf.spictl &= ~(0x1 << i); + } + hw_write_20kx(hw, SPICTL, ctl->spictl); + mdelay(1); + } + if (ctl->dirty.bf.daoimap) { + hw_write_20kx(hw, DAOIMAP+ctl->daoimap.idx*4, + ctl->daoimap.aim); + ctl->dirty.bf.daoimap = 0; + } + + return 0; +} + +static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) +{ + struct daio_mgr_ctrl_blk *blk; + + *rblk = NULL; + blk = kzalloc(sizeof(*blk), GFP_KERNEL); + if (NULL == blk) + return -ENOMEM; + + blk->i2sctl = hw_read_20kx(hw, I2SCTL); + blk->spoctl = hw_read_20kx(hw, SPOCTL); + blk->spictl = hw_read_20kx(hw, SPICTL); + + *rblk = blk; + + return 0; +} + +static int daio_mgr_put_ctrl_blk(void *blk) +{ + kfree((struct daio_mgr_ctrl_blk *)blk); + + return 0; +} + +/* Card hardware initialization block */ +struct dac_conf { + unsigned int msr; /* master sample rate in rsrs */ +}; + +struct adc_conf { + unsigned int msr; /* master sample rate in rsrs */ + unsigned char input; /* the input source of ADC */ + unsigned char mic20db; /* boost mic by 20db if input is microphone */ +}; + +struct daio_conf { + unsigned int msr; /* master sample rate in rsrs */ +}; + +struct trn_conf { + unsigned long vm_pgt_phys; +}; + +static int hw_daio_init(struct hw *hw, const struct daio_conf *info) +{ + u32 i2sorg = 0; + u32 spdorg = 0; + + /* Read I2S CTL. Keep original value. */ + /*i2sorg = hw_read_20kx(hw, I2SCTL);*/ + i2sorg = 0x94040404; /* enable all audio out and I2S-D input */ + /* Program I2S with proper master sample rate and enable + * the correct I2S channel. */ + i2sorg &= 0xfffffffc; + + /* Enable S/PDIF-out-A in fixed 24-bit data + * format and default to 48kHz. */ + /* Disable all before doing any changes. */ + hw_write_20kx(hw, SPOCTL, 0x0); + spdorg = 0x05; + + switch (info->msr) { + case 1: + i2sorg |= 1; + spdorg |= (0x0 << 6); + break; + case 2: + i2sorg |= 2; + spdorg |= (0x1 << 6); + break; + case 4: + i2sorg |= 3; + spdorg |= (0x2 << 6); + break; + default: + i2sorg |= 1; + break; + } + + hw_write_20kx(hw, I2SCTL, i2sorg); + hw_write_20kx(hw, SPOCTL, spdorg); + + /* Enable S/PDIF-in-A in fixed 24-bit data format. */ + /* Disable all before doing any changes. */ + hw_write_20kx(hw, SPICTL, 0x0); + mdelay(1); + spdorg = 0x0a0a0a0a; + hw_write_20kx(hw, SPICTL, spdorg); + mdelay(1); + + return 0; +} + +/* TRANSPORT operations */ +static int hw_trn_init(struct hw *hw, const struct trn_conf *info) +{ + u32 trnctl = 0; + unsigned long ptp_phys_low = 0, ptp_phys_high = 0; + + /* Set up device page table */ + if ((~0UL) == info->vm_pgt_phys) { + printk(KERN_ERR "Wrong device page table page address!\n"); + return -1; + } + + trnctl = 0x13; /* 32-bit, 4k-size page */ +#if BITS_PER_LONG == 64 + ptp_phys_low = info->vm_pgt_phys & ((1UL<<32)-1); + ptp_phys_high = (info->vm_pgt_phys>>32) & ((1UL<<32)-1); + trnctl |= (1<<2); +#elif BITS_PER_LONG == 32 + ptp_phys_low = info->vm_pgt_phys & (~0UL); + ptp_phys_high = 0; +#else +# error "Unknown BITS_PER_LONG!" +#endif +#if PAGE_SIZE == 8192 + trnctl |= (1<<5); +#endif + hw_write_20kx(hw, PTPALX, ptp_phys_low); + hw_write_20kx(hw, PTPAHX, ptp_phys_high); + hw_write_20kx(hw, TRNCTL, trnctl); + hw_write_20kx(hw, TRNIS, 0x200c01); /* realy needed? */ + + return 0; +} + +/* Card initialization */ +#define GCTL_EAC 0x00000001 +#define GCTL_EAI 0x00000002 +#define GCTL_BEP 0x00000004 +#define GCTL_BES 0x00000008 +#define GCTL_DSP 0x00000010 +#define GCTL_DBP 0x00000020 +#define GCTL_ABP 0x00000040 +#define GCTL_TBP 0x00000080 +#define GCTL_SBP 0x00000100 +#define GCTL_FBP 0x00000200 +#define GCTL_XA 0x00000400 +#define GCTL_ET 0x00000800 +#define GCTL_PR 0x00001000 +#define GCTL_MRL 0x00002000 +#define GCTL_SDE 0x00004000 +#define GCTL_SDI 0x00008000 +#define GCTL_SM 0x00010000 +#define GCTL_SR 0x00020000 +#define GCTL_SD 0x00040000 +#define GCTL_SE 0x00080000 +#define GCTL_AID 0x00100000 + +static int hw_pll_init(struct hw *hw, unsigned int rsr) +{ + unsigned int pllctl; + int i = 0; + + pllctl = (48000 == rsr) ? 0x1480a001 : 0x1480a731; + for (i = 0; i < 3; i++) { + if (hw_read_20kx(hw, PLLCTL) == pllctl) + break; + + hw_write_20kx(hw, PLLCTL, pllctl); + mdelay(40); + } + if (i >= 3) { + printk(KERN_ALERT "PLL initialization failed!!!\n"); + return -EBUSY; + } + + return 0; +} + +static int hw_auto_init(struct hw *hw) +{ + unsigned int gctl; + int i; + + gctl = hw_read_20kx(hw, GCTL); + set_field(&gctl, GCTL_EAI, 0); + hw_write_20kx(hw, GCTL, gctl); + set_field(&gctl, GCTL_EAI, 1); + hw_write_20kx(hw, GCTL, gctl); + mdelay(10); + for (i = 0; i < 400000; i++) { + gctl = hw_read_20kx(hw, GCTL); + if (get_field(gctl, GCTL_AID)) + break; + } + if (!get_field(gctl, GCTL_AID)) { + printk(KERN_ALERT "Card Auto-init failed!!!\n"); + return -EBUSY; + } + + return 0; +} + +static int i2c_unlock(struct hw *hw) +{ + if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa) + return 0; + + hw_write_pci(hw, 0xcc, 0x8c); + hw_write_pci(hw, 0xcc, 0x0e); + if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa) + return 0; + + hw_write_pci(hw, 0xcc, 0xee); + hw_write_pci(hw, 0xcc, 0xaa); + if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa) + return 0; + + return -1; +} + +static void i2c_lock(struct hw *hw) +{ + if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa) + hw_write_pci(hw, 0xcc, 0x00); +} + +static void i2c_write(struct hw *hw, u32 device, u32 addr, u32 data) +{ + unsigned int ret = 0; + + do { + ret = hw_read_pci(hw, 0xEC); + } while (!(ret & 0x800000)); + hw_write_pci(hw, 0xE0, device); + hw_write_pci(hw, 0xE4, (data << 8) | (addr & 0xff)); +} + +/* DAC operations */ + +static int hw_reset_dac(struct hw *hw) +{ + u32 i = 0; + u16 gpioorg = 0; + unsigned int ret = 0; + + if (i2c_unlock(hw)) + return -1; + + do { + ret = hw_read_pci(hw, 0xEC); + } while (!(ret & 0x800000)); + hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */ + + /* To be effective, need to reset the DAC twice. */ + for (i = 0; i < 2; i++) { + /* set gpio */ + mdelay(100); + gpioorg = (u16)hw_read_20kx(hw, GPIO); + gpioorg &= 0xfffd; + hw_write_20kx(hw, GPIO, gpioorg); + mdelay(1); + hw_write_20kx(hw, GPIO, gpioorg | 0x2); + } + + i2c_write(hw, 0x00180080, 0x01, 0x80); + i2c_write(hw, 0x00180080, 0x02, 0x10); + + i2c_lock(hw); + + return 0; +} + +static int hw_dac_init(struct hw *hw, const struct dac_conf *info) +{ + u32 data = 0; + u16 gpioorg = 0; + u16 subsys_id = 0; + unsigned int ret = 0; + + pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); + if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { + /* SB055x, unmute outputs */ + gpioorg = (u16)hw_read_20kx(hw, GPIO); + gpioorg &= 0xffbf; /* set GPIO6 to low */ + gpioorg |= 2; /* set GPIO1 to high */ + hw_write_20kx(hw, GPIO, gpioorg); + return 0; + } + + /* mute outputs */ + gpioorg = (u16)hw_read_20kx(hw, GPIO); + gpioorg &= 0xffbf; + hw_write_20kx(hw, GPIO, gpioorg); + + hw_reset_dac(hw); + + if (i2c_unlock(hw)) + return -1; + + hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */ + do { + ret = hw_read_pci(hw, 0xEC); + } while (!(ret & 0x800000)); + + switch (info->msr) { + case 1: + data = 0x24; + break; + case 2: + data = 0x25; + break; + case 4: + data = 0x26; + break; + default: + data = 0x24; + break; + } + + i2c_write(hw, 0x00180080, 0x06, data); + i2c_write(hw, 0x00180080, 0x09, data); + i2c_write(hw, 0x00180080, 0x0c, data); + i2c_write(hw, 0x00180080, 0x0f, data); + + i2c_lock(hw); + + /* unmute outputs */ + gpioorg = (u16)hw_read_20kx(hw, GPIO); + gpioorg = gpioorg | 0x40; + hw_write_20kx(hw, GPIO, gpioorg); + + return 0; +} + +/* ADC operations */ + +static int is_adc_input_selected_SB055x(struct hw *hw, enum ADCSRC type) +{ + u32 data = 0; + return data; +} + +static int is_adc_input_selected_SBx(struct hw *hw, enum ADCSRC type) +{ + u32 data = 0; + + data = hw_read_20kx(hw, GPIO); + switch (type) { + case ADC_MICIN: + data = ((data & (0x1<<7)) && (data & (0x1<<8))); + break; + case ADC_LINEIN: + data = (!(data & (0x1<<7)) && (data & (0x1<<8))); + break; + case ADC_NONE: /* Digital I/O */ + data = (!(data & (0x1<<8))); + break; + default: + data = 0; + } + return data; +} + +static int is_adc_input_selected_hendrix(struct hw *hw, enum ADCSRC type) +{ + u32 data = 0; + + data = hw_read_20kx(hw, GPIO); + switch (type) { + case ADC_MICIN: + data = (data & (0x1 << 7)) ? 1 : 0; + break; + case ADC_LINEIN: + data = (data & (0x1 << 7)) ? 0 : 1; + break; + default: + data = 0; + } + return data; +} + +static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) +{ + u16 subsys_id = 0; + + pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); + if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { + /* SB055x cards */ + return is_adc_input_selected_SB055x(hw, type); + } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) { + /* SB073x cards */ + return is_adc_input_selected_hendrix(hw, type); + } else if ((subsys_id & 0xf000) == 0x6000) { + /* Vista compatible cards */ + return is_adc_input_selected_hendrix(hw, type); + } else { + return is_adc_input_selected_SBx(hw, type); + } +} + +static int +adc_input_select_SB055x(struct hw *hw, enum ADCSRC type, unsigned char boost) +{ + u32 data = 0; + + /* + * check and set the following GPIO bits accordingly + * ADC_Gain = GPIO2 + * DRM_off = GPIO3 + * Mic_Pwr_on = GPIO7 + * Digital_IO_Sel = GPIO8 + * Mic_Sw = GPIO9 + * Aux/MicLine_Sw = GPIO12 + */ + data = hw_read_20kx(hw, GPIO); + data &= 0xec73; + switch (type) { + case ADC_MICIN: + data |= (0x1<<7) | (0x1<<8) | (0x1<<9) ; + data |= boost ? (0x1<<2) : 0; + break; + case ADC_LINEIN: + data |= (0x1<<8); + break; + case ADC_AUX: + data |= (0x1<<8) | (0x1<<12); + break; + case ADC_NONE: + data |= (0x1<<12); /* set to digital */ + break; + default: + return -1; + } + + hw_write_20kx(hw, GPIO, data); + + return 0; +} + + +static int +adc_input_select_SBx(struct hw *hw, enum ADCSRC type, unsigned char boost) +{ + u32 data = 0; + u32 i2c_data = 0; + unsigned int ret = 0; + + if (i2c_unlock(hw)) + return -1; + + do { + ret = hw_read_pci(hw, 0xEC); + } while (!(ret & 0x800000)); /* i2c ready poll */ + /* set i2c access mode as Direct Control */ + hw_write_pci(hw, 0xEC, 0x05); + + data = hw_read_20kx(hw, GPIO); + switch (type) { + case ADC_MICIN: + data |= ((0x1 << 7) | (0x1 << 8)); + i2c_data = 0x1; /* Mic-in */ + break; + case ADC_LINEIN: + data &= ~(0x1 << 7); + data |= (0x1 << 8); + i2c_data = 0x2; /* Line-in */ + break; + case ADC_NONE: + data &= ~(0x1 << 8); + i2c_data = 0x0; /* set to Digital */ + break; + default: + i2c_lock(hw); + return -1; + } + hw_write_20kx(hw, GPIO, data); + i2c_write(hw, 0x001a0080, 0x2a, i2c_data); + if (boost) { + i2c_write(hw, 0x001a0080, 0x1c, 0xe7); /* +12dB boost */ + i2c_write(hw, 0x001a0080, 0x1e, 0xe7); /* +12dB boost */ + } else { + i2c_write(hw, 0x001a0080, 0x1c, 0xcf); /* No boost */ + i2c_write(hw, 0x001a0080, 0x1e, 0xcf); /* No boost */ + } + + i2c_lock(hw); + + return 0; +} + +static int +adc_input_select_hendrix(struct hw *hw, enum ADCSRC type, unsigned char boost) +{ + u32 data = 0; + u32 i2c_data = 0; + unsigned int ret = 0; + + if (i2c_unlock(hw)) + return -1; + + do { + ret = hw_read_pci(hw, 0xEC); + } while (!(ret & 0x800000)); /* i2c ready poll */ + /* set i2c access mode as Direct Control */ + hw_write_pci(hw, 0xEC, 0x05); + + data = hw_read_20kx(hw, GPIO); + switch (type) { + case ADC_MICIN: + data |= (0x1 << 7); + i2c_data = 0x1; /* Mic-in */ + break; + case ADC_LINEIN: + data &= ~(0x1 << 7); + i2c_data = 0x2; /* Line-in */ + break; + default: + i2c_lock(hw); + return -1; + } + hw_write_20kx(hw, GPIO, data); + i2c_write(hw, 0x001a0080, 0x2a, i2c_data); + if (boost) { + i2c_write(hw, 0x001a0080, 0x1c, 0xe7); /* +12dB boost */ + i2c_write(hw, 0x001a0080, 0x1e, 0xe7); /* +12dB boost */ + } else { + i2c_write(hw, 0x001a0080, 0x1c, 0xcf); /* No boost */ + i2c_write(hw, 0x001a0080, 0x1e, 0xcf); /* No boost */ + } + + i2c_lock(hw); + + return 0; +} + +static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) +{ + u16 subsys_id = 0; + + pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); + if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { + /* SB055x cards */ + return adc_input_select_SB055x(hw, type, (ADC_MICIN == type)); + } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) { + /* SB073x cards */ + return adc_input_select_hendrix(hw, type, (ADC_MICIN == type)); + } else if ((subsys_id & 0xf000) == 0x6000) { + /* Vista compatible cards */ + return adc_input_select_hendrix(hw, type, (ADC_MICIN == type)); + } else { + return adc_input_select_SBx(hw, type, (ADC_MICIN == type)); + } +} + +static int adc_init_SB055x(struct hw *hw, int input, int mic20db) +{ + return adc_input_select_SB055x(hw, input, mic20db); +} + +static int adc_init_SBx(struct hw *hw, int input, int mic20db) +{ + u16 gpioorg; + u16 input_source; + u32 adcdata = 0; + unsigned int ret = 0; + + input_source = 0x100; /* default to analog */ + switch (input) { + case ADC_MICIN: + adcdata = 0x1; + input_source = 0x180; /* set GPIO7 to select Mic */ + break; + case ADC_LINEIN: + adcdata = 0x2; + break; + case ADC_VIDEO: + adcdata = 0x4; + break; + case ADC_AUX: + adcdata = 0x8; + break; + case ADC_NONE: + adcdata = 0x0; + input_source = 0x0; /* set to Digital */ + break; + default: + break; + } + + if (i2c_unlock(hw)) + return -1; + + do { + ret = hw_read_pci(hw, 0xEC); + } while (!(ret & 0x800000)); /* i2c ready poll */ + hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */ + + i2c_write(hw, 0x001a0080, 0x0e, 0x08); + i2c_write(hw, 0x001a0080, 0x18, 0x0a); + i2c_write(hw, 0x001a0080, 0x28, 0x86); + i2c_write(hw, 0x001a0080, 0x2a, adcdata); + + if (mic20db) { + i2c_write(hw, 0x001a0080, 0x1c, 0xf7); + i2c_write(hw, 0x001a0080, 0x1e, 0xf7); + } else { + i2c_write(hw, 0x001a0080, 0x1c, 0xcf); + i2c_write(hw, 0x001a0080, 0x1e, 0xcf); + } + + if (!(hw_read_20kx(hw, ID0) & 0x100)) + i2c_write(hw, 0x001a0080, 0x16, 0x26); + + i2c_lock(hw); + + gpioorg = (u16)hw_read_20kx(hw, GPIO); + gpioorg &= 0xfe7f; + gpioorg |= input_source; + hw_write_20kx(hw, GPIO, gpioorg); + + return 0; +} + +static int hw_adc_init(struct hw *hw, const struct adc_conf *info) +{ + int err = 0; + u16 subsys_id = 0; + + pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); + if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { + /* Sb055x card */ + err = adc_init_SB055x(hw, info->input, info->mic20db); + } else { + err = adc_init_SBx(hw, info->input, info->mic20db); + } + + return err; +} + +static int hw_have_digit_io_switch(struct hw *hw) +{ + u16 subsys_id = 0; + + pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); + /* SB073x and Vista compatible cards have no digit IO switch */ + return !((subsys_id == 0x0029) || (subsys_id == 0x0031) + || ((subsys_id & 0xf000) == 0x6000)); +} + +#define UAA_CFG_PWRSTATUS 0x44 +#define UAA_CFG_SPACE_FLAG 0xA0 +#define UAA_CORE_CHANGE 0x3FFC +static int uaa_to_xfi(struct pci_dev *pci) +{ + unsigned int bar0, bar1, bar2, bar3, bar4, bar5; + unsigned int cmd, irq, cl_size, l_timer, pwr; + unsigned int CTLA, CTLZ, CTLL, CTLX, CTL_, CTLF, CTLi; + unsigned int is_uaa = 0; + unsigned int data[4] = {0}; + unsigned int io_base; + void *mem_base; + int i = 0; + + /* By default, Hendrix card UAA Bar0 should be using memory... */ + io_base = pci_resource_start(pci, 0); + mem_base = ioremap(io_base, pci_resource_len(pci, 0)); + if (NULL == mem_base) + return -ENOENT; + + CTLX = ___constant_swab32(*((unsigned int *)"CTLX")); + CTL_ = ___constant_swab32(*((unsigned int *)"CTL-")); + CTLF = ___constant_swab32(*((unsigned int *)"CTLF")); + CTLi = ___constant_swab32(*((unsigned int *)"CTLi")); + CTLA = ___constant_swab32(*((unsigned int *)"CTLA")); + CTLZ = ___constant_swab32(*((unsigned int *)"CTLZ")); + CTLL = ___constant_swab32(*((unsigned int *)"CTLL")); + + /* Read current mode from Mode Change Register */ + for (i = 0; i < 4; i++) + data[i] = readl(mem_base + UAA_CORE_CHANGE); + + /* Determine current mode... */ + if (data[0] == CTLA) { + is_uaa = ((data[1] == CTLZ && data[2] == CTLL + && data[3] == CTLA) || (data[1] == CTLA + && data[2] == CTLZ && data[3] == CTLL)); + } else if (data[0] == CTLZ) { + is_uaa = (data[1] == CTLL + && data[2] == CTLA && data[3] == CTLA); + } else if (data[0] == CTLL) { + is_uaa = (data[1] == CTLA + && data[2] == CTLA && data[3] == CTLZ); + } else { + is_uaa = 0; + } + + if (!is_uaa) { + /* Not in UAA mode currently. Return directly. */ + iounmap(mem_base); + return 0; + } + + pci_read_config_dword(pci, PCI_BASE_ADDRESS_0, &bar0); + pci_read_config_dword(pci, PCI_BASE_ADDRESS_1, &bar1); + pci_read_config_dword(pci, PCI_BASE_ADDRESS_2, &bar2); + pci_read_config_dword(pci, PCI_BASE_ADDRESS_3, &bar3); + pci_read_config_dword(pci, PCI_BASE_ADDRESS_4, &bar4); + pci_read_config_dword(pci, PCI_BASE_ADDRESS_5, &bar5); + pci_read_config_dword(pci, PCI_INTERRUPT_LINE, &irq); + pci_read_config_dword(pci, PCI_CACHE_LINE_SIZE, &cl_size); + pci_read_config_dword(pci, PCI_LATENCY_TIMER, &l_timer); + pci_read_config_dword(pci, UAA_CFG_PWRSTATUS, &pwr); + pci_read_config_dword(pci, PCI_COMMAND, &cmd); + + /* Set up X-Fi core PCI configuration space. */ + /* Switch to X-Fi config space with BAR0 exposed. */ + pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x87654321); + /* Copy UAA's BAR5 into X-Fi BAR0 */ + pci_write_config_dword(pci, PCI_BASE_ADDRESS_0, bar5); + /* Switch to X-Fi config space without BAR0 exposed. */ + pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x12345678); + pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, bar1); + pci_write_config_dword(pci, PCI_BASE_ADDRESS_2, bar2); + pci_write_config_dword(pci, PCI_BASE_ADDRESS_3, bar3); + pci_write_config_dword(pci, PCI_BASE_ADDRESS_4, bar4); + pci_write_config_dword(pci, PCI_INTERRUPT_LINE, irq); + pci_write_config_dword(pci, PCI_CACHE_LINE_SIZE, cl_size); + pci_write_config_dword(pci, PCI_LATENCY_TIMER, l_timer); + pci_write_config_dword(pci, UAA_CFG_PWRSTATUS, pwr); + pci_write_config_dword(pci, PCI_COMMAND, cmd); + + /* Switch to X-Fi mode */ + writel(CTLX, (mem_base + UAA_CORE_CHANGE)); + writel(CTL_, (mem_base + UAA_CORE_CHANGE)); + writel(CTLF, (mem_base + UAA_CORE_CHANGE)); + writel(CTLi, (mem_base + UAA_CORE_CHANGE)); + + iounmap(mem_base); + + return 0; +} + +static int hw_card_start(struct hw *hw) +{ + int err = 0; + struct pci_dev *pci = hw->pci; + u16 subsys_id = 0; + unsigned int dma_mask = 0; + + err = pci_enable_device(pci); + if (err < 0) + return err; + + /* Set DMA transfer mask */ + dma_mask = CT_XFI_DMA_MASK; + if (pci_set_dma_mask(pci, dma_mask) < 0 || + pci_set_consistent_dma_mask(pci, dma_mask) < 0) { + printk(KERN_ERR "architecture does not support PCI " + "busmaster DMA with mask 0x%x\n", dma_mask); + err = -ENXIO; + goto error1; + } + + err = pci_request_regions(pci, "XFi"); + if (err < 0) + goto error1; + + /* Switch to X-Fi mode from UAA mode if neeeded */ + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsys_id); + if ((0x5 == pci->device) && (0x6000 == (subsys_id & 0x6000))) { + err = uaa_to_xfi(pci); + if (err) + goto error2; + + hw->io_base = pci_resource_start(pci, 5); + } else { + hw->io_base = pci_resource_start(pci, 0); + } + + /*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED, + atc->chip_details->nm_card, hw))) { + goto error2; + } + hw->irq = pci->irq; + */ + + pci_set_master(pci); + + return 0; + +error2: + pci_release_regions(pci); + hw->io_base = 0; +error1: + pci_disable_device(pci); + return err; +} + +static int hw_card_stop(struct hw *hw) +{ + /* TODO: Disable interrupt and so on... */ + return 0; +} + +static int hw_card_shutdown(struct hw *hw) +{ + if (hw->irq >= 0) + free_irq(hw->irq, hw); + + hw->irq = -1; + + if (NULL != ((void *)hw->mem_base)) + iounmap((void *)hw->mem_base); + + hw->mem_base = (unsigned long)NULL; + + if (hw->io_base) + pci_release_regions(hw->pci); + + hw->io_base = 0; + + pci_disable_device(hw->pci); + + return 0; +} + +static int hw_card_init(struct hw *hw, struct card_conf *info) +{ + int err; + unsigned int gctl; + u16 subsys_id = 0; + u32 data = 0; + struct dac_conf dac_info = {0}; + struct adc_conf adc_info = {0}; + struct daio_conf daio_info = {0}; + struct trn_conf trn_info = {0}; + + /* Get PCI io port base address and do Hendrix switch if needed. */ + if (!hw->io_base) { + err = hw_card_start(hw); + if (err) + return err; + } + + /* PLL init */ + err = hw_pll_init(hw, info->rsr); + if (err < 0) + return err; + + /* kick off auto-init */ + err = hw_auto_init(hw); + if (err < 0) + return err; + + /* Enable audio ring */ + gctl = hw_read_20kx(hw, GCTL); + set_field(&gctl, GCTL_EAC, 1); + set_field(&gctl, GCTL_DBP, 1); + set_field(&gctl, GCTL_TBP, 1); + set_field(&gctl, GCTL_FBP, 1); + set_field(&gctl, GCTL_ET, 1); + hw_write_20kx(hw, GCTL, gctl); + mdelay(10); + + /* Reset all global pending interrupts */ + hw_write_20kx(hw, GIE, 0); + /* Reset all SRC pending interrupts */ + hw_write_20kx(hw, SRCIP, 0); + mdelay(30); + + pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); + /* Detect the card ID and configure GPIO accordingly. */ + if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { + /* SB055x cards */ + hw_write_20kx(hw, GPIOCTL, 0x13fe); + } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) { + /* SB073x cards */ + hw_write_20kx(hw, GPIOCTL, 0x00e6); + } else if ((subsys_id & 0xf000) == 0x6000) { + /* Vista compatible cards */ + hw_write_20kx(hw, GPIOCTL, 0x00c2); + } else { + hw_write_20kx(hw, GPIOCTL, 0x01e6); + } + + trn_info.vm_pgt_phys = info->vm_pgt_phys; + err = hw_trn_init(hw, &trn_info); + if (err < 0) + return err; + + daio_info.msr = info->msr; + err = hw_daio_init(hw, &daio_info); + if (err < 0) + return err; + + dac_info.msr = info->msr; + err = hw_dac_init(hw, &dac_info); + if (err < 0) + return err; + + adc_info.msr = info->msr; + adc_info.input = ADC_LINEIN; + adc_info.mic20db = 0; + err = hw_adc_init(hw, &adc_info); + if (err < 0) + return err; + + data = hw_read_20kx(hw, SRCMCTL); + data |= 0x1; /* Enables input from the audio ring */ + hw_write_20kx(hw, SRCMCTL, data); + + return 0; +} + +static u32 hw_read_20kx(struct hw *hw, u32 reg) +{ + u32 value; + unsigned long flags; + + spin_lock_irqsave( + &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags); + outl(reg, hw->io_base + 0x0); + value = inl(hw->io_base + 0x4); + spin_unlock_irqrestore( + &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags); + + return value; +} + +static void hw_write_20kx(struct hw *hw, u32 reg, u32 data) +{ + unsigned long flags; + + spin_lock_irqsave( + &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags); + outl(reg, hw->io_base + 0x0); + outl(data, hw->io_base + 0x4); + spin_unlock_irqrestore( + &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags); + +} + +static u32 hw_read_pci(struct hw *hw, u32 reg) +{ + u32 value; + unsigned long flags; + + spin_lock_irqsave( + &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags); + outl(reg, hw->io_base + 0x10); + value = inl(hw->io_base + 0x14); + spin_unlock_irqrestore( + &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags); + + return value; +} + +static void hw_write_pci(struct hw *hw, u32 reg, u32 data) +{ + unsigned long flags; + + spin_lock_irqsave( + &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags); + outl(reg, hw->io_base + 0x10); + outl(data, hw->io_base + 0x14); + spin_unlock_irqrestore( + &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags); +} + +int create_20k1_hw_obj(struct hw **rhw) +{ + struct hw *hw; + struct hw20k1 *hw20k1; + + *rhw = NULL; + hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL); + if (NULL == hw20k1) + return -ENOMEM; + + spin_lock_init(&hw20k1->reg_20k1_lock); + spin_lock_init(&hw20k1->reg_pci_lock); + + hw = &hw20k1->hw; + + hw->io_base = 0; + hw->mem_base = (unsigned long)NULL; + hw->irq = -1; + + hw->card_init = hw_card_init; + hw->card_stop = hw_card_stop; + hw->pll_init = hw_pll_init; + hw->is_adc_source_selected = hw_is_adc_input_selected; + hw->select_adc_source = hw_adc_input_select; + hw->have_digit_io_switch = hw_have_digit_io_switch; + + hw->src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk; + hw->src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk; + hw->src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk; + hw->src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk; + hw->src_set_state = src_set_state; + hw->src_set_bm = src_set_bm; + hw->src_set_rsr = src_set_rsr; + hw->src_set_sf = src_set_sf; + hw->src_set_wr = src_set_wr; + hw->src_set_pm = src_set_pm; + hw->src_set_rom = src_set_rom; + hw->src_set_vo = src_set_vo; + hw->src_set_st = src_set_st; + hw->src_set_ie = src_set_ie; + hw->src_set_ilsz = src_set_ilsz; + hw->src_set_bp = src_set_bp; + hw->src_set_cisz = src_set_cisz; + hw->src_set_ca = src_set_ca; + hw->src_set_sa = src_set_sa; + hw->src_set_la = src_set_la; + hw->src_set_pitch = src_set_pitch; + hw->src_set_dirty = src_set_dirty; + hw->src_set_clear_zbufs = src_set_clear_zbufs; + hw->src_set_dirty_all = src_set_dirty_all; + hw->src_commit_write = src_commit_write; + hw->src_get_ca = src_get_ca; + hw->src_get_dirty = src_get_dirty; + hw->src_dirty_conj_mask = src_dirty_conj_mask; + hw->src_mgr_enbs_src = src_mgr_enbs_src; + hw->src_mgr_enb_src = src_mgr_enb_src; + hw->src_mgr_dsb_src = src_mgr_dsb_src; + hw->src_mgr_commit_write = src_mgr_commit_write; + + hw->srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk; + hw->srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk; + hw->srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc; + hw->srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser; + hw->srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt; + hw->srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr; + hw->srcimp_mgr_commit_write = srcimp_mgr_commit_write; + + hw->amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk; + hw->amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk; + hw->amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk; + hw->amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk; + hw->amixer_set_mode = amixer_set_mode; + hw->amixer_set_iv = amixer_set_iv; + hw->amixer_set_x = amixer_set_x; + hw->amixer_set_y = amixer_set_y; + hw->amixer_set_sadr = amixer_set_sadr; + hw->amixer_set_se = amixer_set_se; + hw->amixer_set_dirty = amixer_set_dirty; + hw->amixer_set_dirty_all = amixer_set_dirty_all; + hw->amixer_commit_write = amixer_commit_write; + hw->amixer_get_y = amixer_get_y; + hw->amixer_get_dirty = amixer_get_dirty; + + hw->dai_get_ctrl_blk = dai_get_ctrl_blk; + hw->dai_put_ctrl_blk = dai_put_ctrl_blk; + hw->dai_srt_set_srco = dai_srt_set_srcr; + hw->dai_srt_set_srcm = dai_srt_set_srcl; + hw->dai_srt_set_rsr = dai_srt_set_rsr; + hw->dai_srt_set_drat = dai_srt_set_drat; + hw->dai_srt_set_ec = dai_srt_set_ec; + hw->dai_srt_set_et = dai_srt_set_et; + hw->dai_commit_write = dai_commit_write; + + hw->dao_get_ctrl_blk = dao_get_ctrl_blk; + hw->dao_put_ctrl_blk = dao_put_ctrl_blk; + hw->dao_set_spos = dao_set_spos; + hw->dao_commit_write = dao_commit_write; + hw->dao_get_spos = dao_get_spos; + + hw->daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk; + hw->daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk; + hw->daio_mgr_enb_dai = daio_mgr_enb_dai; + hw->daio_mgr_dsb_dai = daio_mgr_dsb_dai; + hw->daio_mgr_enb_dao = daio_mgr_enb_dao; + hw->daio_mgr_dsb_dao = daio_mgr_dsb_dao; + hw->daio_mgr_dao_init = daio_mgr_dao_init; + hw->daio_mgr_set_imaparc = daio_mgr_set_imaparc; + hw->daio_mgr_set_imapnxt = daio_mgr_set_imapnxt; + hw->daio_mgr_set_imapaddr = daio_mgr_set_imapaddr; + hw->daio_mgr_commit_write = daio_mgr_commit_write; + + *rhw = hw; + + return 0; +} + +int destroy_20k1_hw_obj(struct hw *hw) +{ + if (hw->io_base) + hw_card_shutdown(hw); + + kfree(container_of(hw, struct hw20k1, hw)); + return 0; +} -- cgit v1.2.3 From d0da727e025da8b443a4a614dbb7a031b89857d0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 May 2009 10:56:04 +0200 Subject: ALSA: ctxfi - Add missing inclusion of linux/delay.h Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/cthw20k1.c | 1 + sound/pci/ctxfi/cthw20k2.c | 1 + 2 files changed, 2 insertions(+) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 53572d92ef5d..44283bd7b2df 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -25,6 +25,7 @@ #include #include #include +#include #define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bits */ diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index cdcb75cc33b6..9c2d38b4faa1 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -24,6 +24,7 @@ #include #include #include +#include #define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bits */ -- cgit v1.2.3 From cd391e206f486955e216a61bd9ebcb0e142122e9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 2 Jun 2009 15:04:29 +0200 Subject: ALSA: ctxfi - Remove PAGE_SIZE limitation Remove the limitation of PAGE_SIZE to be 4k by defining the own page size and macros for 4k. 8kb page size could be natively supported, but it's disabled right now for simplicity. Also, clean up using upper_32_bits() macro. Signed-off-by: Takashi Iwai --- sound/pci/Kconfig | 1 - sound/pci/ctxfi/cthw20k1.c | 16 ++++++---------- sound/pci/ctxfi/cthw20k2.c | 17 ++++------------- sound/pci/ctxfi/ctvmem.c | 25 ++++++++++++------------- sound/pci/ctxfi/ctvmem.h | 8 ++++++++ 5 files changed, 30 insertions(+), 37 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 2d7fef5df017..3a7640feaf92 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -277,7 +277,6 @@ config SND_CS5535AUDIO config SND_CTXFI tristate "Creative Sound Blaster X-Fi" - depends on X86 select SND_PCM help If you want to use soundcards based on Creative Sound Blastr X-Fi diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 44283bd7b2df..b7b8e6f41d0d 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1249,18 +1249,14 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) } trnctl = 0x13; /* 32-bit, 4k-size page */ -#if BITS_PER_LONG == 64 - ptp_phys_low = info->vm_pgt_phys & ((1UL<<32)-1); - ptp_phys_high = (info->vm_pgt_phys>>32) & ((1UL<<32)-1); - trnctl |= (1<<2); -#elif BITS_PER_LONG == 32 - ptp_phys_low = info->vm_pgt_phys & (~0UL); - ptp_phys_high = 0; -#else -# error "Unknown BITS_PER_LONG!" -#endif + ptp_phys_low = (u32)info->vm_pgt_phys; + ptp_phys_high = upper_32_bits(info->vm_pgt_phys); + if (sizeof(void *) == 8) /* 64bit address */ + trnctl |= (1 << 2); +#if 0 /* Only 4k h/w pages for simplicitiy */ #if PAGE_SIZE == 8192 trnctl |= (1<<5); +#endif #endif hw_write_20kx(hw, PTPALX, ptp_phys_low); hw_write_20kx(hw, PTPAHX, ptp_phys_high); diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 7c24c2ca96bd..349728765f2c 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -1203,19 +1203,10 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) } vmctl = 0x80000C0F; /* 32-bit, 4k-size page */ -#if BITS_PER_LONG == 64 - ptp_phys_low = info->vm_pgt_phys & ((1UL<<32)-1); - ptp_phys_high = (info->vm_pgt_phys>>32) & ((1UL<<32)-1); - vmctl |= (3<<8); -#elif BITS_PER_LONG == 32 - ptp_phys_low = info->vm_pgt_phys & (~0UL); - ptp_phys_high = 0; -#else -# error "Unknown BITS_PER_LONG!" -#endif -#if PAGE_SIZE == 8192 -# error "Don't support 8k-page!" -#endif + ptp_phys_low = (u32)info->vm_pgt_phys; + ptp_phys_high = upper_32_bits(info->vm_pgt_phys); + if (sizeof(void *) == 8) /* 64bit address */ + vmctl |= (3 << 8); /* Write page table physical address to all PTPAL registers */ for (i = 0; i < 64; i++) { hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low); diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index 363b67e3a9e7..74a03623d047 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c @@ -18,12 +18,11 @@ #include "ctvmem.h" #include #include -#include /* for PAGE_SIZE macro definition */ #include #include -#define CT_PTES_PER_PAGE (PAGE_SIZE / sizeof(void *)) -#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * PAGE_SIZE) +#define CT_PTES_PER_PAGE (CT_PAGE_SIZE / sizeof(void *)) +#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * CT_PAGE_SIZE) /* * * Find or create vm block based on requested @size. @@ -138,24 +137,24 @@ ct_vm_map(struct ct_vm *vm, void *host_addr, int size) return NULL; } - start_phys = (virt_to_phys(host_addr) & PAGE_MASK); - pages = (PAGE_ALIGN(virt_to_phys(host_addr) + size) - - start_phys) >> PAGE_SHIFT; + start_phys = (virt_to_phys(host_addr) & CT_PAGE_MASK); + pages = (CT_PAGE_ALIGN(virt_to_phys(host_addr) + size) + - start_phys) >> CT_PAGE_SHIFT; ptp = vm->ptp[0]; - block = get_vm_block(vm, (pages << PAGE_SHIFT)); + block = get_vm_block(vm, (pages << CT_PAGE_SHIFT)); if (block == NULL) { printk(KERN_ERR "ctxfi: No virtual memory block that is big " "enough to allocate!\n"); return NULL; } - pte_start = (block->addr >> PAGE_SHIFT); + pte_start = (block->addr >> CT_PAGE_SHIFT); for (i = 0; i < pages; i++) - ptp[pte_start+i] = start_phys + (i << PAGE_SHIFT); + ptp[pte_start+i] = start_phys + (i << CT_PAGE_SHIFT); - block->addr += (virt_to_phys(host_addr) & (~PAGE_MASK)); + block->addr += (virt_to_phys(host_addr) & (~CT_PAGE_MASK)); block->size = size; return block; @@ -164,9 +163,9 @@ ct_vm_map(struct ct_vm *vm, void *host_addr, int size) static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block) { /* do unmapping */ - block->size = ((block->addr + block->size + PAGE_SIZE - 1) - & PAGE_MASK) - (block->addr & PAGE_MASK); - block->addr &= PAGE_MASK; + block->size = ((block->addr + block->size + CT_PAGE_SIZE - 1) + & CT_PAGE_MASK) - (block->addr & CT_PAGE_MASK); + block->addr &= CT_PAGE_MASK; put_vm_block(vm, block); } diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h index 618952efa5b3..17d2d37a9ea7 100644 --- a/sound/pci/ctxfi/ctvmem.h +++ b/sound/pci/ctxfi/ctvmem.h @@ -23,6 +23,14 @@ #include #include +/* The chip can handle the page table of 4k pages + * (emu20k1 can handle even 8k pages, but we don't use it right now) + */ +#define CT_PAGE_SIZE 4096 +#define CT_PAGE_SHIFT 12 +#define CT_PAGE_MASK (~(PAGE_SIZE - 1)) +#define CT_PAGE_ALIGN(addr) ALIGN(addr, CT_PAGE_SIZE) + struct ct_vm_block { unsigned int addr; /* starting logical addr of this block */ unsigned int size; /* size of this device virtual mem block */ -- cgit v1.2.3 From 6d74b86d3c0f9cfa949566a862aaad840e393249 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 5 Jun 2009 09:26:41 +0200 Subject: ALSA: ctxfi - Allow 64bit DMA emu20kx chips support 64bit address PTE. Allow the DMA bit mask to accept 64bit address, too. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/cthw20k1.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index b7b8e6f41d0d..1da1f82fe812 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -15,8 +15,6 @@ * */ -#include "cthw20k1.h" -#include "ct20k1reg.h" #include #include #include @@ -26,8 +24,14 @@ #include #include #include +#include "cthw20k1.h" +#include "ct20k1reg.h" -#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bits */ +#if BITS_PER_LONG == 32 +#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */ +#else +#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */ +#endif struct hw20k1 { struct hw hw; -- cgit v1.2.3 From 42a0b31827e4c555efebda7d347cf4ea6b82913a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 5 Jun 2009 09:29:22 +0200 Subject: ALSA: ctxfi - Fix endian-dependent codes The UAA-mode check in hwct20k1.c is implemented with the endian-dependent codes. Fix to be more portable (and readable). Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/cthw20k1.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 1da1f82fe812..fd5f454c4040 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1785,6 +1785,8 @@ static int hw_have_digit_io_switch(struct hw *hw) || ((subsys_id & 0xf000) == 0x6000)); } +#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) + #define UAA_CFG_PWRSTATUS 0x44 #define UAA_CFG_SPACE_FLAG 0xA0 #define UAA_CORE_CHANGE 0x3FFC @@ -1792,12 +1794,18 @@ static int uaa_to_xfi(struct pci_dev *pci) { unsigned int bar0, bar1, bar2, bar3, bar4, bar5; unsigned int cmd, irq, cl_size, l_timer, pwr; - unsigned int CTLA, CTLZ, CTLL, CTLX, CTL_, CTLF, CTLi; unsigned int is_uaa = 0; unsigned int data[4] = {0}; unsigned int io_base; void *mem_base; int i = 0; + const u32 CTLX = CTLBITS('C', 'T', 'L', 'X'); + const u32 CTL_ = CTLBITS('C', 'T', 'L', '-'); + const u32 CTLF = CTLBITS('C', 'T', 'L', 'F'); + const u32 CTLi = CTLBITS('C', 'T', 'L', 'i'); + const u32 CTLA = CTLBITS('C', 'T', 'L', 'A'); + const u32 CTLZ = CTLBITS('C', 'T', 'L', 'Z'); + const u32 CTLL = CTLBITS('C', 'T', 'L', 'L'); /* By default, Hendrix card UAA Bar0 should be using memory... */ io_base = pci_resource_start(pci, 0); @@ -1805,14 +1813,6 @@ static int uaa_to_xfi(struct pci_dev *pci) if (NULL == mem_base) return -ENOENT; - CTLX = ___constant_swab32(*((unsigned int *)"CTLX")); - CTL_ = ___constant_swab32(*((unsigned int *)"CTL-")); - CTLF = ___constant_swab32(*((unsigned int *)"CTLF")); - CTLi = ___constant_swab32(*((unsigned int *)"CTLi")); - CTLA = ___constant_swab32(*((unsigned int *)"CTLA")); - CTLZ = ___constant_swab32(*((unsigned int *)"CTLZ")); - CTLL = ___constant_swab32(*((unsigned int *)"CTLL")); - /* Read current mode from Mode Change Register */ for (i = 0; i < 4; i++) data[i] = readl(mem_base + UAA_CORE_CHANGE); -- cgit v1.2.3 From 6bc5874a1ddf98ac0fe6c4eab7d286c11cb1c748 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 5 Jun 2009 12:15:51 +0200 Subject: ALSA: ctxfi - Fix previous fix for 64bit DMA Remove unneeded substitution to 32bit int to make it really working. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/cthw20k1.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index fd5f454c4040..e530a6d60422 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1883,18 +1883,17 @@ static int hw_card_start(struct hw *hw) int err = 0; struct pci_dev *pci = hw->pci; u16 subsys_id = 0; - unsigned int dma_mask = 0; err = pci_enable_device(pci); if (err < 0) return err; /* Set DMA transfer mask */ - dma_mask = CT_XFI_DMA_MASK; - if (pci_set_dma_mask(pci, dma_mask) < 0 || - pci_set_consistent_dma_mask(pci, dma_mask) < 0) { + if (pci_set_dma_mask(pci, CT_XFI_DMA_MASK) < 0 || + pci_set_consistent_dma_mask(pci, CT_XFI_DMA_MASK) < 0) { printk(KERN_ERR "architecture does not support PCI " - "busmaster DMA with mask 0x%x\n", dma_mask); + "busmaster DMA with mask 0x%llx\n", + CT_XFI_DMA_MASK); err = -ENXIO; goto error1; } -- cgit v1.2.3 From b7bbf876087e0e2c0ba723a8398083c9a9ac1dfd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 5 Jun 2009 16:11:07 +0200 Subject: ALSA: ctxfi - Use native timer interrupt on emu20k1 emu20k1 has a native timer interrupt based on the audio clock, which is more accurate than the system timer (from the synchronization POV). This patch adds the code to handle this with multiple streams. The system timer is still used on emu20k2, and can be used also for emu20k1 easily by changing USE_SYSTEM_TIMER to 1 in cttimer.c. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/Makefile | 2 +- sound/pci/ctxfi/ct20k1reg.h | 2 + sound/pci/ctxfi/ctatc.c | 21 ++- sound/pci/ctxfi/ctatc.h | 9 +- sound/pci/ctxfi/cthardware.h | 19 ++ sound/pci/ctxfi/cthw20k1.c | 43 ++++- sound/pci/ctxfi/ctpcm.c | 106 ++--------- sound/pci/ctxfi/cttimer.c | 417 +++++++++++++++++++++++++++++++++++++++++++ sound/pci/ctxfi/cttimer.h | 29 +++ 9 files changed, 543 insertions(+), 105 deletions(-) create mode 100644 sound/pci/ctxfi/cttimer.c create mode 100644 sound/pci/ctxfi/cttimer.h (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/Makefile b/sound/pci/ctxfi/Makefile index 29043237f9f8..15075f89e98a 100644 --- a/sound/pci/ctxfi/Makefile +++ b/sound/pci/ctxfi/Makefile @@ -1,5 +1,5 @@ snd-ctxfi-objs := xfi.o ctatc.o ctvmem.o ctpcm.o ctmixer.o ctresource.o \ - ctsrc.o ctamixer.o ctdaio.o ctimap.o cthardware.o \ + ctsrc.o ctamixer.o ctdaio.o ctimap.o cthardware.o cttimer.o \ cthw20k2.o cthw20k1.o obj-$(CONFIG_SND_CTXFI) += snd-ctxfi.o diff --git a/sound/pci/ctxfi/ct20k1reg.h b/sound/pci/ctxfi/ct20k1reg.h index c62e6775dab3..f2e34e3f27ee 100644 --- a/sound/pci/ctxfi/ct20k1reg.h +++ b/sound/pci/ctxfi/ct20k1reg.h @@ -589,6 +589,8 @@ #define WC 0x1C6000 #define TIMR 0x1C6004 +# define TIMR_IE (1<<15) +# define TIMR_IP (1<<14) #define GIP 0x1C6010 #define GIE 0x1C6014 diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 684947546d81..10b741977dd7 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -22,6 +22,7 @@ #include "ctsrc.h" #include "ctamixer.h" #include "ctdaio.h" +#include "cttimer.h" #include #include #include @@ -307,6 +308,8 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) src = apcm->src; } + ct_timer_prepare(apcm->timer); + return 0; error1: @@ -389,6 +392,7 @@ static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm) src->ops->set_state(src, SRC_STATE_INIT); src->ops->commit_write(src); + ct_timer_start(apcm->timer); return 0; } @@ -397,6 +401,8 @@ static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct src *src = NULL; int i = 0; + ct_timer_stop(apcm->timer); + src = apcm->src; src->ops->set_bm(src, 0); src->ops->set_state(src, SRC_STATE_OFF); @@ -701,6 +707,8 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) } } + ct_timer_prepare(apcm->timer); + return 0; } @@ -749,6 +757,7 @@ static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm) /* Enable relevant SRCs synchronously */ src_mgr->commit_write(src_mgr); + ct_timer_start(apcm->timer); return 0; } @@ -906,6 +915,8 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) dao->ops->set_right_input(dao, &amixer->rsc); spin_unlock_irqrestore(&atc->atc_lock, flags); + ct_timer_prepare(apcm->timer); + return 0; } @@ -1100,6 +1111,11 @@ static int ct_atc_destroy(struct ct_atc *atc) if (NULL == atc) return 0; + if (atc->timer) { + ct_timer_free(atc->timer); + atc->timer = NULL; + } + /* Stop hardware and disable all interrupts */ if (NULL != atc->hw) ((struct hw *)atc->hw)->card_stop(atc->hw); @@ -1586,6 +1602,10 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci, /* Build topology */ atc_connect_resources(atc); + atc->timer = ct_timer_new(atc); + if (!atc->timer) + goto error1; + atc->create_alsa_devs = ct_create_alsa_devs; err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); @@ -1602,4 +1622,3 @@ error1: printk(KERN_ERR "ctxfi: Something wrong!!!\n"); return err; } - diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index b86d12cd4a19..a3f9b1bc7dcc 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -59,16 +59,15 @@ struct ct_atc_chip_details { }; struct ct_atc; +struct ct_timer; +struct ct_timer_instance; /* alsa pcm stream descriptor */ struct ct_atc_pcm { struct snd_pcm_substream *substream; void (*interrupt)(struct ct_atc_pcm *apcm); + struct ct_timer_instance *timer; unsigned int started:1; - unsigned int stop_timer:1; - struct timer_list timer; - spinlock_t timer_lock; - unsigned int position; /* Only mono and interleaved modes are supported now. */ struct ct_vm_block *vm_block; @@ -144,6 +143,8 @@ struct ct_atc { unsigned char n_src; unsigned char n_srcimp; unsigned char n_pcm; + + struct ct_timer *timer; }; diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h index b0512df8b334..35350cf9d2f2 100644 --- a/sound/pci/ctxfi/cthardware.h +++ b/sound/pci/ctxfi/cthardware.h @@ -145,6 +145,12 @@ struct hw { int (*daio_mgr_set_imapaddr)(void *blk, unsigned int addr); int (*daio_mgr_commit_write)(struct hw *hw, void *blk); + int (*set_timer_irq)(struct hw *hw, int enable); + int (*set_timer_tick)(struct hw *hw, unsigned int tick); + + void (*irq_callback)(void *data, unsigned int bit); + void *irq_callback_data; + struct pci_dev *pci; /* the pci kernel structure of this card */ int irq; unsigned long io_base; @@ -157,4 +163,17 @@ int destroy_hw_obj(struct hw *hw); unsigned int get_field(unsigned int data, unsigned int field); void set_field(unsigned int *data, unsigned int field, unsigned int value); +/* IRQ bits */ +#define PLL_INT (1 << 10) /* PLL input-clock out-of-range */ +#define FI_INT (1 << 9) /* forced interrupt */ +#define IT_INT (1 << 8) /* timer interrupt */ +#define PCI_INT (1 << 7) /* PCI bus error pending */ +#define URT_INT (1 << 6) /* UART Tx/Rx */ +#define GPI_INT (1 << 5) /* GPI pin */ +#define MIX_INT (1 << 4) /* mixer parameter segment FIFO channels */ +#define DAI_INT (1 << 3) /* DAI (SR-tracker or SPDIF-receiver) */ +#define TP_INT (1 << 2) /* transport priority queue */ +#define DSP_INT (1 << 1) /* DSP */ +#define SRC_INT (1 << 0) /* SRC channels */ + #endif /* CTHARDWARE_H */ diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index e530a6d60422..550b30a2bcf1 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1171,6 +1171,21 @@ static int daio_mgr_put_ctrl_blk(void *blk) return 0; } +/* Timer interrupt */ +static int set_timer_irq(struct hw *hw, int enable) +{ + hw_write_20kx(hw, GIE, enable ? IT_INT : 0); + return 0; +} + +static int set_timer_tick(struct hw *hw, unsigned int ticks) +{ + if (ticks) + ticks |= TIMR_IE | TIMR_IP; + hw_write_20kx(hw, TIMR, ticks); + return 0; +} + /* Card hardware initialization block */ struct dac_conf { unsigned int msr; /* master sample rate in rsrs */ @@ -1878,6 +1893,22 @@ static int uaa_to_xfi(struct pci_dev *pci) return 0; } +static irqreturn_t ct_20k1_interrupt(int irq, void *dev_id) +{ + struct hw *hw = dev_id; + unsigned int status; + + status = hw_read_20kx(hw, GIP); + if (!status) + return IRQ_NONE; + + if (hw->irq_callback) + hw->irq_callback(hw->irq_callback_data, status); + + hw_write_20kx(hw, GIP, status); + return IRQ_HANDLED; +} + static int hw_card_start(struct hw *hw) { int err = 0; @@ -1914,12 +1945,13 @@ static int hw_card_start(struct hw *hw) hw->io_base = pci_resource_start(pci, 0); } - /*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED, - atc->chip_details->nm_card, hw))) { + err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, + "ctxfi", hw); + if (err < 0) { + printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); goto error2; } hw->irq = pci->irq; - */ pci_set_master(pci); @@ -1936,6 +1968,8 @@ error1: static int hw_card_stop(struct hw *hw) { /* TODO: Disable interrupt and so on... */ + if (hw->irq >= 0) + synchronize_irq(hw->irq); return 0; } @@ -2215,6 +2249,9 @@ int create_20k1_hw_obj(struct hw **rhw) hw->daio_mgr_set_imapaddr = daio_mgr_set_imapaddr; hw->daio_mgr_commit_write = daio_mgr_commit_write; + hw->set_timer_irq = set_timer_irq; + hw->set_timer_tick = set_timer_tick; + *rhw = hw; return 0; diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 52ddf19d83bb..32b742dcd538 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -16,6 +16,7 @@ */ #include "ctpcm.h" +#include "cttimer.h" #include /* Hardware descriptions for playback */ @@ -108,6 +109,7 @@ static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime) struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream); atc->pcm_release_resources(atc, apcm); + ct_timer_instance_free(apcm->timer); kfree(apcm); runtime->private_data = NULL; } @@ -124,8 +126,6 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) if (NULL == apcm) return -ENOMEM; - spin_lock_init(&apcm->timer_lock); - apcm->stop_timer = 0; apcm->substream = substream; apcm->interrupt = ct_atc_pcm_interrupt; runtime->private_data = apcm; @@ -153,6 +153,10 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) return err; } + apcm->timer = ct_timer_instance_new(atc->timer, apcm); + if (!apcm->timer) + return -ENOMEM; + return 0; } @@ -182,89 +186,6 @@ static int ct_pcm_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); } -static void ct_pcm_timer_callback(unsigned long data) -{ - struct ct_atc_pcm *apcm = (struct ct_atc_pcm *)data; - struct snd_pcm_substream *substream = apcm->substream; - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned int period_size = runtime->period_size; - unsigned int buffer_size = runtime->buffer_size; - unsigned long flags; - unsigned int position = 0, dist = 0, interval = 0; - - position = substream->ops->pointer(substream); - dist = (position + buffer_size - apcm->position) % buffer_size; - if ((dist >= period_size) || - (position/period_size != apcm->position/period_size)) { - apcm->interrupt(apcm); - apcm->position = position; - } - /* Add extra HZ*5/1000 to avoid overrun issue when recording - * at 8kHz in 8-bit format or at 88kHz in 24-bit format. */ - interval = ((period_size - (position % period_size)) - * HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000; - spin_lock_irqsave(&apcm->timer_lock, flags); - apcm->timer.expires = jiffies + interval; - if (!apcm->stop_timer) - add_timer(&apcm->timer); - - spin_unlock_irqrestore(&apcm->timer_lock, flags); -} - -static int ct_pcm_timer_prepare(struct ct_atc_pcm *apcm) -{ - unsigned long flags; - - spin_lock_irqsave(&apcm->timer_lock, flags); - if (timer_pending(&apcm->timer)) { - /* The timer has already been started. */ - spin_unlock_irqrestore(&apcm->timer_lock, flags); - return 0; - } - - init_timer(&apcm->timer); - apcm->timer.data = (unsigned long)apcm; - apcm->timer.function = ct_pcm_timer_callback; - spin_unlock_irqrestore(&apcm->timer_lock, flags); - apcm->position = 0; - - return 0; -} - -static int ct_pcm_timer_start(struct ct_atc_pcm *apcm) -{ - struct snd_pcm_runtime *runtime = apcm->substream->runtime; - unsigned long flags; - - spin_lock_irqsave(&apcm->timer_lock, flags); - if (timer_pending(&apcm->timer)) { - /* The timer has already been started. */ - spin_unlock_irqrestore(&apcm->timer_lock, flags); - return 0; - } - - apcm->timer.expires = jiffies + (runtime->period_size * HZ + - (runtime->rate - 1)) / runtime->rate; - apcm->stop_timer = 0; - add_timer(&apcm->timer); - spin_unlock_irqrestore(&apcm->timer_lock, flags); - - return 0; -} - -static int ct_pcm_timer_stop(struct ct_atc_pcm *apcm) -{ - unsigned long flags; - - spin_lock_irqsave(&apcm->timer_lock, flags); - apcm->stop_timer = 1; - del_timer(&apcm->timer); - spin_unlock_irqrestore(&apcm->timer_lock, flags); - - try_to_del_timer_sync(&apcm->timer); - - return 0; -} static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream) { @@ -283,8 +204,6 @@ static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream) return err; } - ct_pcm_timer_prepare(apcm); - return 0; } @@ -300,12 +219,10 @@ ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: atc->pcm_playback_start(atc, apcm); - ct_pcm_timer_start(apcm); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ct_pcm_timer_stop(apcm); atc->pcm_playback_stop(atc, apcm); break; default: @@ -341,9 +258,7 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) if (NULL == apcm) return -ENOMEM; - spin_lock_init(&apcm->timer_lock); apcm->started = 0; - apcm->stop_timer = 0; apcm->substream = substream; apcm->interrupt = ct_atc_pcm_interrupt; runtime->private_data = apcm; @@ -365,6 +280,10 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) return err; } + apcm->timer = ct_timer_instance_new(atc->timer, apcm); + if (!apcm->timer) + return -ENOMEM; + return 0; } @@ -388,8 +307,6 @@ static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream) return err; } - ct_pcm_timer_prepare(apcm); - return 0; } @@ -403,14 +320,11 @@ ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: atc->pcm_capture_start(atc, apcm); - ct_pcm_timer_start(apcm); break; case SNDRV_PCM_TRIGGER_STOP: - ct_pcm_timer_stop(apcm); atc->pcm_capture_stop(atc, apcm); break; default: - ct_pcm_timer_stop(apcm); atc->pcm_capture_stop(atc, apcm); break; } diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c new file mode 100644 index 000000000000..3acb26d0c4cc --- /dev/null +++ b/sound/pci/ctxfi/cttimer.c @@ -0,0 +1,417 @@ +/* + * PCM timer handling on ctxfi + * + * This source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + */ + +#include +#include +#include +#include "ctatc.h" +#include "cthardware.h" +#include "cttimer.h" + +struct ct_timer_ops { + void (*init)(struct ct_timer_instance *); + void (*prepare)(struct ct_timer_instance *); + void (*start)(struct ct_timer_instance *); + void (*stop)(struct ct_timer_instance *); + void (*free_instance)(struct ct_timer_instance *); + void (*interrupt)(struct ct_timer *); + void (*free_global)(struct ct_timer *); +}; + +/* timer instance -- assigned to each PCM stream */ +struct ct_timer_instance { + spinlock_t lock; + struct ct_timer *timer_base; + struct ct_atc_pcm *apcm; + struct snd_pcm_substream *substream; + struct timer_list timer; + struct list_head instance_list; + struct list_head running_list; + unsigned int position; + unsigned int frag_count; + unsigned int running:1; + unsigned int need_update:1; +}; + +/* timer instance manager */ +struct ct_timer { + spinlock_t lock; /* global timer lock (for xfitimer) */ + spinlock_t list_lock; /* lock for instance list */ + struct ct_atc *atc; + struct ct_timer_ops *ops; + struct list_head instance_head; + struct list_head running_head; + unsigned int irq_handling:1; /* in IRQ handling */ + unsigned int reprogram:1; /* need to reprogram the internval */ + unsigned int running:1; /* global timer running */ +}; + + +/* + * system-timer-based updates + */ + +static void ct_systimer_callback(unsigned long data) +{ + struct ct_timer_instance *ti = (struct ct_timer_instance *)data; + struct snd_pcm_substream *substream = ti->substream; + struct snd_pcm_runtime *runtime = substream->runtime; + struct ct_atc_pcm *apcm = ti->apcm; + unsigned int period_size = runtime->period_size; + unsigned int buffer_size = runtime->buffer_size; + unsigned long flags; + unsigned int position, dist, interval; + + position = substream->ops->pointer(substream); + dist = (position + buffer_size - ti->position) % buffer_size; + if (dist >= period_size || + position / period_size != ti->position / period_size) { + apcm->interrupt(apcm); + ti->position = position; + } + /* Add extra HZ*5/1000 to avoid overrun issue when recording + * at 8kHz in 8-bit format or at 88kHz in 24-bit format. */ + interval = ((period_size - (position % period_size)) + * HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000; + spin_lock_irqsave(&ti->lock, flags); + if (ti->running) + mod_timer(&ti->timer, jiffies + interval); + spin_unlock_irqrestore(&ti->lock, flags); +} + +static void ct_systimer_init(struct ct_timer_instance *ti) +{ + setup_timer(&ti->timer, ct_systimer_callback, + (unsigned long)ti); +} + +static void ct_systimer_start(struct ct_timer_instance *ti) +{ + struct snd_pcm_runtime *runtime = ti->substream->runtime; + unsigned long flags; + + spin_lock_irqsave(&ti->lock, flags); + ti->running = 1; + mod_timer(&ti->timer, + jiffies + (runtime->period_size * HZ + + (runtime->rate - 1)) / runtime->rate); + spin_unlock_irqrestore(&ti->lock, flags); +} + +static void ct_systimer_stop(struct ct_timer_instance *ti) +{ + unsigned long flags; + + spin_lock_irqsave(&ti->lock, flags); + ti->running = 0; + del_timer(&ti->timer); + spin_unlock_irqrestore(&ti->lock, flags); +} + +static void ct_systimer_prepare(struct ct_timer_instance *ti) +{ + ct_systimer_stop(ti); + try_to_del_timer_sync(&ti->timer); +} + +#define ct_systimer_free ct_systimer_prepare + +static struct ct_timer_ops ct_systimer_ops = { + .init = ct_systimer_init, + .free_instance = ct_systimer_free, + .prepare = ct_systimer_prepare, + .start = ct_systimer_start, + .stop = ct_systimer_stop, +}; + + +/* + * Handling multiple streams using a global emu20k1 timer irq + */ + +#define CT_TIMER_FREQ 48000 +#define MAX_TICKS ((1 << 13) - 1) + +static void ct_xfitimer_irq_rearm(struct ct_timer *atimer, int ticks) +{ + struct hw *hw = atimer->atc->hw; + if (ticks > MAX_TICKS) + ticks = MAX_TICKS; + hw->set_timer_tick(hw, ticks); + if (!atimer->running) + hw->set_timer_irq(hw, 1); + atimer->running = 1; +} + +static void ct_xfitimer_irq_stop(struct ct_timer *atimer) +{ + if (atimer->running) { + struct hw *hw = atimer->atc->hw; + hw->set_timer_irq(hw, 0); + hw->set_timer_tick(hw, 0); + atimer->running = 0; + } +} + +/* + * reprogram the timer interval; + * checks the running instance list and determines the next timer interval. + * also updates the each stream position, returns the number of streams + * to call snd_pcm_period_elapsed() appropriately + * + * call this inside the lock and irq disabled + */ +static int ct_xfitimer_reprogram(struct ct_timer *atimer) +{ + struct ct_timer_instance *ti; + int min_intr = -1; + int updates = 0; + + list_for_each_entry(ti, &atimer->running_head, running_list) { + struct snd_pcm_runtime *runtime; + unsigned int pos, diff; + int intr; + runtime = ti->substream->runtime; + pos = ti->substream->ops->pointer(ti->substream); + if (pos < ti->position) + diff = runtime->buffer_size - ti->position + pos; + else + diff = pos - ti->position; + ti->position = pos; + while (diff >= ti->frag_count) { + ti->frag_count += runtime->period_size; + ti->need_update = 1; + updates++; + } + ti->frag_count -= diff; + intr = div_u64((u64)ti->frag_count * CT_TIMER_FREQ, + runtime->rate); + if (min_intr < 0 || intr < min_intr) + min_intr = intr; + } + + if (min_intr > 0) + ct_xfitimer_irq_rearm(atimer, min_intr); + else + ct_xfitimer_irq_stop(atimer); + + atimer->reprogram = 0; /* clear flag */ + return updates; +} + +/* look through the instance list and call period_elapsed if needed */ +static void ct_xfitimer_check_period(struct ct_timer *atimer) +{ + struct ct_timer_instance *ti; + unsigned long flags; + + spin_lock_irqsave(&atimer->list_lock, flags); + list_for_each_entry(ti, &atimer->instance_head, instance_list) { + if (ti->need_update) { + ti->need_update = 0; + ti->apcm->interrupt(ti->apcm); + } + } + spin_unlock_irqrestore(&atimer->list_lock, flags); +} + +/* Handle timer-interrupt */ +static void ct_xfitimer_callback(struct ct_timer *atimer) +{ + int update; + unsigned long flags; + + spin_lock_irqsave(&atimer->lock, flags); + atimer->irq_handling = 1; + do { + update = ct_xfitimer_reprogram(atimer); + spin_unlock(&atimer->lock); + if (update) + ct_xfitimer_check_period(atimer); + spin_lock(&atimer->lock); + } while (atimer->reprogram); + atimer->irq_handling = 0; + spin_unlock_irqrestore(&atimer->lock, flags); +} + +static void ct_xfitimer_prepare(struct ct_timer_instance *ti) +{ + ti->frag_count = ti->substream->runtime->period_size; + ti->need_update = 0; +} + + +/* start/stop the timer */ +static void ct_xfitimer_update(struct ct_timer *atimer) +{ + unsigned long flags; + int update; + + if (atimer->irq_handling) { + /* reached from IRQ handler; let it handle later */ + atimer->reprogram = 1; + return; + } + + spin_lock_irqsave(&atimer->lock, flags); + ct_xfitimer_irq_stop(atimer); + update = ct_xfitimer_reprogram(atimer); + spin_unlock_irqrestore(&atimer->lock, flags); + if (update) + ct_xfitimer_check_period(atimer); +} + +static void ct_xfitimer_start(struct ct_timer_instance *ti) +{ + struct ct_timer *atimer = ti->timer_base; + unsigned long flags; + + spin_lock_irqsave(&atimer->lock, flags); + list_add(&ti->running_list, &atimer->running_head); + spin_unlock_irqrestore(&atimer->lock, flags); + ct_xfitimer_update(atimer); +} + +static void ct_xfitimer_stop(struct ct_timer_instance *ti) +{ + struct ct_timer *atimer = ti->timer_base; + unsigned long flags; + + spin_lock_irqsave(&atimer->lock, flags); + list_del_init(&ti->running_list); + ti->need_update = 0; + spin_unlock_irqrestore(&atimer->lock, flags); + ct_xfitimer_update(atimer); +} + +static void ct_xfitimer_free_global(struct ct_timer *atimer) +{ + ct_xfitimer_irq_stop(atimer); +} + +static struct ct_timer_ops ct_xfitimer_ops = { + .prepare = ct_xfitimer_prepare, + .start = ct_xfitimer_start, + .stop = ct_xfitimer_stop, + .interrupt = ct_xfitimer_callback, + .free_global = ct_xfitimer_free_global, +}; + +/* + * timer instance + */ + +struct ct_timer_instance * +ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm) +{ + struct ct_timer_instance *ti; + + ti = kzalloc(sizeof(*ti), GFP_KERNEL); + if (!ti) + return NULL; + spin_lock_init(&ti->lock); + INIT_LIST_HEAD(&ti->instance_list); + INIT_LIST_HEAD(&ti->running_list); + ti->timer_base = atimer; + ti->apcm = apcm; + ti->substream = apcm->substream; + if (atimer->ops->init) + atimer->ops->init(ti); + + spin_lock_irq(&atimer->list_lock); + list_add(&ti->instance_list, &atimer->instance_head); + spin_unlock_irq(&atimer->list_lock); + + return ti; +} + +void ct_timer_prepare(struct ct_timer_instance *ti) +{ + if (ti->timer_base->ops->prepare) + ti->timer_base->ops->prepare(ti); + ti->position = 0; + ti->running = 0; +} + +void ct_timer_start(struct ct_timer_instance *ti) +{ + struct ct_timer *atimer = ti->timer_base; + atimer->ops->start(ti); +} + +void ct_timer_stop(struct ct_timer_instance *ti) +{ + struct ct_timer *atimer = ti->timer_base; + atimer->ops->stop(ti); +} + +void ct_timer_instance_free(struct ct_timer_instance *ti) +{ + struct ct_timer *atimer = ti->timer_base; + + atimer->ops->stop(ti); /* to be sure */ + if (atimer->ops->free_instance) + atimer->ops->free_instance(ti); + + spin_lock_irq(&atimer->list_lock); + list_del(&ti->instance_list); + spin_unlock_irq(&atimer->list_lock); + + kfree(ti); +} + +/* + * timer manager + */ + +#define USE_SYSTEM_TIMER 0 + +static void ct_timer_interrupt(void *data, unsigned int status) +{ + struct ct_timer *timer = data; + + /* Interval timer interrupt */ + if ((status & IT_INT) && timer->ops->interrupt) + timer->ops->interrupt(timer); +} + +struct ct_timer *ct_timer_new(struct ct_atc *atc) +{ + struct ct_timer *atimer; + struct hw *hw; + + atimer = kzalloc(sizeof(*atimer), GFP_KERNEL); + if (!atimer) + return NULL; + spin_lock_init(&atimer->lock); + spin_lock_init(&atimer->list_lock); + INIT_LIST_HEAD(&atimer->instance_head); + INIT_LIST_HEAD(&atimer->running_head); + atimer->atc = atc; + hw = atc->hw; + if (!USE_SYSTEM_TIMER && hw->set_timer_irq) { + printk(KERN_INFO "ctxfi: Use xfi-native timer\n"); + atimer->ops = &ct_xfitimer_ops; + hw->irq_callback_data = atimer; + hw->irq_callback = ct_timer_interrupt; + } else { + printk(KERN_INFO "ctxfi: Use system timer\n"); + atimer->ops = &ct_systimer_ops; + } + return atimer; +} + +void ct_timer_free(struct ct_timer *atimer) +{ + struct hw *hw = atimer->atc->hw; + hw->irq_callback = NULL; + if (atimer->ops->free_global) + atimer->ops->free_global(atimer); + kfree(atimer); +} + diff --git a/sound/pci/ctxfi/cttimer.h b/sound/pci/ctxfi/cttimer.h new file mode 100644 index 000000000000..979348229291 --- /dev/null +++ b/sound/pci/ctxfi/cttimer.h @@ -0,0 +1,29 @@ +/* + * Timer handling + */ + +#ifndef __CTTIMER_H +#define __CTTIMER_H + +#include +#include +#include + +struct snd_pcm_substream; +struct ct_atc; +struct ct_atc_pcm; + +struct ct_timer; +struct ct_timer_instance; + +struct ct_timer *ct_timer_new(struct ct_atc *atc); +void ct_timer_free(struct ct_timer *atimer); + +struct ct_timer_instance * +ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm); +void ct_timer_instance_free(struct ct_timer_instance *ti); +void ct_timer_start(struct ct_timer_instance *ti); +void ct_timer_stop(struct ct_timer_instance *ti); +void ct_timer_prepare(struct ct_timer_instance *ti); + +#endif /* __CTTIMER_H */ -- cgit v1.2.3 From 2a36f67f8c81f0babda0e811c760b7bfa971010b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 5 Jun 2009 16:34:10 +0200 Subject: ALSA: ctxfi - Clean up / optimize - Use static tables instead of assigining each funciton pointer - Add __devinit* to appropriate places; pcm, mixer and timer cannot be marked because they are kept in the function table that lives long - Move create_alsa_devs function out of struct ct_atc to mark it __devinit Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctatc.c | 82 ++++++++--------- sound/pci/ctxfi/ctatc.h | 3 +- sound/pci/ctxfi/cthardware.c | 4 +- sound/pci/ctxfi/cthw20k1.c | 205 +++++++++++++++++++++---------------------- sound/pci/ctxfi/cthw20k2.c | 195 ++++++++++++++++++++-------------------- sound/pci/ctxfi/xfi.c | 2 +- 6 files changed, 243 insertions(+), 248 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 10b741977dd7..9b1324544db0 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -1202,7 +1202,7 @@ static int atc_dev_free(struct snd_device *dev) return ct_atc_destroy(atc); } -static int atc_identify_card(struct ct_atc *atc) +static int __devinit atc_identify_card(struct ct_atc *atc) { u16 subsys; u8 revision; @@ -1243,7 +1243,7 @@ static int atc_identify_card(struct ct_atc *atc) return 0; } -static int ct_create_alsa_devs(struct ct_atc *atc) +int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc) { enum CTALSADEVS i; struct hw *hw = atc->hw; @@ -1277,7 +1277,7 @@ static int ct_create_alsa_devs(struct ct_atc *atc) return 0; } -static int atc_create_hw_devs(struct ct_atc *atc) +static int __devinit atc_create_hw_devs(struct ct_atc *atc) { struct hw *hw = NULL; struct card_conf info = {0}; @@ -1313,7 +1313,7 @@ static int atc_create_hw_devs(struct ct_atc *atc) return 0; } -static int atc_get_resources(struct ct_atc *atc) +static int __devinit atc_get_resources(struct ct_atc *atc) { struct daio_desc da_desc = {0}; struct daio_mgr *daio_mgr = NULL; @@ -1423,7 +1423,7 @@ static int atc_get_resources(struct ct_atc *atc) return 0; } -static void +static void __devinit atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, struct src **srcs, struct srcimp **srcimps) { @@ -1462,7 +1462,7 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */ } -static void atc_connect_resources(struct ct_atc *atc) +static void __devinit atc_connect_resources(struct ct_atc *atc) { struct dai *dai = NULL; struct dao *dao = NULL; @@ -1508,37 +1508,35 @@ static void atc_connect_resources(struct ct_atc *atc) } } -static void atc_set_ops(struct ct_atc *atc) -{ - /* Set operations */ - atc->map_audio_buffer = ct_map_audio_buffer; - atc->unmap_audio_buffer = ct_unmap_audio_buffer; - atc->pcm_playback_prepare = atc_pcm_playback_prepare; - atc->pcm_release_resources = atc_pcm_release_resources; - atc->pcm_playback_start = atc_pcm_playback_start; - atc->pcm_playback_stop = atc_pcm_stop; - atc->pcm_playback_position = atc_pcm_playback_position; - atc->pcm_capture_prepare = atc_pcm_capture_prepare; - atc->pcm_capture_start = atc_pcm_capture_start; - atc->pcm_capture_stop = atc_pcm_stop; - atc->pcm_capture_position = atc_pcm_capture_position; - atc->spdif_passthru_playback_prepare = spdif_passthru_playback_prepare; - atc->get_ptp_phys = atc_get_ptp_phys; - atc->select_line_in = atc_select_line_in; - atc->select_mic_in = atc_select_mic_in; - atc->select_digit_io = atc_select_digit_io; - atc->line_front_unmute = atc_line_front_unmute; - atc->line_surround_unmute = atc_line_surround_unmute; - atc->line_clfe_unmute = atc_line_clfe_unmute; - atc->line_rear_unmute = atc_line_rear_unmute; - atc->line_in_unmute = atc_line_in_unmute; - atc->spdif_out_unmute = atc_spdif_out_unmute; - atc->spdif_in_unmute = atc_spdif_in_unmute; - atc->spdif_out_get_status = atc_spdif_out_get_status; - atc->spdif_out_set_status = atc_spdif_out_set_status; - atc->spdif_out_passthru = atc_spdif_out_passthru; - atc->have_digit_io_switch = atc_have_digit_io_switch; -} +static struct ct_atc atc_preset __devinitdata = { + .map_audio_buffer = ct_map_audio_buffer, + .unmap_audio_buffer = ct_unmap_audio_buffer, + .pcm_playback_prepare = atc_pcm_playback_prepare, + .pcm_release_resources = atc_pcm_release_resources, + .pcm_playback_start = atc_pcm_playback_start, + .pcm_playback_stop = atc_pcm_stop, + .pcm_playback_position = atc_pcm_playback_position, + .pcm_capture_prepare = atc_pcm_capture_prepare, + .pcm_capture_start = atc_pcm_capture_start, + .pcm_capture_stop = atc_pcm_stop, + .pcm_capture_position = atc_pcm_capture_position, + .spdif_passthru_playback_prepare = spdif_passthru_playback_prepare, + .get_ptp_phys = atc_get_ptp_phys, + .select_line_in = atc_select_line_in, + .select_mic_in = atc_select_mic_in, + .select_digit_io = atc_select_digit_io, + .line_front_unmute = atc_line_front_unmute, + .line_surround_unmute = atc_line_surround_unmute, + .line_clfe_unmute = atc_line_clfe_unmute, + .line_rear_unmute = atc_line_rear_unmute, + .line_in_unmute = atc_line_in_unmute, + .spdif_out_unmute = atc_spdif_out_unmute, + .spdif_in_unmute = atc_spdif_in_unmute, + .spdif_out_get_status = atc_spdif_out_get_status, + .spdif_out_set_status = atc_spdif_out_set_status, + .spdif_out_passthru = atc_spdif_out_passthru, + .have_digit_io_switch = atc_have_digit_io_switch, +}; /** * ct_atc_create - create and initialize a hardware manager @@ -1552,7 +1550,7 @@ static void atc_set_ops(struct ct_atc *atc) * Returns 0 if suceeds, or negative error code if fails. */ -int ct_atc_create(struct snd_card *card, struct pci_dev *pci, +int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, unsigned int rsr, unsigned int msr, struct ct_atc **ratc) { struct ct_atc *atc = NULL; @@ -1567,14 +1565,14 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci, if (NULL == atc) return -ENOMEM; + /* Set operations */ + *atc = atc_preset; + atc->card = card; atc->pci = pci; atc->rsr = rsr; atc->msr = msr; - /* Set operations */ - atc_set_ops(atc); - spin_lock_init(&atc->atc_lock); /* Find card model */ @@ -1606,8 +1604,6 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci, if (!atc->timer) goto error1; - atc->create_alsa_devs = ct_create_alsa_devs; - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); if (err < 0) goto error1; diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index a3f9b1bc7dcc..04459aa0d4d9 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -91,8 +91,6 @@ struct ct_atc { const struct ct_atc_chip_details *chip_details; enum CTCARDS model; - /* Create all alsa devices */ - int (*create_alsa_devs)(struct ct_atc *atc); struct ct_vm *vm; /* device virtual memory manager for this card */ int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); @@ -151,5 +149,6 @@ struct ct_atc { int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, unsigned int rsr, unsigned int msr, struct ct_atc **ratc); +int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc); #endif /* CTATC_H */ diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c index 8e58860f641c..53d1acadc0e8 100644 --- a/sound/pci/ctxfi/cthardware.c +++ b/sound/pci/ctxfi/cthardware.c @@ -20,7 +20,7 @@ #include "cthw20k2.h" #include -static enum CHIPTYP get_chip_type(struct hw *hw) +static enum CHIPTYP __devinitdata get_chip_type(struct hw *hw) { enum CHIPTYP type = ATCNONE; @@ -39,7 +39,7 @@ static enum CHIPTYP get_chip_type(struct hw *hw) return type; } -int create_hw_obj(struct pci_dev *pci, struct hw **rhw) +int __devinit create_hw_obj(struct pci_dev *pci, struct hw **rhw) { int err = 0; diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 550b30a2bcf1..df565c11fcca 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -2138,9 +2138,107 @@ static void hw_write_pci(struct hw *hw, u32 reg, u32 data) &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags); } -int create_20k1_hw_obj(struct hw **rhw) +static struct hw ct20k1_preset __devinitdata = { + .irq = -1, + + .card_init = hw_card_init, + .card_stop = hw_card_stop, + .pll_init = hw_pll_init, + .is_adc_source_selected = hw_is_adc_input_selected, + .select_adc_source = hw_adc_input_select, + .have_digit_io_switch = hw_have_digit_io_switch, + + .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, + .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, + .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk, + .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk, + .src_set_state = src_set_state, + .src_set_bm = src_set_bm, + .src_set_rsr = src_set_rsr, + .src_set_sf = src_set_sf, + .src_set_wr = src_set_wr, + .src_set_pm = src_set_pm, + .src_set_rom = src_set_rom, + .src_set_vo = src_set_vo, + .src_set_st = src_set_st, + .src_set_ie = src_set_ie, + .src_set_ilsz = src_set_ilsz, + .src_set_bp = src_set_bp, + .src_set_cisz = src_set_cisz, + .src_set_ca = src_set_ca, + .src_set_sa = src_set_sa, + .src_set_la = src_set_la, + .src_set_pitch = src_set_pitch, + .src_set_dirty = src_set_dirty, + .src_set_clear_zbufs = src_set_clear_zbufs, + .src_set_dirty_all = src_set_dirty_all, + .src_commit_write = src_commit_write, + .src_get_ca = src_get_ca, + .src_get_dirty = src_get_dirty, + .src_dirty_conj_mask = src_dirty_conj_mask, + .src_mgr_enbs_src = src_mgr_enbs_src, + .src_mgr_enb_src = src_mgr_enb_src, + .src_mgr_dsb_src = src_mgr_dsb_src, + .src_mgr_commit_write = src_mgr_commit_write, + + .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk, + .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk, + .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc, + .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser, + .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt, + .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr, + .srcimp_mgr_commit_write = srcimp_mgr_commit_write, + + .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk, + .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk, + .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk, + .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk, + .amixer_set_mode = amixer_set_mode, + .amixer_set_iv = amixer_set_iv, + .amixer_set_x = amixer_set_x, + .amixer_set_y = amixer_set_y, + .amixer_set_sadr = amixer_set_sadr, + .amixer_set_se = amixer_set_se, + .amixer_set_dirty = amixer_set_dirty, + .amixer_set_dirty_all = amixer_set_dirty_all, + .amixer_commit_write = amixer_commit_write, + .amixer_get_y = amixer_get_y, + .amixer_get_dirty = amixer_get_dirty, + + .dai_get_ctrl_blk = dai_get_ctrl_blk, + .dai_put_ctrl_blk = dai_put_ctrl_blk, + .dai_srt_set_srco = dai_srt_set_srcr, + .dai_srt_set_srcm = dai_srt_set_srcl, + .dai_srt_set_rsr = dai_srt_set_rsr, + .dai_srt_set_drat = dai_srt_set_drat, + .dai_srt_set_ec = dai_srt_set_ec, + .dai_srt_set_et = dai_srt_set_et, + .dai_commit_write = dai_commit_write, + + .dao_get_ctrl_blk = dao_get_ctrl_blk, + .dao_put_ctrl_blk = dao_put_ctrl_blk, + .dao_set_spos = dao_set_spos, + .dao_commit_write = dao_commit_write, + .dao_get_spos = dao_get_spos, + + .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk, + .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk, + .daio_mgr_enb_dai = daio_mgr_enb_dai, + .daio_mgr_dsb_dai = daio_mgr_dsb_dai, + .daio_mgr_enb_dao = daio_mgr_enb_dao, + .daio_mgr_dsb_dao = daio_mgr_dsb_dao, + .daio_mgr_dao_init = daio_mgr_dao_init, + .daio_mgr_set_imaparc = daio_mgr_set_imaparc, + .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt, + .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr, + .daio_mgr_commit_write = daio_mgr_commit_write, + + .set_timer_irq = set_timer_irq, + .set_timer_tick = set_timer_tick, +}; + +int __devinit create_20k1_hw_obj(struct hw **rhw) { - struct hw *hw; struct hw20k1 *hw20k1; *rhw = NULL; @@ -2151,108 +2249,9 @@ int create_20k1_hw_obj(struct hw **rhw) spin_lock_init(&hw20k1->reg_20k1_lock); spin_lock_init(&hw20k1->reg_pci_lock); - hw = &hw20k1->hw; + hw20k1->hw = ct20k1_preset; - hw->io_base = 0; - hw->mem_base = (unsigned long)NULL; - hw->irq = -1; - - hw->card_init = hw_card_init; - hw->card_stop = hw_card_stop; - hw->pll_init = hw_pll_init; - hw->is_adc_source_selected = hw_is_adc_input_selected; - hw->select_adc_source = hw_adc_input_select; - hw->have_digit_io_switch = hw_have_digit_io_switch; - - hw->src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk; - hw->src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk; - hw->src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk; - hw->src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk; - hw->src_set_state = src_set_state; - hw->src_set_bm = src_set_bm; - hw->src_set_rsr = src_set_rsr; - hw->src_set_sf = src_set_sf; - hw->src_set_wr = src_set_wr; - hw->src_set_pm = src_set_pm; - hw->src_set_rom = src_set_rom; - hw->src_set_vo = src_set_vo; - hw->src_set_st = src_set_st; - hw->src_set_ie = src_set_ie; - hw->src_set_ilsz = src_set_ilsz; - hw->src_set_bp = src_set_bp; - hw->src_set_cisz = src_set_cisz; - hw->src_set_ca = src_set_ca; - hw->src_set_sa = src_set_sa; - hw->src_set_la = src_set_la; - hw->src_set_pitch = src_set_pitch; - hw->src_set_dirty = src_set_dirty; - hw->src_set_clear_zbufs = src_set_clear_zbufs; - hw->src_set_dirty_all = src_set_dirty_all; - hw->src_commit_write = src_commit_write; - hw->src_get_ca = src_get_ca; - hw->src_get_dirty = src_get_dirty; - hw->src_dirty_conj_mask = src_dirty_conj_mask; - hw->src_mgr_enbs_src = src_mgr_enbs_src; - hw->src_mgr_enb_src = src_mgr_enb_src; - hw->src_mgr_dsb_src = src_mgr_dsb_src; - hw->src_mgr_commit_write = src_mgr_commit_write; - - hw->srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk; - hw->srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk; - hw->srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc; - hw->srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser; - hw->srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt; - hw->srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr; - hw->srcimp_mgr_commit_write = srcimp_mgr_commit_write; - - hw->amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk; - hw->amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk; - hw->amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk; - hw->amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk; - hw->amixer_set_mode = amixer_set_mode; - hw->amixer_set_iv = amixer_set_iv; - hw->amixer_set_x = amixer_set_x; - hw->amixer_set_y = amixer_set_y; - hw->amixer_set_sadr = amixer_set_sadr; - hw->amixer_set_se = amixer_set_se; - hw->amixer_set_dirty = amixer_set_dirty; - hw->amixer_set_dirty_all = amixer_set_dirty_all; - hw->amixer_commit_write = amixer_commit_write; - hw->amixer_get_y = amixer_get_y; - hw->amixer_get_dirty = amixer_get_dirty; - - hw->dai_get_ctrl_blk = dai_get_ctrl_blk; - hw->dai_put_ctrl_blk = dai_put_ctrl_blk; - hw->dai_srt_set_srco = dai_srt_set_srcr; - hw->dai_srt_set_srcm = dai_srt_set_srcl; - hw->dai_srt_set_rsr = dai_srt_set_rsr; - hw->dai_srt_set_drat = dai_srt_set_drat; - hw->dai_srt_set_ec = dai_srt_set_ec; - hw->dai_srt_set_et = dai_srt_set_et; - hw->dai_commit_write = dai_commit_write; - - hw->dao_get_ctrl_blk = dao_get_ctrl_blk; - hw->dao_put_ctrl_blk = dao_put_ctrl_blk; - hw->dao_set_spos = dao_set_spos; - hw->dao_commit_write = dao_commit_write; - hw->dao_get_spos = dao_get_spos; - - hw->daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk; - hw->daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk; - hw->daio_mgr_enb_dai = daio_mgr_enb_dai; - hw->daio_mgr_dsb_dai = daio_mgr_dsb_dai; - hw->daio_mgr_enb_dao = daio_mgr_enb_dao; - hw->daio_mgr_dsb_dao = daio_mgr_dsb_dao; - hw->daio_mgr_dao_init = daio_mgr_dao_init; - hw->daio_mgr_set_imaparc = daio_mgr_set_imaparc; - hw->daio_mgr_set_imapnxt = daio_mgr_set_imapnxt; - hw->daio_mgr_set_imapaddr = daio_mgr_set_imapaddr; - hw->daio_mgr_commit_write = daio_mgr_commit_write; - - hw->set_timer_irq = set_timer_irq; - hw->set_timer_tick = set_timer_tick; - - *rhw = hw; + *rhw = &hw20k1->hw; return 0; } diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 349728765f2c..041199fbae16 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -2006,7 +2006,103 @@ static void hw_write_20kx(struct hw *hw, u32 reg, u32 data) writel(data, (void *)(hw->mem_base + reg)); } -int create_20k2_hw_obj(struct hw **rhw) +static struct hw ct20k2_preset __devinitdata = { + .irq = -1, + + .card_init = hw_card_init, + .card_stop = hw_card_stop, + .pll_init = hw_pll_init, + .is_adc_source_selected = hw_is_adc_input_selected, + .select_adc_source = hw_adc_input_select, + .have_digit_io_switch = hw_have_digit_io_switch, + + .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, + .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, + .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk, + .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk, + .src_set_state = src_set_state, + .src_set_bm = src_set_bm, + .src_set_rsr = src_set_rsr, + .src_set_sf = src_set_sf, + .src_set_wr = src_set_wr, + .src_set_pm = src_set_pm, + .src_set_rom = src_set_rom, + .src_set_vo = src_set_vo, + .src_set_st = src_set_st, + .src_set_ie = src_set_ie, + .src_set_ilsz = src_set_ilsz, + .src_set_bp = src_set_bp, + .src_set_cisz = src_set_cisz, + .src_set_ca = src_set_ca, + .src_set_sa = src_set_sa, + .src_set_la = src_set_la, + .src_set_pitch = src_set_pitch, + .src_set_dirty = src_set_dirty, + .src_set_clear_zbufs = src_set_clear_zbufs, + .src_set_dirty_all = src_set_dirty_all, + .src_commit_write = src_commit_write, + .src_get_ca = src_get_ca, + .src_get_dirty = src_get_dirty, + .src_dirty_conj_mask = src_dirty_conj_mask, + .src_mgr_enbs_src = src_mgr_enbs_src, + .src_mgr_enb_src = src_mgr_enb_src, + .src_mgr_dsb_src = src_mgr_dsb_src, + .src_mgr_commit_write = src_mgr_commit_write, + + .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk, + .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk, + .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc, + .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser, + .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt, + .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr, + .srcimp_mgr_commit_write = srcimp_mgr_commit_write, + + .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk, + .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk, + .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk, + .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk, + .amixer_set_mode = amixer_set_mode, + .amixer_set_iv = amixer_set_iv, + .amixer_set_x = amixer_set_x, + .amixer_set_y = amixer_set_y, + .amixer_set_sadr = amixer_set_sadr, + .amixer_set_se = amixer_set_se, + .amixer_set_dirty = amixer_set_dirty, + .amixer_set_dirty_all = amixer_set_dirty_all, + .amixer_commit_write = amixer_commit_write, + .amixer_get_y = amixer_get_y, + .amixer_get_dirty = amixer_get_dirty, + + .dai_get_ctrl_blk = dai_get_ctrl_blk, + .dai_put_ctrl_blk = dai_put_ctrl_blk, + .dai_srt_set_srco = dai_srt_set_srco, + .dai_srt_set_srcm = dai_srt_set_srcm, + .dai_srt_set_rsr = dai_srt_set_rsr, + .dai_srt_set_drat = dai_srt_set_drat, + .dai_srt_set_ec = dai_srt_set_ec, + .dai_srt_set_et = dai_srt_set_et, + .dai_commit_write = dai_commit_write, + + .dao_get_ctrl_blk = dao_get_ctrl_blk, + .dao_put_ctrl_blk = dao_put_ctrl_blk, + .dao_set_spos = dao_set_spos, + .dao_commit_write = dao_commit_write, + .dao_get_spos = dao_get_spos, + + .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk, + .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk, + .daio_mgr_enb_dai = daio_mgr_enb_dai, + .daio_mgr_dsb_dai = daio_mgr_dsb_dai, + .daio_mgr_enb_dao = daio_mgr_enb_dao, + .daio_mgr_dsb_dao = daio_mgr_dsb_dao, + .daio_mgr_dao_init = daio_mgr_dao_init, + .daio_mgr_set_imaparc = daio_mgr_set_imaparc, + .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt, + .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr, + .daio_mgr_commit_write = daio_mgr_commit_write, +}; + +int __devinit create_20k2_hw_obj(struct hw **rhw) { struct hw *hw; @@ -2015,102 +2111,7 @@ int create_20k2_hw_obj(struct hw **rhw) if (NULL == hw) return -ENOMEM; - hw->io_base = 0; - hw->mem_base = (unsigned long)NULL; - hw->irq = -1; - - hw->card_init = hw_card_init; - hw->card_stop = hw_card_stop; - hw->pll_init = hw_pll_init; - hw->is_adc_source_selected = hw_is_adc_input_selected; - hw->select_adc_source = hw_adc_input_select; - hw->have_digit_io_switch = hw_have_digit_io_switch; - - hw->src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk; - hw->src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk; - hw->src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk; - hw->src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk; - hw->src_set_state = src_set_state; - hw->src_set_bm = src_set_bm; - hw->src_set_rsr = src_set_rsr; - hw->src_set_sf = src_set_sf; - hw->src_set_wr = src_set_wr; - hw->src_set_pm = src_set_pm; - hw->src_set_rom = src_set_rom; - hw->src_set_vo = src_set_vo; - hw->src_set_st = src_set_st; - hw->src_set_ie = src_set_ie; - hw->src_set_ilsz = src_set_ilsz; - hw->src_set_bp = src_set_bp; - hw->src_set_cisz = src_set_cisz; - hw->src_set_ca = src_set_ca; - hw->src_set_sa = src_set_sa; - hw->src_set_la = src_set_la; - hw->src_set_pitch = src_set_pitch; - hw->src_set_dirty = src_set_dirty; - hw->src_set_clear_zbufs = src_set_clear_zbufs; - hw->src_set_dirty_all = src_set_dirty_all; - hw->src_commit_write = src_commit_write; - hw->src_get_ca = src_get_ca; - hw->src_get_dirty = src_get_dirty; - hw->src_dirty_conj_mask = src_dirty_conj_mask; - hw->src_mgr_enbs_src = src_mgr_enbs_src; - hw->src_mgr_enb_src = src_mgr_enb_src; - hw->src_mgr_dsb_src = src_mgr_dsb_src; - hw->src_mgr_commit_write = src_mgr_commit_write; - - hw->srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk; - hw->srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk; - hw->srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc; - hw->srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser; - hw->srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt; - hw->srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr; - hw->srcimp_mgr_commit_write = srcimp_mgr_commit_write; - - hw->amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk; - hw->amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk; - hw->amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk; - hw->amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk; - hw->amixer_set_mode = amixer_set_mode; - hw->amixer_set_iv = amixer_set_iv; - hw->amixer_set_x = amixer_set_x; - hw->amixer_set_y = amixer_set_y; - hw->amixer_set_sadr = amixer_set_sadr; - hw->amixer_set_se = amixer_set_se; - hw->amixer_set_dirty = amixer_set_dirty; - hw->amixer_set_dirty_all = amixer_set_dirty_all; - hw->amixer_commit_write = amixer_commit_write; - hw->amixer_get_y = amixer_get_y; - hw->amixer_get_dirty = amixer_get_dirty; - - hw->dai_get_ctrl_blk = dai_get_ctrl_blk; - hw->dai_put_ctrl_blk = dai_put_ctrl_blk; - hw->dai_srt_set_srco = dai_srt_set_srco; - hw->dai_srt_set_srcm = dai_srt_set_srcm; - hw->dai_srt_set_rsr = dai_srt_set_rsr; - hw->dai_srt_set_drat = dai_srt_set_drat; - hw->dai_srt_set_ec = dai_srt_set_ec; - hw->dai_srt_set_et = dai_srt_set_et; - hw->dai_commit_write = dai_commit_write; - - hw->dao_get_ctrl_blk = dao_get_ctrl_blk; - hw->dao_put_ctrl_blk = dao_put_ctrl_blk; - hw->dao_set_spos = dao_set_spos; - hw->dao_commit_write = dao_commit_write; - hw->dao_get_spos = dao_get_spos; - - hw->daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk; - hw->daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk; - hw->daio_mgr_enb_dai = daio_mgr_enb_dai; - hw->daio_mgr_dsb_dai = daio_mgr_dsb_dai; - hw->daio_mgr_enb_dao = daio_mgr_enb_dao; - hw->daio_mgr_dsb_dao = daio_mgr_dsb_dao; - hw->daio_mgr_dao_init = daio_mgr_dao_init; - hw->daio_mgr_set_imaparc = daio_mgr_set_imaparc; - hw->daio_mgr_set_imapnxt = daio_mgr_set_imapnxt; - hw->daio_mgr_set_imapaddr = daio_mgr_set_imapaddr; - hw->daio_mgr_commit_write = daio_mgr_commit_write; - + *hw = ct20k2_preset; *rhw = hw; return 0; diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c index bf232e7299ac..279dac6c34dd 100644 --- a/sound/pci/ctxfi/xfi.c +++ b/sound/pci/ctxfi/xfi.c @@ -86,7 +86,7 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) card->private_data = atc; /* Create alsa devices supported by this card */ - err = atc->create_alsa_devs(atc); + err = ct_atc_create_alsa_devs(atc); if (err < 0) goto error; -- cgit v1.2.3 From 54de6bc8b2437f642844cecb8d183df2368ffceb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 8 Jun 2009 10:21:07 +0200 Subject: ALSA: ctxfi - Optimize the native timer handling using wc counter Optimize the timer update routine to look up wall clock once instead of checking the position of each stream at each timer update. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/cthardware.h | 1 + sound/pci/ctxfi/cthw20k1.c | 6 ++++ sound/pci/ctxfi/cttimer.c | 76 ++++++++++++++++++++++++++++---------------- 3 files changed, 55 insertions(+), 28 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h index 35350cf9d2f2..8f11644ddc92 100644 --- a/sound/pci/ctxfi/cthardware.h +++ b/sound/pci/ctxfi/cthardware.h @@ -147,6 +147,7 @@ struct hw { int (*set_timer_irq)(struct hw *hw, int enable); int (*set_timer_tick)(struct hw *hw, unsigned int tick); + unsigned int (*get_wc)(struct hw *hw); void (*irq_callback)(void *data, unsigned int bit); void *irq_callback_data; diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index df565c11fcca..b165466e1a54 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1186,6 +1186,11 @@ static int set_timer_tick(struct hw *hw, unsigned int ticks) return 0; } +static unsigned int get_wc(struct hw *hw) +{ + return hw_read_20kx(hw, WC); +} + /* Card hardware initialization block */ struct dac_conf { unsigned int msr; /* master sample rate in rsrs */ @@ -2235,6 +2240,7 @@ static struct hw ct20k1_preset __devinitdata = { .set_timer_irq = set_timer_irq, .set_timer_tick = set_timer_tick, + .get_wc = get_wc, }; int __devinit create_20k1_hw_obj(struct hw **rhw) diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c index ceda74e356cb..ec869a4fe2b3 100644 --- a/sound/pci/ctxfi/cttimer.c +++ b/sound/pci/ctxfi/cttimer.c @@ -47,6 +47,7 @@ struct ct_timer { struct ct_timer_ops *ops; struct list_head instance_head; struct list_head running_head; + unsigned int wc; /* current wallclock */ unsigned int irq_handling:1; /* in IRQ handling */ unsigned int reprogram:1; /* need to reprogram the internval */ unsigned int running:1; /* global timer running */ @@ -136,6 +137,7 @@ static struct ct_timer_ops ct_systimer_ops = { */ #define CT_TIMER_FREQ 48000 +#define MIN_TICKS 1 #define MAX_TICKS ((1 << 13) - 1) static void ct_xfitimer_irq_rearm(struct ct_timer *atimer, int ticks) @@ -159,6 +161,12 @@ static void ct_xfitimer_irq_stop(struct ct_timer *atimer) } } +static inline unsigned int ct_xfitimer_get_wc(struct ct_timer *atimer) +{ + struct hw *hw = atimer->atc->hw; + return hw->get_wc(hw); +} + /* * reprogram the timer interval; * checks the running instance list and determines the next timer interval. @@ -170,37 +178,46 @@ static void ct_xfitimer_irq_stop(struct ct_timer *atimer) static int ct_xfitimer_reprogram(struct ct_timer *atimer) { struct ct_timer_instance *ti; - int min_intr = -1; + unsigned int min_intr = (unsigned int)-1; int updates = 0; + unsigned int wc, diff; + if (list_empty(&atimer->running_head)) { + ct_xfitimer_irq_stop(atimer); + atimer->reprogram = 0; /* clear flag */ + return 0; + } + + wc = ct_xfitimer_get_wc(atimer); + diff = wc - atimer->wc; + atimer->wc = wc; list_for_each_entry(ti, &atimer->running_head, running_list) { - struct snd_pcm_runtime *runtime; - unsigned int pos, diff; - int intr; - runtime = ti->substream->runtime; - pos = ti->substream->ops->pointer(ti->substream); - if (pos < ti->position) - diff = runtime->buffer_size - ti->position + pos; - else - diff = pos - ti->position; - ti->position = pos; - while (diff >= ti->frag_count) { - ti->frag_count += runtime->period_size; - ti->need_update = 1; - updates++; + if (ti->frag_count > diff) + ti->frag_count -= diff; + else { + unsigned int pos; + unsigned int period_size, rate; + + period_size = ti->substream->runtime->period_size; + rate = ti->substream->runtime->rate; + pos = ti->substream->ops->pointer(ti->substream); + if (pos / period_size != ti->position / period_size) { + ti->need_update = 1; + ti->position = pos; + updates++; + } + pos %= period_size; + pos = period_size - pos; + ti->frag_count = div_u64((u64)pos * CT_TIMER_FREQ + + rate - 1, rate); } - ti->frag_count -= diff; - intr = div_u64((u64)ti->frag_count * CT_TIMER_FREQ, - runtime->rate); - if (min_intr < 0 || intr < min_intr) - min_intr = intr; + if (ti->frag_count < min_intr) + min_intr = ti->frag_count; } - if (min_intr > 0) - ct_xfitimer_irq_rearm(atimer, min_intr); - else - ct_xfitimer_irq_stop(atimer); - + if (min_intr < MIN_TICKS) + min_intr = MIN_TICKS; + ct_xfitimer_irq_rearm(atimer, min_intr); atimer->reprogram = 0; /* clear flag */ return updates; } @@ -253,13 +270,14 @@ static void ct_xfitimer_update(struct ct_timer *atimer) unsigned long flags; int update; + spin_lock_irqsave(&atimer->lock, flags); if (atimer->irq_handling) { /* reached from IRQ handler; let it handle later */ atimer->reprogram = 1; + spin_unlock_irqrestore(&atimer->lock, flags); return; } - spin_lock_irqsave(&atimer->lock, flags); ct_xfitimer_irq_stop(atimer); update = ct_xfitimer_reprogram(atimer); spin_unlock_irqrestore(&atimer->lock, flags); @@ -273,6 +291,8 @@ static void ct_xfitimer_start(struct ct_timer_instance *ti) unsigned long flags; spin_lock_irqsave(&atimer->lock, flags); + if (list_empty(&ti->running_list)) + atimer->wc = ct_xfitimer_get_wc(atimer); list_add(&ti->running_list, &atimer->running_head); spin_unlock_irqrestore(&atimer->lock, flags); ct_xfitimer_update(atimer); @@ -396,12 +416,12 @@ struct ct_timer *ct_timer_new(struct ct_atc *atc) atimer->atc = atc; hw = atc->hw; if (!USE_SYSTEM_TIMER && hw->set_timer_irq) { - printk(KERN_INFO "ctxfi: Use xfi-native timer\n"); + snd_printd(KERN_INFO "ctxfi: Use xfi-native timer\n"); atimer->ops = &ct_xfitimer_ops; hw->irq_callback_data = atimer; hw->irq_callback = ct_timer_interrupt; } else { - printk(KERN_INFO "ctxfi: Use system timer\n"); + snd_printd(KERN_INFO "ctxfi: Use system timer\n"); atimer->ops = &ct_systimer_ops; } return atimer; -- cgit v1.2.3 From 514eef9c2a711b4c24b97bb456d39695a6fe1775 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 8 Jun 2009 14:57:57 +0200 Subject: ALSA: ctxfi - Remove useless initializations and cast Remove useless variable initializations and cast at the beginning of functions. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctamixer.c | 62 ++++++++-------- sound/pci/ctxfi/ctatc.c | 164 ++++++++++++++++++++++--------------------- sound/pci/ctxfi/ctdaio.c | 40 +++++------ sound/pci/ctxfi/cthardware.c | 6 +- sound/pci/ctxfi/cthw20k1.c | 82 +++++++++++----------- sound/pci/ctxfi/cthw20k2.c | 52 +++++++------- sound/pci/ctxfi/ctimap.c | 4 +- sound/pci/ctxfi/ctmixer.c | 60 ++++++++-------- sound/pci/ctxfi/ctresource.c | 6 +- sound/pci/ctxfi/ctsrc.c | 110 ++++++++++++++--------------- sound/pci/ctxfi/ctvmem.c | 12 ++-- 11 files changed, 301 insertions(+), 297 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c index 859e996ad728..a1db51b3ead8 100644 --- a/sound/pci/ctxfi/ctamixer.c +++ b/sound/pci/ctxfi/ctamixer.c @@ -58,9 +58,9 @@ static struct rsc_ops amixer_basic_rsc_ops = { static int amixer_set_input(struct amixer *amixer, struct rsc *rsc) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)amixer->rsc.hw; + hw = amixer->rsc.hw; hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE); amixer->input = rsc; if (NULL == rsc) @@ -75,9 +75,9 @@ static int amixer_set_input(struct amixer *amixer, struct rsc *rsc) /* y is a 14-bit immediate constant */ static int amixer_set_y(struct amixer *amixer, unsigned int y) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)amixer->rsc.hw; + hw = amixer->rsc.hw; hw->amixer_set_y(amixer->rsc.ctrl_blk, y); return 0; @@ -85,9 +85,9 @@ static int amixer_set_y(struct amixer *amixer, unsigned int y) static int amixer_set_invalid_squash(struct amixer *amixer, unsigned int iv) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)amixer->rsc.hw; + hw = amixer->rsc.hw; hw->amixer_set_iv(amixer->rsc.ctrl_blk, iv); return 0; @@ -95,9 +95,9 @@ static int amixer_set_invalid_squash(struct amixer *amixer, unsigned int iv) static int amixer_set_sum(struct amixer *amixer, struct sum *sum) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)amixer->rsc.hw; + hw = amixer->rsc.hw; amixer->sum = sum; if (NULL == sum) { hw->amixer_set_se(amixer->rsc.ctrl_blk, 0); @@ -112,13 +112,13 @@ static int amixer_set_sum(struct amixer *amixer, struct sum *sum) static int amixer_commit_write(struct amixer *amixer) { - struct hw *hw = NULL; - unsigned int index = 0; - int i = 0; - struct rsc *input = NULL; - struct sum *sum = NULL; + struct hw *hw; + unsigned int index; + int i; + struct rsc *input; + struct sum *sum; - hw = (struct hw *)amixer->rsc.hw; + hw = amixer->rsc.hw; input = amixer->input; sum = amixer->sum; @@ -158,10 +158,10 @@ static int amixer_commit_write(struct amixer *amixer) static int amixer_commit_raw_write(struct amixer *amixer) { - struct hw *hw = NULL; - unsigned int index = 0; + struct hw *hw; + unsigned int index; - hw = (struct hw *)amixer->rsc.hw; + hw = amixer->rsc.hw; index = amixer->rsc.ops->output_slot(&amixer->rsc); hw->amixer_commit_write(hw, index, amixer->rsc.ctrl_blk); @@ -170,9 +170,9 @@ static int amixer_commit_raw_write(struct amixer *amixer) static int amixer_get_y(struct amixer *amixer) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)amixer->rsc.hw; + hw = amixer->rsc.hw; return hw->amixer_get_y(amixer->rsc.ctrl_blk); } @@ -201,7 +201,7 @@ static int amixer_rsc_init(struct amixer *amixer, const struct amixer_desc *desc, struct amixer_mgr *mgr) { - int err = 0; + int err; err = rsc_init(&amixer->rsc, amixer->idx[0], AMIXER, desc->msr, mgr->mgr.hw); @@ -233,9 +233,9 @@ static int get_amixer_rsc(struct amixer_mgr *mgr, const struct amixer_desc *desc, struct amixer **ramixer) { - int err = 0, i = 0; - unsigned int idx = 0; - struct amixer *amixer = NULL; + int err, i; + unsigned int idx; + struct amixer *amixer; unsigned long flags; *ramixer = NULL; @@ -284,7 +284,7 @@ error: static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer) { unsigned long flags; - int i = 0; + int i; spin_lock_irqsave(&mgr->mgr_lock, flags); for (i = 0; i < amixer->rsc.msr; i++) @@ -299,7 +299,7 @@ static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer) int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr) { - int err = 0; + int err; struct amixer_mgr *amixer_mgr; *ramixer_mgr = NULL; @@ -367,7 +367,7 @@ static int sum_rsc_init(struct sum *sum, const struct sum_desc *desc, struct sum_mgr *mgr) { - int err = 0; + int err; err = rsc_init(&sum->rsc, sum->idx[0], SUM, desc->msr, mgr->mgr.hw); if (err) @@ -388,9 +388,9 @@ static int get_sum_rsc(struct sum_mgr *mgr, const struct sum_desc *desc, struct sum **rsum) { - int err = 0, i = 0; - unsigned int idx = 0; - struct sum *sum = NULL; + int err, i; + unsigned int idx; + struct sum *sum; unsigned long flags; *rsum = NULL; @@ -438,7 +438,7 @@ error: static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum) { unsigned long flags; - int i = 0; + int i; spin_lock_irqsave(&mgr->mgr_lock, flags); for (i = 0; i < sum->rsc.msr; i++) @@ -453,7 +453,7 @@ static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum) int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr) { - int err = 0; + int err; struct sum_mgr *sum_mgr; *rsum_mgr = NULL; diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 9b1324544db0..7898a375df0e 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -190,8 +190,8 @@ static unsigned int convert_format(snd_pcm_format_t snd_format) static unsigned int atc_get_pitch(unsigned int input_rate, unsigned int output_rate) { - unsigned int pitch = 0; - int b = 0; + unsigned int pitch; + int b; /* get pitch and convert to fixed-point 8.24 format. */ pitch = (input_rate / output_rate) << 24; @@ -241,12 +241,12 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER]; struct src_desc desc = {0}; struct amixer_desc mix_dsc = {0}; - struct src *src = NULL; - struct amixer *amixer = NULL; - int err = 0; + struct src *src; + struct amixer *amixer; + int err; int n_amixer = apcm->substream->runtime->channels, i = 0; int device = apcm->substream->pcm->device; - unsigned int pitch = 0; + unsigned int pitch; unsigned long flags; if (NULL != apcm->src) { @@ -324,8 +324,8 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP]; struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER]; struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM]; - struct srcimp *srcimp = NULL; - int i = 0; + struct srcimp *srcimp; + int i; if (NULL != apcm->srcimps) { for (i = 0; i < apcm->n_srcimp; i++) { @@ -377,7 +377,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm) { - unsigned int max_cisz = 0; + unsigned int max_cisz; struct src *src = apcm->src; max_cisz = src->multi * src->rsc.msr; @@ -398,8 +398,8 @@ static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm) static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm) { - struct src *src = NULL; - int i = 0; + struct src *src; + int i; ct_timer_stop(apcm->timer); @@ -426,8 +426,8 @@ static int atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm) { struct src *src = apcm->src; - u32 size = 0, max_cisz = 0; - int position = 0; + u32 size, max_cisz; + int position; position = src->ops->get_ca(src); @@ -449,7 +449,7 @@ struct src_node_conf_t { static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm, struct src_node_conf_t *conf, int *n_srcc) { - unsigned int pitch = 0; + unsigned int pitch; /* get pitch and convert to fixed-point 8.24 format. */ pitch = atc_get_pitch((atc->rsr * atc->msr), @@ -494,14 +494,14 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER]; struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM]; struct src_desc src_dsc = {0}; - struct src *src = NULL; + struct src *src; struct srcimp_desc srcimp_dsc = {0}; - struct srcimp *srcimp = NULL; + struct srcimp *srcimp; struct amixer_desc mix_dsc = {0}; struct sum_desc sum_dsc = {0}; - unsigned int pitch = 0; - int multi = 0, err = 0, i = 0; - int n_srcimp = 0, n_amixer = 0, n_srcc = 0, n_sum = 0; + unsigned int pitch; + int multi, err, i; + int n_srcimp, n_amixer, n_srcc, n_sum; struct src_node_conf_t src_node_conf[2] = {{0} }; /* first release old resources */ @@ -518,8 +518,8 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) setup_src_node_conf(atc, apcm, src_node_conf, &n_srcc); n_sum = (1 == multi) ? 1 : 0; - n_amixer += n_sum * 2 + n_srcc; - n_srcimp += n_srcc; + n_amixer = n_sum * 2 + n_srcc; + n_srcimp = n_srcc; if ((multi > 1) && (0x8000000 >= pitch)) { /* Need extra AMIXERs and SRCIMPs for special treatment * of interleaved recording of conjugate channels */ @@ -633,14 +633,14 @@ error1: static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) { - struct src *src = NULL; - struct amixer *amixer = NULL; - struct srcimp *srcimp = NULL; + struct src *src; + struct amixer *amixer; + struct srcimp *srcimp; struct ct_mixer *mixer = atc->mixer; - struct sum *mono = NULL; + struct sum *mono; struct rsc *out_ports[8] = {NULL}; - int err = 0, i = 0, j = 0, n_sum = 0, multi = 0; - unsigned int pitch = 0; + int err, i, j, n_sum, multi; + unsigned int pitch; int mix_base = 0, imp_base = 0; if (NULL != apcm->src) { @@ -714,9 +714,9 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm) { - struct src *src = NULL; + struct src *src; struct src_mgr *src_mgr = atc->rsc_mgrs[SRC]; - int i = 0, multi = 0; + int i, multi; if (apcm->started) return 0; @@ -776,10 +776,10 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc, struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER]; struct src_desc desc = {0}; struct amixer_desc mix_dsc = {0}; - struct src *src = NULL; - int err = 0; - int n_amixer = apcm->substream->runtime->channels, i = 0; - unsigned int pitch = 0, rsr = atc->pll_rate; + struct src *src; + int err; + int n_amixer = apcm->substream->runtime->channels, i; + unsigned int pitch, rsr = atc->pll_rate; /* first release old resources */ atc->pcm_release_resources(atc, apcm); @@ -832,15 +832,24 @@ error1: return err; } +static int atc_pll_init(struct ct_atc *atc, int rate) +{ + struct hw *hw = atc->hw; + int err; + err = hw->pll_init(hw, rate); + atc->pll_rate = err ? 0 : rate; + return err; +} + static int spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) { struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); unsigned long flags; unsigned int rate = apcm->substream->runtime->rate; - unsigned int status = 0; - int err = 0; - unsigned char iec958_con_fs = 0; + unsigned int status; + int err; + unsigned char iec958_con_fs; switch (rate) { case 48000: @@ -864,10 +873,8 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) dao->ops->set_spos(dao, status); dao->ops->commit_write(dao); } - if ((rate != atc->pll_rate) && (32000 != rate)) { - err = ((struct hw *)atc->hw)->pll_init(atc->hw, rate); - atc->pll_rate = err ? 0 : rate; - } + if ((rate != atc->pll_rate) && (32000 != rate)) + err = atc_pll_init(atc, rate); spin_unlock_irqrestore(&atc->atc_lock, flags); return err; @@ -876,11 +883,11 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) static int spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) { - struct src *src = NULL; - struct amixer *amixer = NULL; - struct dao *dao = NULL; - int err = 0; - int i = 0; + struct src *src; + struct amixer *amixer; + struct dao *dao; + int err; + int i; unsigned long flags; if (NULL != apcm->src) @@ -924,7 +931,7 @@ static int atc_select_line_in(struct ct_atc *atc) { struct hw *hw = atc->hw; struct ct_mixer *mixer = atc->mixer; - struct src *src = NULL; + struct src *src; if (hw->is_adc_source_selected(hw, ADC_LINEIN)) return 0; @@ -946,7 +953,7 @@ static int atc_select_mic_in(struct ct_atc *atc) { struct hw *hw = atc->hw; struct ct_mixer *mixer = atc->mixer; - struct src *src = NULL; + struct src *src; if (hw->is_adc_source_selected(hw, ADC_MICIN)) return 0; @@ -1063,8 +1070,8 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) { unsigned long flags; struct dao_desc da_dsc = {0}; - struct dao *dao = NULL; - int err = 0; + struct dao *dao; + int err; struct ct_mixer *mixer = atc->mixer; struct rsc *rscs[2] = {NULL}; unsigned int spos = 0; @@ -1082,11 +1089,8 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) dao->ops->set_left_input(dao, rscs[0]); dao->ops->set_right_input(dao, rscs[1]); /* Restore PLL to atc->rsr if needed. */ - if (atc->pll_rate != atc->rsr) { - err = ((struct hw *)atc->hw)->pll_init(atc->hw, - atc->rsr); - atc->pll_rate = err ? 0 : atc->rsr; - } + if (atc->pll_rate != atc->rsr) + err = atc_pll_init(atc, atc->rsr); } dao->ops->set_spos(dao, spos); dao->ops->commit_write(dao); @@ -1097,15 +1101,15 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) static int ct_atc_destroy(struct ct_atc *atc) { - struct daio_mgr *daio_mgr = NULL; - struct dao *dao = NULL; - struct dai *dai = NULL; - struct daio *daio = NULL; - struct sum_mgr *sum_mgr = NULL; - struct src_mgr *src_mgr = NULL; - struct srcimp_mgr *srcimp_mgr = NULL; - struct srcimp *srcimp = NULL; - struct ct_mixer *mixer = NULL; + struct daio_mgr *daio_mgr; + struct dao *dao; + struct dai *dai; + struct daio *daio; + struct sum_mgr *sum_mgr; + struct src_mgr *src_mgr; + struct srcimp_mgr *srcimp_mgr; + struct srcimp *srcimp; + struct ct_mixer *mixer; int i = 0; if (NULL == atc) @@ -1279,9 +1283,9 @@ int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc) static int __devinit atc_create_hw_devs(struct ct_atc *atc) { - struct hw *hw = NULL; + struct hw *hw; struct card_conf info = {0}; - int i = 0, err = 0; + int i, err; err = create_hw_obj(atc->pci, &hw); if (err) { @@ -1316,14 +1320,14 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc) static int __devinit atc_get_resources(struct ct_atc *atc) { struct daio_desc da_desc = {0}; - struct daio_mgr *daio_mgr = NULL; + struct daio_mgr *daio_mgr; struct src_desc src_dsc = {0}; - struct src_mgr *src_mgr = NULL; + struct src_mgr *src_mgr; struct srcimp_desc srcimp_dsc = {0}; - struct srcimp_mgr *srcimp_mgr = NULL; + struct srcimp_mgr *srcimp_mgr; struct sum_desc sum_dsc = {0}; - struct sum_mgr *sum_mgr = NULL; - int err = 0, i = 0; + struct sum_mgr *sum_mgr; + int err, i; unsigned short subsys_id; atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL); @@ -1428,8 +1432,8 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, struct src **srcs, struct srcimp **srcimps) { struct rsc *rscs[2] = {NULL}; - struct src *src = NULL; - struct srcimp *srcimp = NULL; + struct src *src; + struct srcimp *srcimp; int i = 0; rscs[0] = &dai->daio.rscl; @@ -1464,13 +1468,13 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, static void __devinit atc_connect_resources(struct ct_atc *atc) { - struct dai *dai = NULL; - struct dao *dao = NULL; - struct src *src = NULL; - struct sum *sum = NULL; - struct ct_mixer *mixer = NULL; + struct dai *dai; + struct dao *dao; + struct src *src; + struct sum *sum; + struct ct_mixer *mixer; struct rsc *rscs[2] = {NULL}; - int i = 0, j = 0; + int i, j; mixer = atc->mixer; @@ -1553,11 +1557,11 @@ static struct ct_atc atc_preset __devinitdata = { int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, unsigned int rsr, unsigned int msr, struct ct_atc **ratc) { - struct ct_atc *atc = NULL; + struct ct_atc *atc; static struct snd_device_ops ops = { .dev_free = atc_dev_free, }; - int err = 0; + int err; *ratc = NULL; diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index a2aea399eba1..befead4eeaab 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -168,9 +168,9 @@ static int dao_commit_write(struct dao *dao) static int dao_set_left_input(struct dao *dao, struct rsc *input) { - struct imapper *entry = NULL; + struct imapper *entry; struct daio *daio = &dao->daio; - int i = 0; + int i; entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL); if (NULL == entry) @@ -196,9 +196,9 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input) static int dao_set_right_input(struct dao *dao, struct rsc *input) { - struct imapper *entry = NULL; + struct imapper *entry; struct daio *daio = &dao->daio; - int i = 0; + int i; entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL); if (NULL == entry) @@ -224,9 +224,9 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input) static int dao_clear_left_input(struct dao *dao) { - struct imapper *entry = NULL; + struct imapper *entry; struct daio *daio = &dao->daio; - int i = 0; + int i; if (NULL == dao->imappers[0]) return 0; @@ -248,9 +248,9 @@ static int dao_clear_left_input(struct dao *dao) static int dao_clear_right_input(struct dao *dao) { - struct imapper *entry = NULL; + struct imapper *entry; struct daio *daio = &dao->daio; - int i = 0; + int i; if (NULL == dao->imappers[daio->rscl.msr]) return 0; @@ -299,7 +299,7 @@ static int dai_set_srt_srcr(struct dai *dai, struct rsc *src) static int dai_set_srt_msr(struct dai *dai, unsigned int msr) { - unsigned int rsr = 0; + unsigned int rsr; for (rsr = 0; msr > 1; msr >>= 1) rsr++; @@ -340,8 +340,8 @@ static int daio_rsc_init(struct daio *daio, const struct daio_desc *desc, void *hw) { - int err = 0; - unsigned int idx_l = 0, idx_r = 0; + int err; + unsigned int idx_l, idx_r; switch (((struct hw *)hw)->get_chip_type(hw)) { case ATC20K1: @@ -400,8 +400,8 @@ static int dao_rsc_init(struct dao *dao, struct daio_mgr *mgr) { struct hw *hw = mgr->mgr.hw; - unsigned int conf = 0; - int err = 0; + unsigned int conf; + int err; err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw); if (err) @@ -423,7 +423,7 @@ static int dao_rsc_init(struct dao *dao, daio_device_index(dao->daio.type, hw)); hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); - conf |= (desc->msr & 0x7) | (desc->passthru << 3); + conf = (desc->msr & 0x7) | (desc->passthru << 3); hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk, daio_device_index(dao->daio.type, hw), conf); hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, @@ -475,9 +475,9 @@ static int dai_rsc_init(struct dai *dai, const struct daio_desc *desc, struct daio_mgr *mgr) { - int err = 0; + int err; struct hw *hw = mgr->mgr.hw; - unsigned int rsr = 0, msr = 0; + unsigned int rsr, msr; err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw); if (err) @@ -536,7 +536,7 @@ static int get_daio_rsc(struct daio_mgr *mgr, const struct daio_desc *desc, struct daio **rdaio) { - int err = 0; + int err; struct dai *dai = NULL; struct dao *dao = NULL; unsigned long flags; @@ -660,7 +660,7 @@ static int daio_map_op(void *data, struct imapper *entry) static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry) { unsigned long flags; - int err = 0; + int err; spin_lock_irqsave(&mgr->imap_lock, flags); if ((0 == entry->addr) && (mgr->init_imap_added)) { @@ -677,7 +677,7 @@ static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry) static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry) { unsigned long flags; - int err = 0; + int err; spin_lock_irqsave(&mgr->imap_lock, flags); err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr); @@ -701,7 +701,7 @@ static int daio_mgr_commit_write(struct daio_mgr *mgr) int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr) { - int err = 0, i = 0; + int err, i; struct daio_mgr *daio_mgr; struct imapper *entry; diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c index 53d1acadc0e8..5ec6813d3911 100644 --- a/sound/pci/ctxfi/cthardware.c +++ b/sound/pci/ctxfi/cthardware.c @@ -22,7 +22,7 @@ static enum CHIPTYP __devinitdata get_chip_type(struct hw *hw) { - enum CHIPTYP type = ATCNONE; + enum CHIPTYP type; switch (hw->pci->device) { case 0x0005: /* 20k1 device */ @@ -41,7 +41,7 @@ static enum CHIPTYP __devinitdata get_chip_type(struct hw *hw) int __devinit create_hw_obj(struct pci_dev *pci, struct hw **rhw) { - int err = 0; + int err; switch (pci->device) { case 0x0005: /* 20k1 device */ @@ -65,7 +65,7 @@ int __devinit create_hw_obj(struct pci_dev *pci, struct hw **rhw) int destroy_hw_obj(struct hw *hw) { - int err = 0; + int err; switch (hw->pci->device) { case 0x0005: /* 20k1 device */ diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index b165466e1a54..38b87b6ee6d4 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -369,7 +369,7 @@ static unsigned int src_param_pitch_mixer(unsigned int src_idx) static int src_commit_write(struct hw *hw, unsigned int idx, void *blk) { struct src_rsc_ctrl_blk *ctl = blk; - int i = 0; + int i; if (ctl->dirty.bf.czbfs) { /* Clear Z-Buffer registers */ @@ -468,8 +468,8 @@ static int src_mgr_dsb_src(void *blk, unsigned int idx) static int src_mgr_commit_write(struct hw *hw, void *blk) { struct src_mgr_ctrl_blk *ctl = blk; - int i = 0; - unsigned int ret = 0; + int i; + unsigned int ret; if (ctl->dirty.bf.enbsa) { do { @@ -1108,7 +1108,7 @@ static int daio_mgr_set_imapaddr(void *blk, unsigned int addr) static int daio_mgr_commit_write(struct hw *hw, void *blk) { struct daio_mgr_ctrl_blk *ctl = blk; - int i = 0; + int i; if (ctl->dirty.bf.i2sictl || ctl->dirty.bf.i2soctl) { for (i = 0; i < 4; i++) { @@ -1212,8 +1212,8 @@ struct trn_conf { static int hw_daio_init(struct hw *hw, const struct daio_conf *info) { - u32 i2sorg = 0; - u32 spdorg = 0; + u32 i2sorg; + u32 spdorg; /* Read I2S CTL. Keep original value. */ /*i2sorg = hw_read_20kx(hw, I2SCTL);*/ @@ -1263,8 +1263,8 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info) /* TRANSPORT operations */ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) { - u32 trnctl = 0; - unsigned long ptp_phys_low = 0, ptp_phys_high = 0; + u32 trnctl; + u32 ptp_phys_low, ptp_phys_high; /* Set up device page table */ if ((~0UL) == info->vm_pgt_phys) { @@ -1316,7 +1316,7 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) static int hw_pll_init(struct hw *hw, unsigned int rsr) { unsigned int pllctl; - int i = 0; + int i; pllctl = (48000 == rsr) ? 0x1480a001 : 0x1480a731; for (i = 0; i < 3; i++) { @@ -1384,7 +1384,7 @@ static void i2c_lock(struct hw *hw) static void i2c_write(struct hw *hw, u32 device, u32 addr, u32 data) { - unsigned int ret = 0; + unsigned int ret; do { ret = hw_read_pci(hw, 0xEC); @@ -1397,9 +1397,9 @@ static void i2c_write(struct hw *hw, u32 device, u32 addr, u32 data) static int hw_reset_dac(struct hw *hw) { - u32 i = 0; - u16 gpioorg = 0; - unsigned int ret = 0; + u32 i; + u16 gpioorg; + unsigned int ret; if (i2c_unlock(hw)) return -1; @@ -1430,10 +1430,10 @@ static int hw_reset_dac(struct hw *hw) static int hw_dac_init(struct hw *hw, const struct dac_conf *info) { - u32 data = 0; - u16 gpioorg = 0; - u16 subsys_id = 0; - unsigned int ret = 0; + u32 data; + u16 gpioorg; + u16 subsys_id; + unsigned int ret; pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { @@ -1494,13 +1494,12 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info) static int is_adc_input_selected_SB055x(struct hw *hw, enum ADCSRC type) { - u32 data = 0; - return data; + return 0; } static int is_adc_input_selected_SBx(struct hw *hw, enum ADCSRC type) { - u32 data = 0; + u32 data; data = hw_read_20kx(hw, GPIO); switch (type) { @@ -1521,7 +1520,7 @@ static int is_adc_input_selected_SBx(struct hw *hw, enum ADCSRC type) static int is_adc_input_selected_hendrix(struct hw *hw, enum ADCSRC type) { - u32 data = 0; + u32 data; data = hw_read_20kx(hw, GPIO); switch (type) { @@ -1539,7 +1538,7 @@ static int is_adc_input_selected_hendrix(struct hw *hw, enum ADCSRC type) static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) { - u16 subsys_id = 0; + u16 subsys_id; pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { @@ -1559,7 +1558,7 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) static int adc_input_select_SB055x(struct hw *hw, enum ADCSRC type, unsigned char boost) { - u32 data = 0; + u32 data; /* * check and set the following GPIO bits accordingly @@ -1599,9 +1598,9 @@ adc_input_select_SB055x(struct hw *hw, enum ADCSRC type, unsigned char boost) static int adc_input_select_SBx(struct hw *hw, enum ADCSRC type, unsigned char boost) { - u32 data = 0; - u32 i2c_data = 0; - unsigned int ret = 0; + u32 data; + u32 i2c_data; + unsigned int ret; if (i2c_unlock(hw)) return -1; @@ -1649,9 +1648,9 @@ adc_input_select_SBx(struct hw *hw, enum ADCSRC type, unsigned char boost) static int adc_input_select_hendrix(struct hw *hw, enum ADCSRC type, unsigned char boost) { - u32 data = 0; - u32 i2c_data = 0; - unsigned int ret = 0; + u32 data; + u32 i2c_data; + unsigned int ret; if (i2c_unlock(hw)) return -1; @@ -1693,7 +1692,7 @@ adc_input_select_hendrix(struct hw *hw, enum ADCSRC type, unsigned char boost) static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) { - u16 subsys_id = 0; + u16 subsys_id; pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { @@ -1719,8 +1718,8 @@ static int adc_init_SBx(struct hw *hw, int input, int mic20db) { u16 gpioorg; u16 input_source; - u32 adcdata = 0; - unsigned int ret = 0; + u32 adcdata; + unsigned int ret; input_source = 0x100; /* default to analog */ switch (input) { @@ -1742,6 +1741,7 @@ static int adc_init_SBx(struct hw *hw, int input, int mic20db) input_source = 0x0; /* set to Digital */ break; default: + adcdata = 0x0; break; } @@ -1781,8 +1781,8 @@ static int adc_init_SBx(struct hw *hw, int input, int mic20db) static int hw_adc_init(struct hw *hw, const struct adc_conf *info) { - int err = 0; - u16 subsys_id = 0; + int err; + u16 subsys_id; pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { @@ -1797,7 +1797,7 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info) static int hw_have_digit_io_switch(struct hw *hw) { - u16 subsys_id = 0; + u16 subsys_id; pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); /* SB073x and Vista compatible cards have no digit IO switch */ @@ -1814,11 +1814,11 @@ static int uaa_to_xfi(struct pci_dev *pci) { unsigned int bar0, bar1, bar2, bar3, bar4, bar5; unsigned int cmd, irq, cl_size, l_timer, pwr; - unsigned int is_uaa = 0; + unsigned int is_uaa; unsigned int data[4] = {0}; unsigned int io_base; void *mem_base; - int i = 0; + int i; const u32 CTLX = CTLBITS('C', 'T', 'L', 'X'); const u32 CTL_ = CTLBITS('C', 'T', 'L', '-'); const u32 CTLF = CTLBITS('C', 'T', 'L', 'F'); @@ -1916,9 +1916,9 @@ static irqreturn_t ct_20k1_interrupt(int irq, void *dev_id) static int hw_card_start(struct hw *hw) { - int err = 0; + int err; struct pci_dev *pci = hw->pci; - u16 subsys_id = 0; + u16 subsys_id; err = pci_enable_device(pci); if (err < 0) @@ -2004,8 +2004,8 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) { int err; unsigned int gctl; - u16 subsys_id = 0; - u32 data = 0; + u16 subsys_id; + u32 data; struct dac_conf dac_info = {0}; struct adc_conf adc_info = {0}; struct daio_conf daio_info = {0}; diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index edbfb4827469..7d6dcbaf5244 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk) static int src_put_rsc_ctrl_blk(void *blk) { - kfree((struct src_rsc_ctrl_blk *)blk); + kfree(blk); return 0; } @@ -359,7 +359,7 @@ static unsigned int src_param_pitch_mixer(unsigned int src_idx) static int src_commit_write(struct hw *hw, unsigned int idx, void *blk) { struct src_rsc_ctrl_blk *ctl = blk; - int i = 0; + int i; if (ctl->dirty.bf.czbfs) { /* Clear Z-Buffer registers */ @@ -458,8 +458,8 @@ static int src_mgr_dsb_src(void *blk, unsigned int idx) static int src_mgr_commit_write(struct hw *hw, void *blk) { struct src_mgr_ctrl_blk *ctl = blk; - int i = 0; - unsigned int ret = 0; + int i; + unsigned int ret; if (ctl->dirty.bf.enbsa) { do { @@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk) static int src_mgr_put_ctrl_blk(void *blk) { - kfree((struct src_mgr_ctrl_blk *)blk); + kfree(blk); return 0; } @@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk) static int srcimp_mgr_put_ctrl_blk(void *blk) { - kfree((struct srcimp_mgr_ctrl_blk *)blk); + kfree(blk); return 0; } @@ -704,7 +704,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk) static int amixer_rsc_put_ctrl_blk(void *blk) { - kfree((struct amixer_rsc_ctrl_blk *)blk); + kfree(blk); return 0; } @@ -893,7 +893,7 @@ static int dai_get_ctrl_blk(void **rblk) static int dai_put_ctrl_blk(void *blk) { - kfree((struct dai_ctrl_blk *)blk); + kfree(blk); return 0; } @@ -943,7 +943,7 @@ static int dao_get_ctrl_blk(void **rblk) static int dao_put_ctrl_blk(void *blk) { - kfree((struct dao_ctrl_blk *)blk); + kfree(blk); return 0; } @@ -1051,8 +1051,8 @@ static int daio_mgr_set_imapaddr(void *blk, unsigned int addr) static int daio_mgr_commit_write(struct hw *hw, void *blk) { struct daio_mgr_ctrl_blk *ctl = blk; - unsigned int data = 0; - int i = 0; + unsigned int data; + int i; for (i = 0; i < 8; i++) { if ((ctl->dirty.bf.atxctl & (0x1 << i))) { @@ -1080,7 +1080,7 @@ static int daio_mgr_commit_write(struct hw *hw, void *blk) static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) { struct daio_mgr_ctrl_blk *blk; - int i = 0; + int i; *rblk = NULL; blk = kzalloc(sizeof(*blk), GFP_KERNEL); @@ -1099,7 +1099,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) static int daio_mgr_put_ctrl_blk(void *blk) { - kfree((struct daio_mgr_ctrl_blk *)blk); + kfree(blk); return 0; } @@ -1125,7 +1125,7 @@ struct trn_conf { static int hw_daio_init(struct hw *hw, const struct daio_conf *info) { - u32 dwData = 0; + u32 dwData; int i; /* Program I2S with proper sample rate and enable the correct I2S @@ -1195,9 +1195,9 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info) /* TRANSPORT operations */ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) { - u32 vmctl = 0, data = 0; - unsigned long ptp_phys_low = 0, ptp_phys_high = 0; - int i = 0; + u32 vmctl, data; + u32 ptp_phys_low, ptp_phys_high; + int i; /* Set up device page table */ if ((~0UL) == info->vm_pgt_phys) { @@ -1433,7 +1433,7 @@ static int I2CLockChip(struct hw *hw) static int I2CInit(struct hw *hw, u8 bDeviceID, u8 bAddressSize, u8 bDataSize) { - int err = 0; + int err; unsigned int RegI2CStatus; unsigned int RegI2CAddress; @@ -1481,7 +1481,7 @@ static int I2CUninit(struct hw *hw) static int I2CWaitDataReady(struct hw *hw) { int i = 0x400000; - unsigned int ret = 0; + unsigned int ret; do { ret = hw_read_20kx(hw, I2C_IF_STATUS); @@ -1541,9 +1541,9 @@ static int I2CWrite(struct hw *hw, u16 wAddress, u32 dwData) static int hw_dac_init(struct hw *hw, const struct dac_conf *info) { - int err = 0; - u32 dwData = 0; - int i = 0; + int err; + u32 dwData; + int i; struct REGS_CS4382 cs4382_Read = {0}; struct REGS_CS4382 cs4382_Def = { 0x00000001, /* Mode Control 1 */ @@ -1696,7 +1696,7 @@ End: static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) { - u32 data = 0; + u32 data; data = hw_read_20kx(hw, GPIO_DATA); switch (type) { @@ -1714,7 +1714,7 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) { - u32 data = 0; + u32 data; data = hw_read_20kx(hw, GPIO_DATA); switch (type) { @@ -1747,8 +1747,8 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) static int hw_adc_init(struct hw *hw, const struct adc_conf *info) { - int err = 0; - u32 dwMux = 2, dwData = 0, dwCtl = 0; + int err; + u32 dwMux = 2, dwData, dwCtl; /* Set ADC reset bit as output */ dwData = hw_read_20kx(hw, GPIO_CTRL); diff --git a/sound/pci/ctxfi/ctimap.c b/sound/pci/ctxfi/ctimap.c index d34eacd902ce..0b73368a4df6 100644 --- a/sound/pci/ctxfi/ctimap.c +++ b/sound/pci/ctxfi/ctimap.c @@ -99,8 +99,8 @@ int input_mapper_delete(struct list_head *mappers, struct imapper *entry, void free_input_mapper_list(struct list_head *head) { - struct imapper *entry = NULL; - struct list_head *pos = NULL; + struct imapper *entry; + struct list_head *pos; while (!list_empty(head)) { pos = head->next; diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index 796156e4bd38..666722d9de41 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -298,7 +298,7 @@ set_switch_state(struct ct_mixer *mixer, * from 2^-6 to (1+1023/1024) */ static unsigned int uint16_to_float14(unsigned int x) { - unsigned int i = 0; + unsigned int i; if (x < 17) return 0; @@ -318,7 +318,7 @@ static unsigned int uint16_to_float14(unsigned int x) static unsigned int float14_to_uint16(unsigned int x) { - unsigned int e = 0; + unsigned int e; if (!x) return x; @@ -491,7 +491,7 @@ static int ct_alsa_mix_switch_put(struct snd_kcontrol *kcontrol, struct ct_atc *atc = snd_kcontrol_chip(kcontrol); struct ct_mixer *mixer = atc->mixer; enum CTALSA_MIXER_CTL type = kcontrol->private_value; - int state = 0; + int state; state = ucontrol->value.integer.value[0]; if (get_switch_state(mixer, type) == state) @@ -574,7 +574,7 @@ static int ct_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - unsigned int status = 0; + unsigned int status; atc->spdif_out_get_status(atc, &status); ucontrol->value.iec958.status[0] = (status >> 0) & 0xff; @@ -589,8 +589,8 @@ static int ct_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - int change = 1; - unsigned int status = 0, old_status = 0; + int change; + unsigned int status, old_status; status = (ucontrol->value.iec958.status[0] << 0) | (ucontrol->value.iec958.status[1] << 8) | @@ -641,8 +641,8 @@ static struct snd_kcontrol_new iec958_ctl = { static int ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new) { - struct snd_kcontrol *kctl = NULL; - int err = 0; + struct snd_kcontrol *kctl; + int err; kctl = snd_ctl_new1(new, mixer->atc); if (NULL == kctl) @@ -669,9 +669,9 @@ ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new) static int ct_mixer_kcontrols_create(struct ct_mixer *mixer) { - enum CTALSA_MIXER_CTL type = 0; + enum CTALSA_MIXER_CTL type; struct ct_atc *atc = mixer->atc; - int err = 0; + int err; /* Create snd kcontrol instances on demand */ for (type = VOL_MIXER_START; type <= VOL_MIXER_END; type++) { @@ -733,9 +733,9 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer) static void ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type) { - struct amixer *amix_d = NULL; - struct sum *sum_c = NULL; - int i = 0; + struct amixer *amix_d; + struct sum *sum_c; + int i; for (i = 0; i < 2; i++) { amix_d = mixer->amixers[type*CHN_NUM+i]; @@ -748,8 +748,8 @@ ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type) static void ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type) { - struct amixer *amix_d = NULL; - int i = 0; + struct amixer *amix_d; + int i; for (i = 0; i < 2; i++) { amix_d = mixer->amixers[type*CHN_NUM+i]; @@ -760,14 +760,14 @@ ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type) static int ct_mixer_get_resources(struct ct_mixer *mixer) { - struct sum_mgr *sum_mgr = NULL; - struct sum *sum = NULL; + struct sum_mgr *sum_mgr; + struct sum *sum; struct sum_desc sum_desc = {0}; - struct amixer_mgr *amixer_mgr = NULL; - struct amixer *amixer = NULL; + struct amixer_mgr *amixer_mgr; + struct amixer *amixer; struct amixer_desc am_desc = {0}; - int err = 0; - int i = 0; + int err; + int i; /* Allocate sum resources for mixer obj */ sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM]; @@ -822,8 +822,8 @@ error1: static int ct_mixer_get_mem(struct ct_mixer **rmixer) { - struct ct_mixer *mixer = NULL; - int err = 0; + struct ct_mixer *mixer; + int err; *rmixer = NULL; /* Allocate mem for mixer obj */ @@ -855,9 +855,9 @@ error1: static int ct_mixer_topology_build(struct ct_mixer *mixer) { - struct sum *sum = NULL; - struct amixer *amix_d = NULL, *amix_s = NULL; - enum CT_AMIXER_CTL i = 0, j = 0; + struct sum *sum; + struct amixer *amix_d, *amix_s; + enum CT_AMIXER_CTL i, j; /* Build topology from destination to source */ @@ -1044,7 +1044,7 @@ int ct_mixer_destroy(struct ct_mixer *mixer) struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM]; struct amixer_mgr *amixer_mgr = (struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER]; - struct amixer *amixer = NULL; + struct amixer *amixer; int i = 0; /* Release amixer resources */ @@ -1071,8 +1071,8 @@ int ct_mixer_destroy(struct ct_mixer *mixer) int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer) { - struct ct_mixer *mixer = NULL; - int err = 0; + struct ct_mixer *mixer; + int err; *rmixer = NULL; @@ -1109,7 +1109,7 @@ int ct_alsa_mix_create(struct ct_atc *atc, enum CTALSADEVS device, const char *device_name) { - int err = 0; + int err; /* Create snd kcontrol instances on demand */ /* vol_ctl.device = swh_ctl.device = device; */ /* better w/ device 0 */ diff --git a/sound/pci/ctxfi/ctresource.c b/sound/pci/ctxfi/ctresource.c index da21a717a07a..889c495bb7d1 100644 --- a/sound/pci/ctxfi/ctresource.c +++ b/sound/pci/ctxfi/ctresource.c @@ -27,7 +27,7 @@ static int get_resource(u8 *rscs, unsigned int amount, unsigned int multi, unsigned int *ridx) { - int i = 0, j = 0, k = 0, n = 0; + int i, j, k, n; /* Check whether there are sufficient resources to meet request. */ for (i = 0, n = multi; i < amount; i++) { @@ -61,7 +61,7 @@ get_resource(u8 *rscs, unsigned int amount, static int put_resource(u8 *rscs, unsigned int multi, unsigned int idx) { - unsigned int i = 0, j = 0, k = 0, n = 0; + unsigned int i, j, k, n; /* Mark the contiguous bits in resource bit-map as used */ for (n = multi, i = idx; n > 0; n--) { @@ -76,7 +76,7 @@ static int put_resource(u8 *rscs, unsigned int multi, unsigned int idx) int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx) { - int err = 0; + int err; if (n > mgr->avail) return -ENOENT; diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index 77e118c5bc97..e1c145d8b702 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c @@ -37,9 +37,9 @@ static int (*src_default_config[3])(struct src *) = { static int src_set_state(struct src *src, unsigned int state) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_state(src->rsc.ctrl_blk, state); return 0; @@ -47,9 +47,9 @@ static int src_set_state(struct src *src, unsigned int state) static int src_set_bm(struct src *src, unsigned int bm) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_bm(src->rsc.ctrl_blk, bm); return 0; @@ -57,9 +57,9 @@ static int src_set_bm(struct src *src, unsigned int bm) static int src_set_sf(struct src *src, unsigned int sf) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_sf(src->rsc.ctrl_blk, sf); return 0; @@ -67,9 +67,9 @@ static int src_set_sf(struct src *src, unsigned int sf) static int src_set_pm(struct src *src, unsigned int pm) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_pm(src->rsc.ctrl_blk, pm); return 0; @@ -77,9 +77,9 @@ static int src_set_pm(struct src *src, unsigned int pm) static int src_set_rom(struct src *src, unsigned int rom) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_rom(src->rsc.ctrl_blk, rom); return 0; @@ -87,9 +87,9 @@ static int src_set_rom(struct src *src, unsigned int rom) static int src_set_vo(struct src *src, unsigned int vo) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_vo(src->rsc.ctrl_blk, vo); return 0; @@ -97,9 +97,9 @@ static int src_set_vo(struct src *src, unsigned int vo) static int src_set_st(struct src *src, unsigned int st) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_st(src->rsc.ctrl_blk, st); return 0; @@ -107,9 +107,9 @@ static int src_set_st(struct src *src, unsigned int st) static int src_set_bp(struct src *src, unsigned int bp) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_bp(src->rsc.ctrl_blk, bp); return 0; @@ -117,9 +117,9 @@ static int src_set_bp(struct src *src, unsigned int bp) static int src_set_cisz(struct src *src, unsigned int cisz) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_cisz(src->rsc.ctrl_blk, cisz); return 0; @@ -127,9 +127,9 @@ static int src_set_cisz(struct src *src, unsigned int cisz) static int src_set_ca(struct src *src, unsigned int ca) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_ca(src->rsc.ctrl_blk, ca); return 0; @@ -137,9 +137,9 @@ static int src_set_ca(struct src *src, unsigned int ca) static int src_set_sa(struct src *src, unsigned int sa) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_sa(src->rsc.ctrl_blk, sa); return 0; @@ -147,9 +147,9 @@ static int src_set_sa(struct src *src, unsigned int sa) static int src_set_la(struct src *src, unsigned int la) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_la(src->rsc.ctrl_blk, la); return 0; @@ -157,9 +157,9 @@ static int src_set_la(struct src *src, unsigned int la) static int src_set_pitch(struct src *src, unsigned int pitch) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_pitch(src->rsc.ctrl_blk, pitch); return 0; @@ -167,9 +167,9 @@ static int src_set_pitch(struct src *src, unsigned int pitch) static int src_set_clear_zbufs(struct src *src) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); return 0; @@ -177,11 +177,11 @@ static int src_set_clear_zbufs(struct src *src) static int src_commit_write(struct src *src) { - struct hw *hw = NULL; - int i = 0; + struct hw *hw; + int i; unsigned int dirty = 0; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; src->rsc.ops->master(&src->rsc); if (src->rsc.msr > 1) { /* Save dirty flags for conjugate resource programming */ @@ -207,9 +207,9 @@ static int src_commit_write(struct src *src) static int src_get_ca(struct src *src) { - struct hw *hw = NULL; + struct hw *hw; - hw = (struct hw *)src->rsc.hw; + hw = src->rsc.hw; return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc), src->rsc.ctrl_blk); } @@ -229,7 +229,7 @@ static struct src *src_next_interleave(struct src *src) static int src_default_config_memrd(struct src *src) { struct hw *hw = src->rsc.hw; - unsigned int rsr = 0, msr = 0; + unsigned int rsr, msr; hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); hw->src_set_bm(src->rsc.ctrl_blk, 1); @@ -297,7 +297,7 @@ static int src_default_config_memwr(struct src *src) static int src_default_config_arcrw(struct src *src) { struct hw *hw = src->rsc.hw; - unsigned int rsr = 0, msr = 0; + unsigned int rsr, msr; unsigned int dirty; hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); @@ -360,8 +360,8 @@ static int src_rsc_init(struct src *src, u32 idx, const struct src_desc *desc, struct src_mgr *mgr) { - int err = 0; - int i = 0, n = 0; + int err; + int i, n; struct src *p; n = (MEMRD == desc->mode) ? desc->multi : 1; @@ -395,7 +395,7 @@ error1: static int src_rsc_uninit(struct src *src, struct src_mgr *mgr) { - int i = 0, n = 0; + int i, n; struct src *p; n = (MEMRD == src->mode) ? src->multi : 1; @@ -416,8 +416,8 @@ static int get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc) { unsigned int idx = SRC_RESOURCE_NUM; - int err = 0; - struct src *src = NULL; + int err; + struct src *src; unsigned long flags; *rsrc = NULL; @@ -489,7 +489,7 @@ static int put_src_rsc(struct src_mgr *mgr, struct src *src) static int src_enable_s(struct src_mgr *mgr, struct src *src) { struct hw *hw = mgr->mgr.hw; - int i = 0; + int i; src->rsc.ops->master(&src->rsc); for (i = 0; i < src->rsc.msr; i++) { @@ -505,7 +505,7 @@ static int src_enable_s(struct src_mgr *mgr, struct src *src) static int src_enable(struct src_mgr *mgr, struct src *src) { struct hw *hw = mgr->mgr.hw; - int i = 0; + int i; src->rsc.ops->master(&src->rsc); for (i = 0; i < src->rsc.msr; i++) { @@ -521,7 +521,7 @@ static int src_enable(struct src_mgr *mgr, struct src *src) static int src_disable(struct src_mgr *mgr, struct src *src) { struct hw *hw = mgr->mgr.hw; - int i = 0; + int i; src->rsc.ops->master(&src->rsc); for (i = 0; i < src->rsc.msr; i++) { @@ -545,7 +545,7 @@ static int src_mgr_commit_write(struct src_mgr *mgr) int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr) { - int err = 0, i = 0; + int err, i; struct src_mgr *src_mgr; *rsrc_mgr = NULL; @@ -618,8 +618,8 @@ static struct rsc_ops srcimp_basic_rsc_ops = { static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input) { - struct imapper *entry = NULL; - int i = 0; + struct imapper *entry; + int i; srcimp->rsc.ops->master(&srcimp->rsc); src->rsc.ops->master(&src->rsc); @@ -646,7 +646,7 @@ static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input) static int srcimp_unmap(struct srcimp *srcimp) { - int i = 0; + int i; /* Program master and conjugate resources */ for (i = 0; i < srcimp->rsc.msr; i++) { @@ -669,7 +669,7 @@ static int srcimp_rsc_init(struct srcimp *srcimp, const struct srcimp_desc *desc, struct srcimp_mgr *mgr) { - int err = 0; + int err; err = rsc_init(&srcimp->rsc, srcimp->idx[0], SRCIMP, desc->msr, mgr->mgr.hw); @@ -715,9 +715,9 @@ static int get_srcimp_rsc(struct srcimp_mgr *mgr, const struct srcimp_desc *desc, struct srcimp **rsrcimp) { - int err = 0, i = 0; - unsigned int idx = 0; - struct srcimp *srcimp = NULL; + int err, i; + unsigned int idx; + struct srcimp *srcimp; unsigned long flags; *rsrcimp = NULL; @@ -765,7 +765,7 @@ error1: static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp) { unsigned long flags; - int i = 0; + int i; spin_lock_irqsave(&mgr->mgr_lock, flags); for (i = 0; i < srcimp->rsc.msr; i++) @@ -795,7 +795,7 @@ static int srcimp_map_op(void *data, struct imapper *entry) static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry) { unsigned long flags; - int err = 0; + int err; spin_lock_irqsave(&mgr->imap_lock, flags); if ((0 == entry->addr) && (mgr->init_imap_added)) { @@ -812,7 +812,7 @@ static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry) static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry) { unsigned long flags; - int err = 0; + int err; spin_lock_irqsave(&mgr->imap_lock, flags); err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr); @@ -828,7 +828,7 @@ static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry) int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr) { - int err = 0; + int err; struct srcimp_mgr *srcimp_mgr; struct imapper *entry; diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index b7f8e58ae07d..67665a7e43c6 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c @@ -31,8 +31,8 @@ static struct ct_vm_block * get_vm_block(struct ct_vm *vm, unsigned int size) { - struct ct_vm_block *block = NULL, *entry = NULL; - struct list_head *pos = NULL; + struct ct_vm_block *block = NULL, *entry; + struct list_head *pos; size = CT_PAGE_ALIGN(size); if (size > vm->size) { @@ -77,8 +77,8 @@ get_vm_block(struct ct_vm *vm, unsigned int size) static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block) { - struct ct_vm_block *entry = NULL, *pre_ent = NULL; - struct list_head *pos = NULL, *pre = NULL; + struct ct_vm_block *entry, *pre_ent; + struct list_head *pos, *pre; block->size = CT_PAGE_ALIGN(block->size); @@ -223,8 +223,8 @@ int ct_vm_create(struct ct_vm **rvm) void ct_vm_destroy(struct ct_vm *vm) { int i; - struct list_head *pos = NULL; - struct ct_vm_block *entry = NULL; + struct list_head *pos; + struct ct_vm_block *entry; /* free used and unused list nodes */ while (!list_empty(&vm->used)) { -- cgit v1.2.3 From 9470195a9cd13e6d90221b8b5d897e9232da8d28 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 8 Jun 2009 18:10:32 +0200 Subject: ALSA: ctxfi - Clean up probe routines Clean up probe routines and model detection routines so that the driver won't call and check the PCI subsystem id at each time. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctatc.c | 132 +++++++++++++++++++------------------------ sound/pci/ctxfi/ctatc.h | 17 ++---- sound/pci/ctxfi/ctdaio.c | 6 +- sound/pci/ctxfi/cthardware.c | 31 +++------- sound/pci/ctxfi/cthardware.h | 20 ++++++- sound/pci/ctxfi/cthw20k1.c | 88 +++++++++++------------------ sound/pci/ctxfi/xfi.c | 15 +++-- 7 files changed, 135 insertions(+), 174 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 7898a375df0e..002a70e0b13a 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -39,29 +39,40 @@ | (0x10 << 16) \ | ((IEC958_AES3_CON_FS_48000) << 24)) -static const struct ct_atc_chip_sub_details atc_sub_details[NUM_CTCARDS] = { - [CTSB0760] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB0760, - .nm_model = "SB076x"}, - [CTHENDRIX] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, - .nm_model = "Hendrix"}, - [CTSB08801] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB08801, - .nm_model = "SB0880"}, - [CTSB08802] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB08802, - .nm_model = "SB0880"}, - [CTSB08803] = {.subsys = PCI_SUBDEVICE_ID_CREATIVE_SB08803, - .nm_model = "SB0880"} +static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = { + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X), + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X), + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X), + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0x6000, + PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "UAA", CTUAA), + SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE, + "Unknown", CT20K1_UNKNOWN), + { } /* terminator */ }; -static struct ct_atc_chip_details atc_chip_details[] = { - {.vendor = PCI_VENDOR_ID_CREATIVE, - .device = PCI_DEVICE_ID_CREATIVE_20K1, - .sub_details = NULL, - .nm_card = "X-Fi 20k1"}, - {.vendor = PCI_VENDOR_ID_CREATIVE, - .device = PCI_DEVICE_ID_CREATIVE_20K2, - .sub_details = atc_sub_details, - .nm_card = "X-Fi 20k2"}, - {} /* terminator */ +static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760, + "SB0760", CTSB0760), + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801, + "SB0880", CTSB0880), + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802, + "SB0880", CTSB0880), + SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08803, + "SB0880", CTSB0880), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0x6000, + PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "UAA", CTHENDRIX), + { } /* terminator */ +}; + +static const char *ct_subsys_name[NUM_CTCARDS] = { + [CTSB055X] = "SB055x", + [CTSB073X] = "SB073x", + [CTSB0760] = "SB076x", + [CTUAA] = "UAA", + [CT20K1_UNKNOWN] = "Unknown", + [CTHENDRIX] = "Hendrix", + [CTSB0880] = "SB0880", }; static struct { @@ -1208,62 +1219,39 @@ static int atc_dev_free(struct snd_device *dev) static int __devinit atc_identify_card(struct ct_atc *atc) { - u16 subsys; - u8 revision; - struct pci_dev *pci = atc->pci; - const struct ct_atc_chip_details *d; - enum CTCARDS i; - - subsys = pci->subsystem_device; - revision = pci->revision; - atc->chip_details = NULL; - atc->model = NUM_CTCARDS; - for (d = atc_chip_details; d->vendor; d++) { - if (d->vendor != pci->vendor || d->device != pci->device) - continue; + const struct snd_pci_quirk *p; + const struct snd_pci_quirk *list; - if (NULL == d->sub_details) { - atc->chip_details = d; - break; - } - for (i = 0; i < NUM_CTCARDS; i++) { - if ((d->sub_details[i].subsys == subsys) || - (((subsys & 0x6000) == 0x6000) && - ((d->sub_details[i].subsys & 0x6000) == 0x6000))) { - atc->model = i; - break; - } - } - if (i >= NUM_CTCARDS) - continue; - - atc->chip_details = d; + switch (atc->chip_type) { + case ATC20K1: + atc->chip_name = "20K1"; + list = subsys_20k1_list; + break; + case ATC20K2: + atc->chip_name = "20K2"; + list = subsys_20k2_list; break; - /* not take revision into consideration now */ + default: + return -ENOENT; } - if (!d->vendor) + p = snd_pci_quirk_lookup(atc->pci, list); + if (!p) return -ENOENT; - + atc->model = p->value; + atc->model_name = ct_subsys_name[atc->model]; + snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", + atc->chip_name, atc->model_name, + atc->pci->subsystem_vendor, + atc->pci->subsystem_device); return 0; } int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc) { enum CTALSADEVS i; - struct hw *hw = atc->hw; int err; - switch (hw->get_chip_type(hw)) { - case ATC20K1: - alsa_dev_funcs[MIXER].public_name = "20K1"; - break; - case ATC20K2: - alsa_dev_funcs[MIXER].public_name = "20K2"; - break; - default: - alsa_dev_funcs[MIXER].public_name = "Unknown"; - break; - } + alsa_dev_funcs[MIXER].public_name = atc->chip_name; for (i = 0; i < NUM_CTALSADEVS; i++) { if (NULL == alsa_dev_funcs[i].create) @@ -1287,7 +1275,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc) struct card_conf info = {0}; int i, err; - err = create_hw_obj(atc->pci, &hw); + err = create_hw_obj(atc->pci, atc->chip_type, atc->model, &hw); if (err) { printk(KERN_ERR "Failed to create hw obj!!!\n"); return err; @@ -1328,7 +1316,6 @@ static int __devinit atc_get_resources(struct ct_atc *atc) struct sum_desc sum_dsc = {0}; struct sum_mgr *sum_mgr; int err, i; - unsigned short subsys_id; atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL); if (NULL == atc->daios) @@ -1359,13 +1346,10 @@ static int __devinit atc_get_resources(struct ct_atc *atc) } atc->n_daio++; } - subsys_id = atc->pci->subsystem_device; - if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) { - /* SB073x cards */ + if (atc->model == CTSB073X) da_desc.type = SPDIFI1; - } else { + else da_desc.type = SPDIFIO; - } err = daio_mgr->get_daio(daio_mgr, &da_desc, (struct daio **)&atc->daios[i]); if (err) { @@ -1555,7 +1539,8 @@ static struct ct_atc atc_preset __devinitdata = { */ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, - unsigned int rsr, unsigned int msr, struct ct_atc **ratc) + unsigned int rsr, unsigned int msr, + int chip_type, struct ct_atc **ratc) { struct ct_atc *atc; static struct snd_device_ops ops = { @@ -1576,6 +1561,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, atc->pci = pci; atc->rsr = rsr; atc->msr = msr; + atc->chip_type = chip_type; spin_lock_init(&atc->atc_lock); diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index 04459aa0d4d9..a03347232e84 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -37,15 +37,6 @@ enum CTALSADEVS { /* Types of alsa devices */ NUM_CTALSADEVS /* This should always be the last */ }; -enum CTCARDS { - CTSB0760, - CTHENDRIX, - CTSB08801, - CTSB08802, - CTSB08803, - NUM_CTCARDS /* This should always be the last */ -}; - struct ct_atc_chip_sub_details { u16 subsys; const char *nm_model; @@ -89,8 +80,10 @@ struct ct_atc { unsigned int msr; /* master sample rate in rsr */ unsigned int pll_rate; /* current rate of Phase Lock Loop */ - const struct ct_atc_chip_details *chip_details; - enum CTCARDS model; + int chip_type; + int model; + const char *chip_name; + const char *model_name; struct ct_vm *vm; /* device virtual memory manager for this card */ int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); @@ -147,7 +140,7 @@ struct ct_atc { int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, - unsigned int rsr, unsigned int msr, + unsigned int rsr, unsigned int msr, int chip_type, struct ct_atc **ratc); int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc); diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index befead4eeaab..082e35c08c02 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -116,7 +116,7 @@ static struct rsc_ops daio_in_rsc_ops_20k2 = { static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw) { - switch (hw->get_chip_type(hw)) { + switch (hw->chip_type) { case ATC20K1: switch (type) { case SPDIFOO: return 0; @@ -343,7 +343,7 @@ static int daio_rsc_init(struct daio *daio, int err; unsigned int idx_l, idx_r; - switch (((struct hw *)hw)->get_chip_type(hw)) { + switch (((struct hw *)hw)->chip_type) { case ATC20K1: idx_l = idx_20k1[desc->type].left; idx_r = idx_20k1[desc->type].right; @@ -367,7 +367,7 @@ static int daio_rsc_init(struct daio *daio, if (desc->type <= DAIO_OUT_MAX) { daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops; } else { - switch (((struct hw *)hw)->get_chip_type(hw)) { + switch (((struct hw *)hw)->chip_type) { case ATC20K1: daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1; break; diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c index 5ec6813d3911..8e64f4862e85 100644 --- a/sound/pci/ctxfi/cthardware.c +++ b/sound/pci/ctxfi/cthardware.c @@ -20,34 +20,16 @@ #include "cthw20k2.h" #include -static enum CHIPTYP __devinitdata get_chip_type(struct hw *hw) -{ - enum CHIPTYP type; - - switch (hw->pci->device) { - case 0x0005: /* 20k1 device */ - type = ATC20K1; - break; - case 0x000B: /* 20k2 device */ - type = ATC20K2; - break; - default: - type = ATCNONE; - break; - } - - return type; -} - -int __devinit create_hw_obj(struct pci_dev *pci, struct hw **rhw) +int __devinit create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type, + enum CTCARDS model, struct hw **rhw) { int err; - switch (pci->device) { - case 0x0005: /* 20k1 device */ + switch (chip_type) { + case ATC20K1: err = create_20k1_hw_obj(rhw); break; - case 0x000B: /* 20k2 device */ + case ATC20K2: err = create_20k2_hw_obj(rhw); break; default: @@ -58,7 +40,8 @@ int __devinit create_hw_obj(struct pci_dev *pci, struct hw **rhw) return err; (*rhw)->pci = pci; - (*rhw)->get_chip_type = get_chip_type; + (*rhw)->chip_type = chip_type; + (*rhw)->model = model; return 0; } diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h index 8f11644ddc92..4a8e04f090a4 100644 --- a/sound/pci/ctxfi/cthardware.h +++ b/sound/pci/ctxfi/cthardware.h @@ -27,6 +27,19 @@ enum CHIPTYP { ATCNONE }; +enum CTCARDS { + /* 20k1 models */ + CTSB055X, + CTSB073X, + CTUAA, + CT20K1_UNKNOWN, + /* 20k2 models */ + CTSB0760, + CTHENDRIX, + CTSB0880, + NUM_CTCARDS /* This should always be the last */ +}; + /* Type of input source for ADC */ enum ADCSRC{ ADC_MICIN, @@ -48,7 +61,6 @@ struct hw { int (*card_init)(struct hw *hw, struct card_conf *info); int (*card_stop)(struct hw *hw); int (*pll_init)(struct hw *hw, unsigned int rsr); - enum CHIPTYP (*get_chip_type)(struct hw *hw); int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); int (*select_adc_source)(struct hw *hw, enum ADCSRC source); int (*have_digit_io_switch)(struct hw *hw); @@ -156,9 +168,13 @@ struct hw { int irq; unsigned long io_base; unsigned long mem_base; + + enum CHIPTYP chip_type; + enum CTCARDS model; }; -int create_hw_obj(struct pci_dev *pci, struct hw **rhw); +int create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type, + enum CTCARDS model, struct hw **rhw); int destroy_hw_obj(struct hw *hw); unsigned int get_field(unsigned int data, unsigned int field); diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 38b87b6ee6d4..5d58650beb73 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1432,11 +1432,9 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info) { u32 data; u16 gpioorg; - u16 subsys_id; unsigned int ret; - pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); - if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { + if (hw->model == CTSB055X) { /* SB055x, unmute outputs */ gpioorg = (u16)hw_read_20kx(hw, GPIO); gpioorg &= 0xffbf; /* set GPIO6 to low */ @@ -1538,19 +1536,14 @@ static int is_adc_input_selected_hendrix(struct hw *hw, enum ADCSRC type) static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) { - u16 subsys_id; - - pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); - if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { - /* SB055x cards */ + switch (hw->model) { + case CTSB055X: return is_adc_input_selected_SB055x(hw, type); - } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) { - /* SB073x cards */ + case CTSB073X: return is_adc_input_selected_hendrix(hw, type); - } else if ((subsys_id & 0xf000) == 0x6000) { - /* Vista compatible cards */ + case CTHENDRIX: return is_adc_input_selected_hendrix(hw, type); - } else { + default: return is_adc_input_selected_SBx(hw, type); } } @@ -1692,20 +1685,17 @@ adc_input_select_hendrix(struct hw *hw, enum ADCSRC type, unsigned char boost) static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) { - u16 subsys_id; - - pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); - if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { - /* SB055x cards */ - return adc_input_select_SB055x(hw, type, (ADC_MICIN == type)); - } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) { - /* SB073x cards */ - return adc_input_select_hendrix(hw, type, (ADC_MICIN == type)); - } else if ((subsys_id & 0xf000) == 0x6000) { - /* Vista compatible cards */ - return adc_input_select_hendrix(hw, type, (ADC_MICIN == type)); - } else { - return adc_input_select_SBx(hw, type, (ADC_MICIN == type)); + int state = type == ADC_MICIN; + + switch (hw->model) { + case CTSB055X: + return adc_input_select_SB055x(hw, type, state); + case CTSB073X: + return adc_input_select_hendrix(hw, type, state); + case CTHENDRIX: + return adc_input_select_hendrix(hw, type, state); + default: + return adc_input_select_SBx(hw, type, state); } } @@ -1781,28 +1771,16 @@ static int adc_init_SBx(struct hw *hw, int input, int mic20db) static int hw_adc_init(struct hw *hw, const struct adc_conf *info) { - int err; - u16 subsys_id; - - pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); - if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { - /* Sb055x card */ - err = adc_init_SB055x(hw, info->input, info->mic20db); - } else { - err = adc_init_SBx(hw, info->input, info->mic20db); - } - - return err; + if (hw->model == CTSB055X) + return adc_init_SB055x(hw, info->input, info->mic20db); + else + return adc_init_SBx(hw, info->input, info->mic20db); } static int hw_have_digit_io_switch(struct hw *hw) { - u16 subsys_id; - - pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); /* SB073x and Vista compatible cards have no digit IO switch */ - return !((subsys_id == 0x0029) || (subsys_id == 0x0031) - || ((subsys_id & 0xf000) == 0x6000)); + return !(hw->model == CTSB073X || hw->model == CTHENDRIX); } #define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) @@ -1918,7 +1896,6 @@ static int hw_card_start(struct hw *hw) { int err; struct pci_dev *pci = hw->pci; - u16 subsys_id; err = pci_enable_device(pci); if (err < 0) @@ -1939,8 +1916,7 @@ static int hw_card_start(struct hw *hw) goto error1; /* Switch to X-Fi mode from UAA mode if neeeded */ - pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsys_id); - if ((0x5 == pci->device) && (0x6000 == (subsys_id & 0x6000))) { + if (hw->model == CTHENDRIX) { err = uaa_to_xfi(pci); if (err) goto error2; @@ -2004,7 +1980,6 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) { int err; unsigned int gctl; - u16 subsys_id; u32 data; struct dac_conf dac_info = {0}; struct adc_conf adc_info = {0}; @@ -2044,19 +2019,20 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) hw_write_20kx(hw, SRCIP, 0); mdelay(30); - pci_read_config_word(hw->pci, PCI_SUBSYSTEM_ID, &subsys_id); /* Detect the card ID and configure GPIO accordingly. */ - if ((subsys_id == 0x0022) || (subsys_id == 0x002F)) { - /* SB055x cards */ + switch (hw->model) { + case CTSB055X: hw_write_20kx(hw, GPIOCTL, 0x13fe); - } else if ((subsys_id == 0x0029) || (subsys_id == 0x0031)) { - /* SB073x cards */ + break; + case CTSB073X: hw_write_20kx(hw, GPIOCTL, 0x00e6); - } else if ((subsys_id & 0xf000) == 0x6000) { - /* Vista compatible cards */ + break; + case CTHENDRIX: /* Vista compatible cards */ hw_write_20kx(hw, GPIOCTL, 0x00c2); - } else { + break; + default: hw_write_20kx(hw, GPIOCTL, 0x01e6); + break; } trn_info.vm_pgt_phys = info->vm_pgt_phys; diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c index 279dac6c34dd..2d3dd89af151 100644 --- a/sound/pci/ctxfi/xfi.c +++ b/sound/pci/ctxfi/xfi.c @@ -15,6 +15,7 @@ #include #include #include "ctatc.h" +#include "cthardware.h" MODULE_AUTHOR("Creative Technology Ltd"); MODULE_DESCRIPTION("X-Fi driver version 1.03"); @@ -41,8 +42,12 @@ MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver"); static struct pci_device_id ct_pci_dev_ids[] = { /* only X-Fi is supported, so... */ - { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1) }, - { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2) }, + { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1), + .driver_data = ATC20K1, + }, + { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2), + .driver_data = ATC20K2, + }, { 0, } }; MODULE_DEVICE_TABLE(pci, ct_pci_dev_ids); @@ -79,7 +84,8 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) "1 and 2, Value 2 is assumed.\n"); multiple = 2; } - err = ct_atc_create(card, pci, reference_rate, multiple, &atc); + err = ct_atc_create(card, pci, reference_rate, multiple, + pci_id->driver_data, &atc); if (err < 0) goto error; @@ -92,7 +98,8 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) strcpy(card->driver, "SB-XFi"); strcpy(card->shortname, "Creative X-Fi"); - strcpy(card->longname, "Creative ALSA Driver X-Fi"); + snprintf(card->longname, sizeof(card->longname), "%s %s %s", + card->shortname, atc->chip_name, atc->model_name); err = snd_card_register(card); if (err < 0) -- cgit v1.2.3 From 09521d2e3edd0bf02b66e5b8c13f1559f2d6958a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 8 Jun 2009 18:29:38 +0200 Subject: ALSA: ctxfi - Fix wrong model id for UAA CTUAA should be checked instead of CTHENDRIX. The latter is for 20k2 chip. Also, fixed the detection of UAA/HENDRIX models by fixing the mask bits. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctatc.c | 9 +++++---- sound/pci/ctxfi/cthw20k1.c | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'sound/pci/ctxfi/cthw20k1.c') diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 002a70e0b13a..4e25b24848bd 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -44,8 +44,8 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X), SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X), SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X), - SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0x6000, - PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "UAA", CTUAA), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000, + "UAA", CTUAA), SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE, "Unknown", CT20K1_UNKNOWN), { } /* terminator */ @@ -60,8 +60,9 @@ static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { "SB0880", CTSB0880), SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08803, "SB0880", CTSB0880), - SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0x6000, - PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "UAA", CTHENDRIX), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, + PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "HENDRIX", + CTHENDRIX), { } /* terminator */ }; diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 5d58650beb73..cb69d9ddfbe3 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1541,7 +1541,7 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) return is_adc_input_selected_SB055x(hw, type); case CTSB073X: return is_adc_input_selected_hendrix(hw, type); - case CTHENDRIX: + case CTUAA: return is_adc_input_selected_hendrix(hw, type); default: return is_adc_input_selected_SBx(hw, type); @@ -1692,7 +1692,7 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) return adc_input_select_SB055x(hw, type, state); case CTSB073X: return adc_input_select_hendrix(hw, type, state); - case CTHENDRIX: + case CTUAA: return adc_input_select_hendrix(hw, type, state); default: return adc_input_select_SBx(hw, type, state); @@ -1780,7 +1780,7 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info) static int hw_have_digit_io_switch(struct hw *hw) { /* SB073x and Vista compatible cards have no digit IO switch */ - return !(hw->model == CTSB073X || hw->model == CTHENDRIX); + return !(hw->model == CTSB073X || hw->model == CTUAA); } #define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) @@ -1916,7 +1916,7 @@ static int hw_card_start(struct hw *hw) goto error1; /* Switch to X-Fi mode from UAA mode if neeeded */ - if (hw->model == CTHENDRIX) { + if (hw->model == CTUAA) { err = uaa_to_xfi(pci); if (err) goto error2; @@ -2027,7 +2027,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) case CTSB073X: hw_write_20kx(hw, GPIOCTL, 0x00e6); break; - case CTHENDRIX: /* Vista compatible cards */ + case CTUAA: hw_write_20kx(hw, GPIOCTL, 0x00c2); break; default: -- cgit v1.2.3