diff options
Diffstat (limited to 'ANDROID_3.4.5/sound/pci/ctxfi')
30 files changed, 0 insertions, 13401 deletions
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/Makefile b/ANDROID_3.4.5/sound/pci/ctxfi/Makefile deleted file mode 100644 index 15075f89..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -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 cttimer.o \ - cthw20k2.o cthw20k1.o - -obj-$(CONFIG_SND_CTXFI) += snd-ctxfi.o diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k1reg.h b/ANDROID_3.4.5/sound/pci/ctxfi/ct20k1reg.h deleted file mode 100644 index f2e34e3f..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k1reg.h +++ /dev/null @@ -1,636 +0,0 @@ -/** - * 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. - */ - -#ifndef CT20K1REG_H -#define CT20k1REG_H - -/* 20k1 registers */ -#define DSPXRAM_START 0x000000 -#define DSPXRAM_END 0x013FFC -#define DSPAXRAM_START 0x020000 -#define DSPAXRAM_END 0x023FFC -#define DSPYRAM_START 0x040000 -#define DSPYRAM_END 0x04FFFC -#define DSPAYRAM_START 0x020000 -#define DSPAYRAM_END 0x063FFC -#define DSPMICRO_START 0x080000 -#define DSPMICRO_END 0x0B3FFC -#define DSP0IO_START 0x100000 -#define DSP0IO_END 0x101FFC -#define AUDIORINGIPDSP0_START 0x100000 -#define AUDIORINGIPDSP0_END 0x1003FC -#define AUDIORINGOPDSP0_START 0x100400 -#define AUDIORINGOPDSP0_END 0x1007FC -#define AUDPARARINGIODSP0_START 0x100800 -#define AUDPARARINGIODSP0_END 0x100BFC -#define DSP0LOCALHWREG_START 0x100C00 -#define DSP0LOCALHWREG_END 0x100C3C -#define DSP0XYRAMAGINDEX_START 0x100C40 -#define DSP0XYRAMAGINDEX_END 0x100C5C -#define DSP0XYRAMAGMDFR_START 0x100C60 -#define DSP0XYRAMAGMDFR_END 0x100C7C -#define DSP0INTCONTLVEC_START 0x100C80 -#define DSP0INTCONTLVEC_END 0x100CD8 -#define INTCONTLGLOBALREG_START 0x100D1C -#define INTCONTLGLOBALREG_END 0x100D3C -#define HOSTINTFPORTADDRCONTDSP0 0x100D40 -#define HOSTINTFPORTDATADSP0 0x100D44 -#define TIME0PERENBDSP0 0x100D60 -#define TIME0COUNTERDSP0 0x100D64 -#define TIME1PERENBDSP0 0x100D68 -#define TIME1COUNTERDSP0 0x100D6C -#define TIME2PERENBDSP0 0x100D70 -#define TIME2COUNTERDSP0 0x100D74 -#define TIME3PERENBDSP0 0x100D78 -#define TIME3COUNTERDSP0 0x100D7C -#define XRAMINDOPERREFNOUP_STARTDSP0 0x100D80 -#define XRAMINDOPERREFNOUP_ENDDSP0 0x100D9C -#define XRAMINDOPERREFUP_STARTDSP0 0x100DA0 -#define XRAMINDOPERREFUP_ENDDSP0 0x100DBC -#define YRAMINDOPERREFNOUP_STARTDSP0 0x100DC0 -#define YRAMINDOPERREFNOUP_ENDDSP0 0x100DDC -#define YRAMINDOPERREFUP_STARTDSP0 0x100DE0 -#define YRAMINDOPERREFUP_ENDDSP0 0x100DFC -#define DSP0CONDCODE 0x100E00 -#define DSP0STACKFLAG 0x100E04 -#define DSP0PROGCOUNTSTACKPTREG 0x100E08 -#define DSP0PROGCOUNTSTACKDATAREG 0x100E0C -#define DSP0CURLOOPADDRREG 0x100E10 -#define DSP0CURLOOPCOUNT 0x100E14 -#define DSP0TOPLOOPCOUNTSTACK 0x100E18 -#define DSP0TOPLOOPADDRSTACK 0x100E1C -#define DSP0LOOPSTACKPTR 0x100E20 -#define DSP0STASSTACKDATAREG 0x100E24 -#define DSP0STASSTACKPTR 0x100E28 -#define DSP0PROGCOUNT 0x100E2C -#define GLOBDSPDEBGREG 0x100E30 -#define GLOBDSPBREPTRREG 0x100E30 -#define DSP0XYRAMBASE_START 0x100EA0 -#define DSP0XYRAMBASE_END 0x100EBC -#define DSP0XYRAMLENG_START 0x100EC0 -#define DSP0XYRAMLENG_END 0x100EDC -#define SEMAPHOREREGDSP0 0x100EE0 -#define DSP0INTCONTMASKREG 0x100EE4 -#define DSP0INTCONTPENDREG 0x100EE8 -#define DSP0INTCONTSERVINT 0x100EEC -#define DSPINTCONTEXTINTMODREG 0x100EEC -#define GPIODSP0 0x100EFC -#define DMADSPBASEADDRREG_STARTDSP0 0x100F00 -#define DMADSPBASEADDRREG_ENDDSP0 0x100F1C -#define DMAHOSTBASEADDRREG_STARTDSP0 0x100F20 -#define DMAHOSTBASEADDRREG_ENDDSP0 0x100F3C -#define DMADSPCURADDRREG_STARTDSP0 0x100F40 -#define DMADSPCURADDRREG_ENDDSP0 0x100F5C -#define DMAHOSTCURADDRREG_STARTDSP0 0x100F60 -#define DMAHOSTCURADDRREG_ENDDSP0 0x100F7C -#define DMATANXCOUNTREG_STARTDSP0 0x100F80 -#define DMATANXCOUNTREG_ENDDSP0 0x100F9C -#define DMATIMEBUGREG_STARTDSP0 0x100FA0 -#define DMATIMEBUGREG_ENDDSP0 0x100FAC -#define DMACNTLMODFREG_STARTDSP0 0x100FA0 -#define DMACNTLMODFREG_ENDDSP0 0x100FAC - -#define DMAGLOBSTATSREGDSP0 0x100FEC -#define DSP0XGPRAM_START 0x101000 -#define DSP0XGPRAM_END 0x1017FC -#define DSP0YGPRAM_START 0x101800 -#define DSP0YGPRAM_END 0x101FFC - - - - -#define AUDIORINGIPDSP1_START 0x102000 -#define AUDIORINGIPDSP1_END 0x1023FC -#define AUDIORINGOPDSP1_START 0x102400 -#define AUDIORINGOPDSP1_END 0x1027FC -#define AUDPARARINGIODSP1_START 0x102800 -#define AUDPARARINGIODSP1_END 0x102BFC -#define DSP1LOCALHWREG_START 0x102C00 -#define DSP1LOCALHWREG_END 0x102C3C -#define DSP1XYRAMAGINDEX_START 0x102C40 -#define DSP1XYRAMAGINDEX_END 0x102C5C -#define DSP1XYRAMAGMDFR_START 0x102C60 -#define DSP1XYRAMAGMDFR_END 0x102C7C -#define DSP1INTCONTLVEC_START 0x102C80 -#define DSP1INTCONTLVEC_END 0x102CD8 -#define HOSTINTFPORTADDRCONTDSP1 0x102D40 -#define HOSTINTFPORTDATADSP1 0x102D44 -#define TIME0PERENBDSP1 0x102D60 -#define TIME0COUNTERDSP1 0x102D64 -#define TIME1PERENBDSP1 0x102D68 -#define TIME1COUNTERDSP1 0x102D6C -#define TIME2PERENBDSP1 0x102D70 -#define TIME2COUNTERDSP1 0x102D74 -#define TIME3PERENBDSP1 0x102D78 -#define TIME3COUNTERDSP1 0x102D7C -#define XRAMINDOPERREFNOUP_STARTDSP1 0x102D80 -#define XRAMINDOPERREFNOUP_ENDDSP1 0x102D9C -#define XRAMINDOPERREFUP_STARTDSP1 0x102DA0 -#define XRAMINDOPERREFUP_ENDDSP1 0x102DBC -#define YRAMINDOPERREFNOUP_STARTDSP1 0x102DC0 -#define YRAMINDOPERREFNOUP_ENDDSP1 0x102DDC -#define YRAMINDOPERREFUP_STARTDSP1 0x102DE0 -#define YRAMINDOPERREFUP_ENDDSP1 0x102DFC - -#define DSP1CONDCODE 0x102E00 -#define DSP1STACKFLAG 0x102E04 -#define DSP1PROGCOUNTSTACKPTREG 0x102E08 -#define DSP1PROGCOUNTSTACKDATAREG 0x102E0C -#define DSP1CURLOOPADDRREG 0x102E10 -#define DSP1CURLOOPCOUNT 0x102E14 -#define DSP1TOPLOOPCOUNTSTACK 0x102E18 -#define DSP1TOPLOOPADDRSTACK 0x102E1C -#define DSP1LOOPSTACKPTR 0x102E20 -#define DSP1STASSTACKDATAREG 0x102E24 -#define DSP1STASSTACKPTR 0x102E28 -#define DSP1PROGCOUNT 0x102E2C -#define DSP1XYRAMBASE_START 0x102EA0 -#define DSP1XYRAMBASE_END 0x102EBC -#define DSP1XYRAMLENG_START 0x102EC0 -#define DSP1XYRAMLENG_END 0x102EDC -#define SEMAPHOREREGDSP1 0x102EE0 -#define DSP1INTCONTMASKREG 0x102EE4 -#define DSP1INTCONTPENDREG 0x102EE8 -#define DSP1INTCONTSERVINT 0x102EEC -#define GPIODSP1 0x102EFC -#define DMADSPBASEADDRREG_STARTDSP1 0x102F00 -#define DMADSPBASEADDRREG_ENDDSP1 0x102F1C -#define DMAHOSTBASEADDRREG_STARTDSP1 0x102F20 -#define DMAHOSTBASEADDRREG_ENDDSP1 0x102F3C -#define DMADSPCURADDRREG_STARTDSP1 0x102F40 -#define DMADSPCURADDRREG_ENDDSP1 0x102F5C -#define DMAHOSTCURADDRREG_STARTDSP1 0x102F60 -#define DMAHOSTCURADDRREG_ENDDSP1 0x102F7C -#define DMATANXCOUNTREG_STARTDSP1 0x102F80 -#define DMATANXCOUNTREG_ENDDSP1 0x102F9C -#define DMATIMEBUGREG_STARTDSP1 0x102FA0 -#define DMATIMEBUGREG_ENDDSP1 0x102FAC -#define DMACNTLMODFREG_STARTDSP1 0x102FA0 -#define DMACNTLMODFREG_ENDDSP1 0x102FAC - -#define DMAGLOBSTATSREGDSP1 0x102FEC -#define DSP1XGPRAM_START 0x103000 -#define DSP1XGPRAM_END 0x1033FC -#define DSP1YGPRAM_START 0x103400 -#define DSP1YGPRAM_END 0x1037FC - - - -#define AUDIORINGIPDSP2_START 0x104000 -#define AUDIORINGIPDSP2_END 0x1043FC -#define AUDIORINGOPDSP2_START 0x104400 -#define AUDIORINGOPDSP2_END 0x1047FC -#define AUDPARARINGIODSP2_START 0x104800 -#define AUDPARARINGIODSP2_END 0x104BFC -#define DSP2LOCALHWREG_START 0x104C00 -#define DSP2LOCALHWREG_END 0x104C3C -#define DSP2XYRAMAGINDEX_START 0x104C40 -#define DSP2XYRAMAGINDEX_END 0x104C5C -#define DSP2XYRAMAGMDFR_START 0x104C60 -#define DSP2XYRAMAGMDFR_END 0x104C7C -#define DSP2INTCONTLVEC_START 0x104C80 -#define DSP2INTCONTLVEC_END 0x104CD8 -#define HOSTINTFPORTADDRCONTDSP2 0x104D40 -#define HOSTINTFPORTDATADSP2 0x104D44 -#define TIME0PERENBDSP2 0x104D60 -#define TIME0COUNTERDSP2 0x104D64 -#define TIME1PERENBDSP2 0x104D68 -#define TIME1COUNTERDSP2 0x104D6C -#define TIME2PERENBDSP2 0x104D70 -#define TIME2COUNTERDSP2 0x104D74 -#define TIME3PERENBDSP2 0x104D78 -#define TIME3COUNTERDSP2 0x104D7C -#define XRAMINDOPERREFNOUP_STARTDSP2 0x104D80 -#define XRAMINDOPERREFNOUP_ENDDSP2 0x104D9C -#define XRAMINDOPERREFUP_STARTDSP2 0x104DA0 -#define XRAMINDOPERREFUP_ENDDSP2 0x104DBC -#define YRAMINDOPERREFNOUP_STARTDSP2 0x104DC0 -#define YRAMINDOPERREFNOUP_ENDDSP2 0x104DDC -#define YRAMINDOPERREFUP_STARTDSP2 0x104DE0 -#define YRAMINDOPERREFUP_ENDDSP2 0x104DFC -#define DSP2CONDCODE 0x104E00 -#define DSP2STACKFLAG 0x104E04 -#define DSP2PROGCOUNTSTACKPTREG 0x104E08 -#define DSP2PROGCOUNTSTACKDATAREG 0x104E0C -#define DSP2CURLOOPADDRREG 0x104E10 -#define DSP2CURLOOPCOUNT 0x104E14 -#define DSP2TOPLOOPCOUNTSTACK 0x104E18 -#define DSP2TOPLOOPADDRSTACK 0x104E1C -#define DSP2LOOPSTACKPTR 0x104E20 -#define DSP2STASSTACKDATAREG 0x104E24 -#define DSP2STASSTACKPTR 0x104E28 -#define DSP2PROGCOUNT 0x104E2C -#define DSP2XYRAMBASE_START 0x104EA0 -#define DSP2XYRAMBASE_END 0x104EBC -#define DSP2XYRAMLENG_START 0x104EC0 -#define DSP2XYRAMLENG_END 0x104EDC -#define SEMAPHOREREGDSP2 0x104EE0 -#define DSP2INTCONTMASKREG 0x104EE4 -#define DSP2INTCONTPENDREG 0x104EE8 -#define DSP2INTCONTSERVINT 0x104EEC -#define GPIODSP2 0x104EFC -#define DMADSPBASEADDRREG_STARTDSP2 0x104F00 -#define DMADSPBASEADDRREG_ENDDSP2 0x104F1C -#define DMAHOSTBASEADDRREG_STARTDSP2 0x104F20 -#define DMAHOSTBASEADDRREG_ENDDSP2 0x104F3C -#define DMADSPCURADDRREG_STARTDSP2 0x104F40 -#define DMADSPCURADDRREG_ENDDSP2 0x104F5C -#define DMAHOSTCURADDRREG_STARTDSP2 0x104F60 -#define DMAHOSTCURADDRREG_ENDDSP2 0x104F7C -#define DMATANXCOUNTREG_STARTDSP2 0x104F80 -#define DMATANXCOUNTREG_ENDDSP2 0x104F9C -#define DMATIMEBUGREG_STARTDSP2 0x104FA0 -#define DMATIMEBUGREG_ENDDSP2 0x104FAC -#define DMACNTLMODFREG_STARTDSP2 0x104FA0 -#define DMACNTLMODFREG_ENDDSP2 0x104FAC - -#define DMAGLOBSTATSREGDSP2 0x104FEC -#define DSP2XGPRAM_START 0x105000 -#define DSP2XGPRAM_END 0x1051FC -#define DSP2YGPRAM_START 0x105800 -#define DSP2YGPRAM_END 0x1059FC - - - -#define AUDIORINGIPDSP3_START 0x106000 -#define AUDIORINGIPDSP3_END 0x1063FC -#define AUDIORINGOPDSP3_START 0x106400 -#define AUDIORINGOPDSP3_END 0x1067FC -#define AUDPARARINGIODSP3_START 0x106800 -#define AUDPARARINGIODSP3_END 0x106BFC -#define DSP3LOCALHWREG_START 0x106C00 -#define DSP3LOCALHWREG_END 0x106C3C -#define DSP3XYRAMAGINDEX_START 0x106C40 -#define DSP3XYRAMAGINDEX_END 0x106C5C -#define DSP3XYRAMAGMDFR_START 0x106C60 -#define DSP3XYRAMAGMDFR_END 0x106C7C -#define DSP3INTCONTLVEC_START 0x106C80 -#define DSP3INTCONTLVEC_END 0x106CD8 -#define HOSTINTFPORTADDRCONTDSP3 0x106D40 -#define HOSTINTFPORTDATADSP3 0x106D44 -#define TIME0PERENBDSP3 0x106D60 -#define TIME0COUNTERDSP3 0x106D64 -#define TIME1PERENBDSP3 0x106D68 -#define TIME1COUNTERDSP3 0x106D6C -#define TIME2PERENBDSP3 0x106D70 -#define TIME2COUNTERDSP3 0x106D74 -#define TIME3PERENBDSP3 0x106D78 -#define TIME3COUNTERDSP3 0x106D7C -#define XRAMINDOPERREFNOUP_STARTDSP3 0x106D80 -#define XRAMINDOPERREFNOUP_ENDDSP3 0x106D9C -#define XRAMINDOPERREFUP_STARTDSP3 0x106DA0 -#define XRAMINDOPERREFUP_ENDDSP3 0x106DBC -#define YRAMINDOPERREFNOUP_STARTDSP3 0x106DC0 -#define YRAMINDOPERREFNOUP_ENDDSP3 0x106DDC -#define YRAMINDOPERREFUP_STARTDSP3 0x106DE0 -#define YRAMINDOPERREFUP_ENDDSP3 0x100DFC - -#define DSP3CONDCODE 0x106E00 -#define DSP3STACKFLAG 0x106E04 -#define DSP3PROGCOUNTSTACKPTREG 0x106E08 -#define DSP3PROGCOUNTSTACKDATAREG 0x106E0C -#define DSP3CURLOOPADDRREG 0x106E10 -#define DSP3CURLOOPCOUNT 0x106E14 -#define DSP3TOPLOOPCOUNTSTACK 0x106E18 -#define DSP3TOPLOOPADDRSTACK 0x106E1C -#define DSP3LOOPSTACKPTR 0x106E20 -#define DSP3STASSTACKDATAREG 0x106E24 -#define DSP3STASSTACKPTR 0x106E28 -#define DSP3PROGCOUNT 0x106E2C -#define DSP3XYRAMBASE_START 0x106EA0 -#define DSP3XYRAMBASE_END 0x106EBC -#define DSP3XYRAMLENG_START 0x106EC0 -#define DSP3XYRAMLENG_END 0x106EDC -#define SEMAPHOREREGDSP3 0x106EE0 -#define DSP3INTCONTMASKREG 0x106EE4 -#define DSP3INTCONTPENDREG 0x106EE8 -#define DSP3INTCONTSERVINT 0x106EEC -#define GPIODSP3 0x106EFC -#define DMADSPBASEADDRREG_STARTDSP3 0x106F00 -#define DMADSPBASEADDRREG_ENDDSP3 0x106F1C -#define DMAHOSTBASEADDRREG_STARTDSP3 0x106F20 -#define DMAHOSTBASEADDRREG_ENDDSP3 0x106F3C -#define DMADSPCURADDRREG_STARTDSP3 0x106F40 -#define DMADSPCURADDRREG_ENDDSP3 0x106F5C -#define DMAHOSTCURADDRREG_STARTDSP3 0x106F60 -#define DMAHOSTCURADDRREG_ENDDSP3 0x106F7C -#define DMATANXCOUNTREG_STARTDSP3 0x106F80 -#define DMATANXCOUNTREG_ENDDSP3 0x106F9C -#define DMATIMEBUGREG_STARTDSP3 0x106FA0 -#define DMATIMEBUGREG_ENDDSP3 0x106FAC -#define DMACNTLMODFREG_STARTDSP3 0x106FA0 -#define DMACNTLMODFREG_ENDDSP3 0x106FAC - -#define DMAGLOBSTATSREGDSP3 0x106FEC -#define DSP3XGPRAM_START 0x107000 -#define DSP3XGPRAM_END 0x1071FC -#define DSP3YGPRAM_START 0x107800 -#define DSP3YGPRAM_END 0x1079FC - -/* end of DSP reg definitions */ - -#define DSPAIMAP_START 0x108000 -#define DSPAIMAP_END 0x1083FC -#define DSPPIMAP_START 0x108400 -#define DSPPIMAP_END 0x1087FC -#define DSPPOMAP_START 0x108800 -#define DSPPOMAP_END 0x108BFC -#define DSPPOCTL 0x108C00 -#define TKCTL_START 0x110000 -#define TKCTL_END 0x110FFC -#define TKCC_START 0x111000 -#define TKCC_END 0x111FFC -#define TKIMAP_START 0x112000 -#define TKIMAP_END 0x112FFC -#define TKDCTR16 0x113000 -#define TKPB16 0x113004 -#define TKBS16 0x113008 -#define TKDCTR32 0x11300C -#define TKPB32 0x113010 -#define TKBS32 0x113014 -#define ICDCTR16 0x113018 -#define ITBS16 0x11301C -#define ICDCTR32 0x113020 -#define ITBS32 0x113024 -#define ITSTART 0x113028 -#define TKSQ 0x11302C - -#define TKSCCTL_START 0x114000 -#define TKSCCTL_END 0x11403C -#define TKSCADR_START 0x114100 -#define TKSCADR_END 0x11413C -#define TKSCDATAX_START 0x114800 -#define TKSCDATAX_END 0x1149FC -#define TKPCDATAX_START 0x120000 -#define TKPCDATAX_END 0x12FFFC - -#define MALSA 0x130000 -#define MAPPHA 0x130004 -#define MAPPLA 0x130008 -#define MALSB 0x130010 -#define MAPPHB 0x130014 -#define MAPPLB 0x130018 - -#define TANSPORTMAPABREGS_START 0x130020 -#define TANSPORTMAPABREGS_END 0x13A2FC - -#define PTPAHX 0x13B000 -#define PTPALX 0x13B004 - -#define TANSPPAGETABLEPHYADDR015_START 0x13B008 -#define TANSPPAGETABLEPHYADDR015_END 0x13B07C -#define TRNQADRX_START 0x13B100 -#define TRNQADRX_END 0x13B13C -#define TRNQTIMX_START 0x13B200 -#define TRNQTIMX_END 0x13B23C -#define TRNQAPARMX_START 0x13B300 -#define TRNQAPARMX_END 0x13B33C - -#define TRNQCNT 0x13B400 -#define TRNCTL 0x13B404 -#define TRNIS 0x13B408 -#define TRNCURTS 0x13B40C - -#define AMOP_START 0x140000 -#define AMOPLO 0x140000 -#define AMOPHI 0x140004 -#define AMOP_END 0x147FFC -#define PMOP_START 0x148000 -#define PMOPLO 0x148000 -#define PMOPHI 0x148004 -#define PMOP_END 0x14FFFC -#define PCURR_START 0x150000 -#define PCURR_END 0x153FFC -#define PTRAG_START 0x154000 -#define PTRAG_END 0x157FFC -#define PSR_START 0x158000 -#define PSR_END 0x15BFFC - -#define PFSTAT4SEG_START 0x160000 -#define PFSTAT4SEG_END 0x160BFC -#define PFSTAT2SEG_START 0x160C00 -#define PFSTAT2SEG_END 0x1617FC -#define PFTARG4SEG_START 0x164000 -#define PFTARG4SEG_END 0x164BFC -#define PFTARG2SEG_START 0x164C00 -#define PFTARG2SEG_END 0x1657FC -#define PFSR4SEG_START 0x168000 -#define PFSR4SEG_END 0x168BFC -#define PFSR2SEG_START 0x168C00 -#define PFSR2SEG_END 0x1697FC -#define PCURRMS4SEG_START 0x16C000 -#define PCURRMS4SEG_END 0x16CCFC -#define PCURRMS2SEG_START 0x16CC00 -#define PCURRMS2SEG_END 0x16D7FC -#define PTARGMS4SEG_START 0x170000 -#define PTARGMS4SEG_END 0x172FFC -#define PTARGMS2SEG_START 0x173000 -#define PTARGMS2SEG_END 0x1747FC -#define PSRMS4SEG_START 0x170000 -#define PSRMS4SEG_END 0x172FFC -#define PSRMS2SEG_START 0x173000 -#define PSRMS2SEG_END 0x1747FC - -#define PRING_LO_START 0x190000 -#define PRING_LO_END 0x193FFC -#define PRING_HI_START 0x194000 -#define PRING_HI_END 0x197FFC -#define PRING_LO_HI_START 0x198000 -#define PRING_LO_HI 0x198000 -#define PRING_LO_HI_END 0x19BFFC - -#define PINTFIFO 0x1A0000 -#define SRCCTL 0x1B0000 -#define SRCCCR 0x1B0004 -#define SRCIMAP 0x1B0008 -#define SRCODDC 0x1B000C -#define SRCCA 0x1B0010 -#define SRCCF 0x1B0014 -#define SRCSA 0x1B0018 -#define SRCLA 0x1B001C -#define SRCCTLSWR 0x1B0020 - -/* SRC HERE */ -#define SRCALBA 0x1B002C -#define SRCMCTL 0x1B012C -#define SRCCERR 0x1B022C -#define SRCITB 0x1B032C -#define SRCIPM 0x1B082C -#define SRCIP 0x1B102C -#define SRCENBSTAT 0x1B202C -#define SRCENBLO 0x1B212C -#define SRCENBHI 0x1B222C -#define SRCENBS 0x1B232C -#define SRCENB 0x1B282C -#define SRCENB07 0x1B282C -#define SRCENBS07 0x1B302C - -#define SRCDN0Z 0x1B0030 -#define SRCDN0Z0 0x1B0030 -#define SRCDN0Z1 0x1B0034 -#define SRCDN0Z2 0x1B0038 -#define SRCDN0Z3 0x1B003C -#define SRCDN1Z 0x1B0040 -#define SRCDN1Z0 0x1B0040 -#define SRCDN1Z1 0x1B0044 -#define SRCDN1Z2 0x1B0048 -#define SRCDN1Z3 0x1B004C -#define SRCDN1Z4 0x1B0050 -#define SRCDN1Z5 0x1B0054 -#define SRCDN1Z6 0x1B0058 -#define SRCDN1Z7 0x1B005C -#define SRCUPZ 0x1B0060 -#define SRCUPZ0 0x1B0060 -#define SRCUPZ1 0x1B0064 -#define SRCUPZ2 0x1B0068 -#define SRCUPZ3 0x1B006C -#define SRCUPZ4 0x1B0070 -#define SRCUPZ5 0x1B0074 -#define SRCUPZ6 0x1B0078 -#define SRCUPZ7 0x1B007C -#define SRCCD0 0x1B0080 -#define SRCCD1 0x1B0084 -#define SRCCD2 0x1B0088 -#define SRCCD3 0x1B008C -#define SRCCD4 0x1B0090 -#define SRCCD5 0x1B0094 -#define SRCCD6 0x1B0098 -#define SRCCD7 0x1B009C -#define SRCCD8 0x1B00A0 -#define SRCCD9 0x1B00A4 -#define SRCCDA 0x1B00A8 -#define SRCCDB 0x1B00AC -#define SRCCDC 0x1B00B0 -#define SRCCDD 0x1B00B4 -#define SRCCDE 0x1B00B8 -#define SRCCDF 0x1B00BC -#define SRCCD10 0x1B00C0 -#define SRCCD11 0x1B00C4 -#define SRCCD12 0x1B00C8 -#define SRCCD13 0x1B00CC -#define SRCCD14 0x1B00D0 -#define SRCCD15 0x1B00D4 -#define SRCCD16 0x1B00D8 -#define SRCCD17 0x1B00DC -#define SRCCD18 0x1B00E0 -#define SRCCD19 0x1B00E4 -#define SRCCD1A 0x1B00E8 -#define SRCCD1B 0x1B00EC -#define SRCCD1C 0x1B00F0 -#define SRCCD1D 0x1B00F4 -#define SRCCD1E 0x1B00F8 -#define SRCCD1F 0x1B00FC - -#define SRCCONTRBLOCK_START 0x1B0100 -#define SRCCONTRBLOCK_END 0x1BFFFC -#define FILTOP_START 0x1C0000 -#define FILTOP_END 0x1C05FC -#define FILTIMAP_START 0x1C0800 -#define FILTIMAP_END 0x1C0DFC -#define FILTZ1_START 0x1C1000 -#define FILTZ1_END 0x1C15FC -#define FILTZ2_START 0x1C1800 -#define FILTZ2_END 0x1C1DFC -#define DAOIMAP_START 0x1C5000 -#define DAOIMAP 0x1C5000 -#define DAOIMAP_END 0x1C5124 - -#define AC97D 0x1C5400 -#define AC97A 0x1C5404 -#define AC97CTL 0x1C5408 -#define I2SCTL 0x1C5420 - -#define SPOS 0x1C5440 -#define SPOSA 0x1C5440 -#define SPOSB 0x1C5444 -#define SPOSC 0x1C5448 -#define SPOSD 0x1C544C - -#define SPISA 0x1C5450 -#define SPISB 0x1C5454 -#define SPISC 0x1C5458 -#define SPISD 0x1C545C - -#define SPFSCTL 0x1C5460 - -#define SPFS0 0x1C5468 -#define SPFS1 0x1C546C -#define SPFS2 0x1C5470 -#define SPFS3 0x1C5474 -#define SPFS4 0x1C5478 -#define SPFS5 0x1C547C - -#define SPOCTL 0x1C5480 -#define SPICTL 0x1C5484 -#define SPISTS 0x1C5488 -#define SPINTP 0x1C548C -#define SPINTE 0x1C5490 -#define SPUTCTLAB 0x1C5494 -#define SPUTCTLCD 0x1C5498 - -#define SRTSPA 0x1C54C0 -#define SRTSPB 0x1C54C4 -#define SRTSPC 0x1C54C8 -#define SRTSPD 0x1C54CC - -#define SRTSCTL 0x1C54D0 -#define SRTSCTLA 0x1C54D0 -#define SRTSCTLB 0x1C54D4 -#define SRTSCTLC 0x1C54D8 -#define SRTSCTLD 0x1C54DC - -#define SRTI2S 0x1C54E0 -#define SRTICTL 0x1C54F0 - -#define WC 0x1C6000 -#define TIMR 0x1C6004 -# define TIMR_IE (1<<15) -# define TIMR_IP (1<<14) - -#define GIP 0x1C6010 -#define GIE 0x1C6014 -#define DIE 0x1C6018 -#define DIC 0x1C601C -#define GPIO 0x1C6020 -#define GPIOCTL 0x1C6024 -#define GPIP 0x1C6028 -#define GPIE 0x1C602C -#define DSPINT0 0x1C6030 -#define DSPEIOC 0x1C6034 -#define MUADAT 0x1C6040 -#define MUACMD 0x1C6044 -#define MUASTAT 0x1C6044 -#define MUBDAT 0x1C6048 -#define MUBCMD 0x1C604C -#define MUBSTAT 0x1C604C -#define UARTCMA 0x1C6050 -#define UARTCMB 0x1C6054 -#define UARTIP 0x1C6058 -#define UARTIE 0x1C605C -#define PLLCTL 0x1C6060 -#define PLLDCD 0x1C6064 -#define GCTL 0x1C6070 -#define ID0 0x1C6080 -#define ID1 0x1C6084 -#define ID2 0x1C6088 -#define ID3 0x1C608C -#define SDRCTL 0x1C7000 - - -#define I2SA_L 0x0L -#define I2SA_R 0x1L -#define I2SB_L 0x8L -#define I2SB_R 0x9L -#define I2SC_L 0x10L -#define I2SC_R 0x11L -#define I2SD_L 0x18L -#define I2SD_R 0x19L - -#endif /* CT20K1REG_H */ - - diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k2reg.h b/ANDROID_3.4.5/sound/pci/ctxfi/ct20k2reg.h deleted file mode 100644 index ca501ba0..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k2reg.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * 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. - */ - -#ifndef _20K2REGISTERS_H_ -#define _20K2REGISTERS_H_ - - -/* Timer Registers */ -#define WC 0x1b7000 -#define TIMR 0x1b7004 -# define TIMR_IE (1<<15) -# define TIMR_IP (1<<14) -#define GIP 0x1b7010 -#define GIE 0x1b7014 - -/* I2C Registers */ -#define I2C_IF_ADDRESS 0x1B9000 -#define I2C_IF_WDATA 0x1B9004 -#define I2C_IF_RDATA 0x1B9008 -#define I2C_IF_STATUS 0x1B900C -#define I2C_IF_WLOCK 0x1B9010 - -/* Global Control Registers */ -#define GLOBAL_CNTL_GCTL 0x1B7090 - -/* PLL Registers */ -#define PLL_CTL 0x1B7080 -#define PLL_STAT 0x1B7084 -#define PLL_ENB 0x1B7088 - -/* SRC Registers */ -#define SRC_CTL 0x1A0000 /* 0x1A0000 + (256 * Chn) */ -#define SRC_CCR 0x1A0004 /* 0x1A0004 + (256 * Chn) */ -#define SRC_IMAP 0x1A0008 /* 0x1A0008 + (256 * Chn) */ -#define SRC_CA 0x1A0010 /* 0x1A0010 + (256 * Chn) */ -#define SRC_CF 0x1A0014 /* 0x1A0014 + (256 * Chn) */ -#define SRC_SA 0x1A0018 /* 0x1A0018 + (256 * Chn) */ -#define SRC_LA 0x1A001C /* 0x1A001C + (256 * Chn) */ -#define SRC_CTLSWR 0x1A0020 /* 0x1A0020 + (256 * Chn) */ -#define SRC_CD 0x1A0080 /* 0x1A0080 + (256 * Chn) + (4 * Regn) */ -#define SRC_MCTL 0x1A012C -#define SRC_IP 0x1A102C /* 0x1A102C + (256 * Regn) */ -#define SRC_ENB 0x1A282C /* 0x1A282C + (256 * Regn) */ -#define SRC_ENBSTAT 0x1A202C -#define SRC_ENBSA 0x1A232C -#define SRC_DN0Z 0x1A0030 -#define SRC_DN1Z 0x1A0040 -#define SRC_UPZ 0x1A0060 - -/* GPIO Registers */ -#define GPIO_DATA 0x1B7020 -#define GPIO_CTRL 0x1B7024 -#define GPIO_EXT_DATA 0x1B70A0 - -/* Virtual memory registers */ -#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */ -#define VMEM_PTPAH 0x1C6304 /* 0x1C6304 + (16 * Chn) */ -#define VMEM_CTL 0x1C7000 - -/* Transport Registers */ -#define TRANSPORT_ENB 0x1B6000 -#define TRANSPORT_CTL 0x1B6004 -#define TRANSPORT_INT 0x1B6008 - -/* Audio IO */ -#define AUDIO_IO_AIM 0x1B5000 /* 0x1B5000 + (0x04 * Chn) */ -#define AUDIO_IO_TX_CTL 0x1B5400 /* 0x1B5400 + (0x40 * Chn) */ -#define AUDIO_IO_TX_CSTAT_L 0x1B5408 /* 0x1B5408 + (0x40 * Chn) */ -#define AUDIO_IO_TX_CSTAT_H 0x1B540C /* 0x1B540C + (0x40 * Chn) */ -#define AUDIO_IO_RX_CTL 0x1B5410 /* 0x1B5410 + (0x40 * Chn) */ -#define AUDIO_IO_RX_SRT_CTL 0x1B5420 /* 0x1B5420 + (0x40 * Chn) */ -#define AUDIO_IO_MCLK 0x1B5600 -#define AUDIO_IO_TX_BLRCLK 0x1B5604 -#define AUDIO_IO_RX_BLRCLK 0x1B5608 - -/* Mixer */ -#define MIXER_AMOPLO 0x130000 /* 0x130000 + (8 * Chn) [4095 : 0] */ -#define MIXER_AMOPHI 0x130004 /* 0x130004 + (8 * Chn) [4095 : 0] */ -#define MIXER_PRING_LO_HI 0x188000 /* 0x188000 + (4 * Chn) [4095 : 0] */ -#define MIXER_PMOPLO 0x138000 /* 0x138000 + (8 * Chn) [4095 : 0] */ -#define MIXER_PMOPHI 0x138004 /* 0x138004 + (8 * Chn) [4095 : 0] */ -#define MIXER_AR_ENABLE 0x19000C - -#endif diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.c deleted file mode 100644 index fee35cfc..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.c +++ /dev/null @@ -1,486 +0,0 @@ -/** - * 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 ctamixer.c - * - * @Brief - * This file contains the implementation of the Audio Mixer - * resource management object. - * - * @Author Liu Chun - * @Date May 21 2008 - * - */ - -#include "ctamixer.h" -#include "cthardware.h" -#include <linux/slab.h> - -#define AMIXER_RESOURCE_NUM 256 -#define SUM_RESOURCE_NUM 256 - -#define AMIXER_Y_IMMEDIATE 1 - -#define BLANK_SLOT 4094 - -static int amixer_master(struct rsc *rsc) -{ - rsc->conj = 0; - return rsc->idx = container_of(rsc, struct amixer, rsc)->idx[0]; -} - -static int amixer_next_conj(struct rsc *rsc) -{ - rsc->conj++; - return container_of(rsc, struct amixer, rsc)->idx[rsc->conj]; -} - -static int amixer_index(const struct rsc *rsc) -{ - return container_of(rsc, struct amixer, rsc)->idx[rsc->conj]; -} - -static int amixer_output_slot(const struct rsc *rsc) -{ - return (amixer_index(rsc) << 4) + 0x4; -} - -static struct rsc_ops amixer_basic_rsc_ops = { - .master = amixer_master, - .next_conj = amixer_next_conj, - .index = amixer_index, - .output_slot = amixer_output_slot, -}; - -static int amixer_set_input(struct amixer *amixer, struct rsc *rsc) -{ - struct hw *hw; - - hw = amixer->rsc.hw; - hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE); - amixer->input = rsc; - if (!rsc) - hw->amixer_set_x(amixer->rsc.ctrl_blk, BLANK_SLOT); - else - hw->amixer_set_x(amixer->rsc.ctrl_blk, - rsc->ops->output_slot(rsc)); - - return 0; -} - -/* y is a 14-bit immediate constant */ -static int amixer_set_y(struct amixer *amixer, unsigned int y) -{ - struct hw *hw; - - hw = amixer->rsc.hw; - hw->amixer_set_y(amixer->rsc.ctrl_blk, y); - - return 0; -} - -static int amixer_set_invalid_squash(struct amixer *amixer, unsigned int iv) -{ - struct hw *hw; - - hw = amixer->rsc.hw; - hw->amixer_set_iv(amixer->rsc.ctrl_blk, iv); - - return 0; -} - -static int amixer_set_sum(struct amixer *amixer, struct sum *sum) -{ - struct hw *hw; - - hw = amixer->rsc.hw; - amixer->sum = sum; - if (!sum) { - hw->amixer_set_se(amixer->rsc.ctrl_blk, 0); - } else { - hw->amixer_set_se(amixer->rsc.ctrl_blk, 1); - hw->amixer_set_sadr(amixer->rsc.ctrl_blk, - sum->rsc.ops->index(&sum->rsc)); - } - - return 0; -} - -static int amixer_commit_write(struct amixer *amixer) -{ - struct hw *hw; - unsigned int index; - int i; - struct rsc *input; - struct sum *sum; - - hw = amixer->rsc.hw; - input = amixer->input; - sum = amixer->sum; - - /* Program master and conjugate resources */ - amixer->rsc.ops->master(&amixer->rsc); - if (input) - input->ops->master(input); - - if (sum) - sum->rsc.ops->master(&sum->rsc); - - for (i = 0; i < amixer->rsc.msr; i++) { - hw->amixer_set_dirty_all(amixer->rsc.ctrl_blk); - if (input) { - hw->amixer_set_x(amixer->rsc.ctrl_blk, - input->ops->output_slot(input)); - input->ops->next_conj(input); - } - if (sum) { - hw->amixer_set_sadr(amixer->rsc.ctrl_blk, - sum->rsc.ops->index(&sum->rsc)); - sum->rsc.ops->next_conj(&sum->rsc); - } - index = amixer->rsc.ops->output_slot(&amixer->rsc); - hw->amixer_commit_write(hw, index, amixer->rsc.ctrl_blk); - amixer->rsc.ops->next_conj(&amixer->rsc); - } - amixer->rsc.ops->master(&amixer->rsc); - if (input) - input->ops->master(input); - - if (sum) - sum->rsc.ops->master(&sum->rsc); - - return 0; -} - -static int amixer_commit_raw_write(struct amixer *amixer) -{ - struct hw *hw; - unsigned int index; - - hw = amixer->rsc.hw; - index = amixer->rsc.ops->output_slot(&amixer->rsc); - hw->amixer_commit_write(hw, index, amixer->rsc.ctrl_blk); - - return 0; -} - -static int amixer_get_y(struct amixer *amixer) -{ - struct hw *hw; - - hw = amixer->rsc.hw; - return hw->amixer_get_y(amixer->rsc.ctrl_blk); -} - -static int amixer_setup(struct amixer *amixer, struct rsc *input, - unsigned int scale, struct sum *sum) -{ - amixer_set_input(amixer, input); - amixer_set_y(amixer, scale); - amixer_set_sum(amixer, sum); - amixer_commit_write(amixer); - return 0; -} - -static struct amixer_rsc_ops amixer_ops = { - .set_input = amixer_set_input, - .set_invalid_squash = amixer_set_invalid_squash, - .set_scale = amixer_set_y, - .set_sum = amixer_set_sum, - .commit_write = amixer_commit_write, - .commit_raw_write = amixer_commit_raw_write, - .setup = amixer_setup, - .get_scale = amixer_get_y, -}; - -static int amixer_rsc_init(struct amixer *amixer, - const struct amixer_desc *desc, - struct amixer_mgr *mgr) -{ - int err; - - err = rsc_init(&amixer->rsc, amixer->idx[0], - AMIXER, desc->msr, mgr->mgr.hw); - if (err) - return err; - - /* Set amixer specific operations */ - amixer->rsc.ops = &amixer_basic_rsc_ops; - amixer->ops = &amixer_ops; - amixer->input = NULL; - amixer->sum = NULL; - - amixer_setup(amixer, NULL, 0, NULL); - - return 0; -} - -static int amixer_rsc_uninit(struct amixer *amixer) -{ - amixer_setup(amixer, NULL, 0, NULL); - rsc_uninit(&amixer->rsc); - amixer->ops = NULL; - amixer->input = NULL; - amixer->sum = NULL; - return 0; -} - -static int get_amixer_rsc(struct amixer_mgr *mgr, - const struct amixer_desc *desc, - struct amixer **ramixer) -{ - int err, i; - unsigned int idx; - struct amixer *amixer; - unsigned long flags; - - *ramixer = NULL; - - /* Allocate mem for amixer resource */ - amixer = kzalloc(sizeof(*amixer), GFP_KERNEL); - if (!amixer) - return -ENOMEM; - - /* Check whether there are sufficient - * amixer resources to meet request. */ - err = 0; - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i = 0; i < desc->msr; i++) { - err = mgr_get_resource(&mgr->mgr, 1, &idx); - if (err) - break; - - amixer->idx[i] = idx; - } - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - if (err) { - printk(KERN_ERR "ctxfi: Can't meet AMIXER resource request!\n"); - goto error; - } - - err = amixer_rsc_init(amixer, desc, mgr); - if (err) - goto error; - - *ramixer = amixer; - - return 0; - -error: - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i--; i >= 0; i--) - mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - kfree(amixer); - return err; -} - -static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i = 0; i < amixer->rsc.msr; i++) - mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - amixer_rsc_uninit(amixer); - kfree(amixer); - - return 0; -} - -int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr) -{ - int err; - struct amixer_mgr *amixer_mgr; - - *ramixer_mgr = NULL; - amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL); - if (!amixer_mgr) - return -ENOMEM; - - err = rsc_mgr_init(&amixer_mgr->mgr, AMIXER, AMIXER_RESOURCE_NUM, hw); - if (err) - goto error; - - spin_lock_init(&amixer_mgr->mgr_lock); - - amixer_mgr->get_amixer = get_amixer_rsc; - amixer_mgr->put_amixer = put_amixer_rsc; - - *ramixer_mgr = amixer_mgr; - - return 0; - -error: - kfree(amixer_mgr); - return err; -} - -int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr) -{ - rsc_mgr_uninit(&amixer_mgr->mgr); - kfree(amixer_mgr); - return 0; -} - -/* SUM resource management */ - -static int sum_master(struct rsc *rsc) -{ - rsc->conj = 0; - return rsc->idx = container_of(rsc, struct sum, rsc)->idx[0]; -} - -static int sum_next_conj(struct rsc *rsc) -{ - rsc->conj++; - return container_of(rsc, struct sum, rsc)->idx[rsc->conj]; -} - -static int sum_index(const struct rsc *rsc) -{ - return container_of(rsc, struct sum, rsc)->idx[rsc->conj]; -} - -static int sum_output_slot(const struct rsc *rsc) -{ - return (sum_index(rsc) << 4) + 0xc; -} - -static struct rsc_ops sum_basic_rsc_ops = { - .master = sum_master, - .next_conj = sum_next_conj, - .index = sum_index, - .output_slot = sum_output_slot, -}; - -static int sum_rsc_init(struct sum *sum, - const struct sum_desc *desc, - struct sum_mgr *mgr) -{ - int err; - - err = rsc_init(&sum->rsc, sum->idx[0], SUM, desc->msr, mgr->mgr.hw); - if (err) - return err; - - sum->rsc.ops = &sum_basic_rsc_ops; - - return 0; -} - -static int sum_rsc_uninit(struct sum *sum) -{ - rsc_uninit(&sum->rsc); - return 0; -} - -static int get_sum_rsc(struct sum_mgr *mgr, - const struct sum_desc *desc, - struct sum **rsum) -{ - int err, i; - unsigned int idx; - struct sum *sum; - unsigned long flags; - - *rsum = NULL; - - /* Allocate mem for sum resource */ - sum = kzalloc(sizeof(*sum), GFP_KERNEL); - if (!sum) - return -ENOMEM; - - /* Check whether there are sufficient sum resources to meet request. */ - err = 0; - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i = 0; i < desc->msr; i++) { - err = mgr_get_resource(&mgr->mgr, 1, &idx); - if (err) - break; - - sum->idx[i] = idx; - } - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - if (err) { - printk(KERN_ERR "ctxfi: Can't meet SUM resource request!\n"); - goto error; - } - - err = sum_rsc_init(sum, desc, mgr); - if (err) - goto error; - - *rsum = sum; - - return 0; - -error: - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i--; i >= 0; i--) - mgr_put_resource(&mgr->mgr, 1, sum->idx[i]); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - kfree(sum); - return err; -} - -static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i = 0; i < sum->rsc.msr; i++) - mgr_put_resource(&mgr->mgr, 1, sum->idx[i]); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - sum_rsc_uninit(sum); - kfree(sum); - - return 0; -} - -int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr) -{ - int err; - struct sum_mgr *sum_mgr; - - *rsum_mgr = NULL; - sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL); - if (!sum_mgr) - return -ENOMEM; - - err = rsc_mgr_init(&sum_mgr->mgr, SUM, SUM_RESOURCE_NUM, hw); - if (err) - goto error; - - spin_lock_init(&sum_mgr->mgr_lock); - - sum_mgr->get_sum = get_sum_rsc; - sum_mgr->put_sum = put_sum_rsc; - - *rsum_mgr = sum_mgr; - - return 0; - -error: - kfree(sum_mgr); - return err; -} - -int sum_mgr_destroy(struct sum_mgr *sum_mgr) -{ - rsc_mgr_uninit(&sum_mgr->mgr); - kfree(sum_mgr); - return 0; -} - diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.h deleted file mode 100644 index cc49e5ab..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * 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 ctamixer.h - * - * @Brief - * This file contains the definition of the Audio Mixer - * resource management object. - * - * @Author Liu Chun - * @Date May 21 2008 - * - */ - -#ifndef CTAMIXER_H -#define CTAMIXER_H - -#include "ctresource.h" -#include <linux/spinlock.h> - -/* Define the descriptor of a summation node resource */ -struct sum { - struct rsc rsc; /* Basic resource info */ - unsigned char idx[8]; -}; - -/* Define sum resource request description info */ -struct sum_desc { - unsigned int msr; -}; - -struct sum_mgr { - struct rsc_mgr mgr; /* Basic resource manager info */ - spinlock_t mgr_lock; - - /* request one sum resource */ - int (*get_sum)(struct sum_mgr *mgr, - const struct sum_desc *desc, struct sum **rsum); - /* return one sum resource */ - int (*put_sum)(struct sum_mgr *mgr, struct sum *sum); -}; - -/* Constructor and destructor of daio resource manager */ -int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr); -int sum_mgr_destroy(struct sum_mgr *sum_mgr); - -/* Define the descriptor of a amixer resource */ -struct amixer_rsc_ops; - -struct amixer { - struct rsc rsc; /* Basic resource info */ - unsigned char idx[8]; - struct rsc *input; /* pointer to a resource acting as source */ - struct sum *sum; /* Put amixer output to this summation node */ - struct amixer_rsc_ops *ops; /* AMixer specific operations */ -}; - -struct amixer_rsc_ops { - int (*set_input)(struct amixer *amixer, struct rsc *rsc); - int (*set_scale)(struct amixer *amixer, unsigned int scale); - int (*set_invalid_squash)(struct amixer *amixer, unsigned int iv); - int (*set_sum)(struct amixer *amixer, struct sum *sum); - int (*commit_write)(struct amixer *amixer); - /* Only for interleaved recording */ - int (*commit_raw_write)(struct amixer *amixer); - int (*setup)(struct amixer *amixer, struct rsc *input, - unsigned int scale, struct sum *sum); - int (*get_scale)(struct amixer *amixer); -}; - -/* Define amixer resource request description info */ -struct amixer_desc { - unsigned int msr; -}; - -struct amixer_mgr { - struct rsc_mgr mgr; /* Basic resource manager info */ - spinlock_t mgr_lock; - - /* request one amixer resource */ - int (*get_amixer)(struct amixer_mgr *mgr, - const struct amixer_desc *desc, - struct amixer **ramixer); - /* return one amixer resource */ - int (*put_amixer)(struct amixer_mgr *mgr, struct amixer *amixer); -}; - -/* Constructor and destructor of amixer resource manager */ -int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr); -int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr); - -#endif /* CTAMIXER_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.c deleted file mode 100644 index d8a44235..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.c +++ /dev/null @@ -1,1744 +0,0 @@ -/** - * 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 ctatc.c - * - * @Brief - * This file contains the implementation of the device resource management - * object. - * - * @Author Liu Chun - * @Date Mar 28 2008 - */ - -#include "ctatc.h" -#include "ctpcm.h" -#include "ctmixer.h" -#include "ctsrc.h" -#include "ctamixer.h" -#include "ctdaio.h" -#include "cttimer.h" -#include <linux/delay.h> -#include <linux/slab.h> -#include <sound/pcm.h> -#include <sound/control.h> -#include <sound/asoundef.h> - -#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */ -#define MAX_MULTI_CHN 8 - -#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \ - | IEC958_AES0_CON_NOT_COPYRIGHT) \ - | ((IEC958_AES1_CON_MIXER \ - | IEC958_AES1_CON_ORIGINAL) << 8) \ - | (0x10 << 16) \ - | ((IEC958_AES3_CON_FS_48000) << 24)) - -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, 0xf000, 0x6000, - "UAA", CTUAA), - { } /* 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_SB1270, - "SB1270", CTSB1270), - 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, 0xf000, - PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "HENDRIX", - CTHENDRIX), - { } /* terminator */ -}; - -static const char *ct_subsys_name[NUM_CTCARDS] = { - /* 20k1 models */ - [CTSB055X] = "SB055x", - [CTSB073X] = "SB073x", - [CTUAA] = "UAA", - [CT20K1_UNKNOWN] = "Unknown", - /* 20k2 models */ - [CTSB0760] = "SB076x", - [CTHENDRIX] = "Hendrix", - [CTSB0880] = "SB0880", - [CTSB1270] = "SB1270", - [CT20K2_UNKNOWN] = "Unknown", -}; - -static struct { - int (*create)(struct ct_atc *atc, - enum CTALSADEVS device, const char *device_name); - int (*destroy)(void *alsa_dev); - const char *public_name; -} alsa_dev_funcs[NUM_CTALSADEVS] = { - [FRONT] = { .create = ct_alsa_pcm_create, - .destroy = NULL, - .public_name = "Front/WaveIn"}, - [SURROUND] = { .create = ct_alsa_pcm_create, - .destroy = NULL, - .public_name = "Surround"}, - [CLFE] = { .create = ct_alsa_pcm_create, - .destroy = NULL, - .public_name = "Center/LFE"}, - [SIDE] = { .create = ct_alsa_pcm_create, - .destroy = NULL, - .public_name = "Side"}, - [IEC958] = { .create = ct_alsa_pcm_create, - .destroy = NULL, - .public_name = "IEC958 Non-audio"}, - - [MIXER] = { .create = ct_alsa_mix_create, - .destroy = NULL, - .public_name = "Mixer"} -}; - -typedef int (*create_t)(void *, void **); -typedef int (*destroy_t)(void *); - -static struct { - int (*create)(void *hw, void **rmgr); - int (*destroy)(void *mgr); -} rsc_mgr_funcs[NUM_RSCTYP] = { - [SRC] = { .create = (create_t)src_mgr_create, - .destroy = (destroy_t)src_mgr_destroy }, - [SRCIMP] = { .create = (create_t)srcimp_mgr_create, - .destroy = (destroy_t)srcimp_mgr_destroy }, - [AMIXER] = { .create = (create_t)amixer_mgr_create, - .destroy = (destroy_t)amixer_mgr_destroy }, - [SUM] = { .create = (create_t)sum_mgr_create, - .destroy = (destroy_t)sum_mgr_destroy }, - [DAIO] = { .create = (create_t)daio_mgr_create, - .destroy = (destroy_t)daio_mgr_destroy } -}; - -static int -atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm); - -/* * - * Only mono and interleaved modes are supported now. - * Always allocates a contiguous channel block. - * */ - -static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct snd_pcm_runtime *runtime; - struct ct_vm *vm; - - if (!apcm->substream) - return 0; - - runtime = apcm->substream->runtime; - vm = atc->vm; - - apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes); - - if (!apcm->vm_block) - return -ENOENT; - - return 0; -} - -static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct ct_vm *vm; - - if (!apcm->vm_block) - return; - - vm = atc->vm; - - vm->unmap(vm, apcm->vm_block); - - apcm->vm_block = NULL; -} - -static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index) -{ - return atc->vm->get_ptp_phys(atc->vm, index); -} - -static unsigned int convert_format(snd_pcm_format_t snd_format) -{ - switch (snd_format) { - case SNDRV_PCM_FORMAT_U8: - return SRC_SF_U8; - case SNDRV_PCM_FORMAT_S16_LE: - return SRC_SF_S16; - case SNDRV_PCM_FORMAT_S24_3LE: - return SRC_SF_S24; - case SNDRV_PCM_FORMAT_S32_LE: - return SRC_SF_S32; - case SNDRV_PCM_FORMAT_FLOAT_LE: - return SRC_SF_F32; - default: - printk(KERN_ERR "ctxfi: not recognized snd format is %d \n", - snd_format); - return SRC_SF_S16; - } -} - -static unsigned int -atc_get_pitch(unsigned int input_rate, unsigned int output_rate) -{ - unsigned int pitch; - int b; - - /* get pitch and convert to fixed-point 8.24 format. */ - pitch = (input_rate / output_rate) << 24; - input_rate %= output_rate; - input_rate /= 100; - output_rate /= 100; - for (b = 31; ((b >= 0) && !(input_rate >> b)); ) - b--; - - if (b >= 0) { - input_rate <<= (31 - b); - input_rate /= output_rate; - b = 24 - (31 - b); - if (b >= 0) - input_rate <<= b; - else - input_rate >>= -b; - - pitch |= input_rate; - } - - return pitch; -} - -static int select_rom(unsigned int pitch) -{ - if (pitch > 0x00428f5c && pitch < 0x01b851ec) { - /* 0.26 <= pitch <= 1.72 */ - return 1; - } else if (pitch == 0x01d66666 || pitch == 0x01d66667) { - /* pitch == 1.8375 */ - return 2; - } else if (pitch == 0x02000000) { - /* pitch == 2 */ - return 3; - } else if (pitch <= 0x08000000) { - /* 0 <= pitch <= 8 */ - return 0; - } else { - return -ENOENT; - } -} - -static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src_mgr *src_mgr = atc->rsc_mgrs[SRC]; - struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER]; - struct src_desc desc = {0}; - struct amixer_desc mix_dsc = {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; - - /* first release old resources */ - atc_pcm_release_resources(atc, apcm); - - /* Get SRC resource */ - desc.multi = apcm->substream->runtime->channels; - desc.msr = atc->msr; - desc.mode = MEMRD; - err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src); - if (err) - goto error1; - - pitch = atc_get_pitch(apcm->substream->runtime->rate, - (atc->rsr * atc->msr)); - src = apcm->src; - src->ops->set_pitch(src, pitch); - src->ops->set_rom(src, select_rom(pitch)); - src->ops->set_sf(src, convert_format(apcm->substream->runtime->format)); - src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL)); - - /* Get AMIXER resource */ - n_amixer = (n_amixer < 2) ? 2 : n_amixer; - apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); - if (!apcm->amixers) { - err = -ENOMEM; - goto error1; - } - mix_dsc.msr = atc->msr; - for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) { - err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc, - (struct amixer **)&apcm->amixers[i]); - if (err) - goto error1; - - apcm->n_amixer++; - } - - /* Set up device virtual mem map */ - err = ct_map_audio_buffer(atc, apcm); - if (err < 0) - goto error1; - - /* Connect resources */ - src = apcm->src; - for (i = 0; i < n_amixer; i++) { - amixer = apcm->amixers[i]; - mutex_lock(&atc->atc_mutex); - amixer->ops->setup(amixer, &src->rsc, - INIT_VOL, atc->pcm[i+device*2]); - mutex_unlock(&atc->atc_mutex); - src = src->ops->next_interleave(src); - if (!src) - src = apcm->src; - } - - ct_timer_prepare(apcm->timer); - - return 0; - -error1: - atc_pcm_release_resources(atc, apcm); - return err; -} - -static int -atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src_mgr *src_mgr = atc->rsc_mgrs[SRC]; - 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; - int i; - - if (apcm->srcimps) { - for (i = 0; i < apcm->n_srcimp; i++) { - srcimp = apcm->srcimps[i]; - srcimp->ops->unmap(srcimp); - srcimp_mgr->put_srcimp(srcimp_mgr, srcimp); - apcm->srcimps[i] = NULL; - } - kfree(apcm->srcimps); - apcm->srcimps = NULL; - } - - if (apcm->srccs) { - for (i = 0; i < apcm->n_srcc; i++) { - src_mgr->put_src(src_mgr, apcm->srccs[i]); - apcm->srccs[i] = NULL; - } - kfree(apcm->srccs); - apcm->srccs = NULL; - } - - if (apcm->amixers) { - for (i = 0; i < apcm->n_amixer; i++) { - amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]); - apcm->amixers[i] = NULL; - } - kfree(apcm->amixers); - apcm->amixers = NULL; - } - - if (apcm->mono) { - sum_mgr->put_sum(sum_mgr, apcm->mono); - apcm->mono = NULL; - } - - if (apcm->src) { - src_mgr->put_src(src_mgr, apcm->src); - apcm->src = NULL; - } - - if (apcm->vm_block) { - /* Undo device virtual mem map */ - ct_unmap_audio_buffer(atc, apcm); - apcm->vm_block = NULL; - } - - return 0; -} - -static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - unsigned int max_cisz; - struct src *src = apcm->src; - - if (apcm->started) - return 0; - apcm->started = 1; - - max_cisz = src->multi * src->rsc.msr; - max_cisz = 0x80 * (max_cisz < 8 ? max_cisz : 8); - - src->ops->set_sa(src, apcm->vm_block->addr); - src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size); - src->ops->set_ca(src, apcm->vm_block->addr + max_cisz); - src->ops->set_cisz(src, max_cisz); - - src->ops->set_bm(src, 1); - src->ops->set_state(src, SRC_STATE_INIT); - src->ops->commit_write(src); - - ct_timer_start(apcm->timer); - return 0; -} - -static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src *src; - int i; - - ct_timer_stop(apcm->timer); - - src = apcm->src; - src->ops->set_bm(src, 0); - src->ops->set_state(src, SRC_STATE_OFF); - src->ops->commit_write(src); - - if (apcm->srccs) { - for (i = 0; i < apcm->n_srcc; i++) { - src = apcm->srccs[i]; - src->ops->set_bm(src, 0); - src->ops->set_state(src, SRC_STATE_OFF); - src->ops->commit_write(src); - } - } - - apcm->started = 0; - - return 0; -} - -static int -atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src *src = apcm->src; - u32 size, max_cisz; - int position; - - if (!src) - return 0; - position = src->ops->get_ca(src); - - size = apcm->vm_block->size; - max_cisz = src->multi * src->rsc.msr; - max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8); - - return (position + size - max_cisz - apcm->vm_block->addr) % size; -} - -struct src_node_conf_t { - unsigned int pitch; - unsigned int msr:8; - unsigned int mix_msr:8; - unsigned int imp_msr:8; - unsigned int vo:1; -}; - -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; - - /* get pitch and convert to fixed-point 8.24 format. */ - pitch = atc_get_pitch((atc->rsr * atc->msr), - apcm->substream->runtime->rate); - *n_srcc = 0; - - if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */ - *n_srcc = apcm->substream->runtime->channels; - conf[0].pitch = pitch; - conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1; - conf[0].vo = 1; - } else if (2 <= atc->msr) { - if (0x8000000 < pitch) { - /* Need two-stage SRCs, SRCIMPs and - * AMIXERs for converting format */ - conf[0].pitch = (atc->msr << 24); - conf[0].msr = conf[0].mix_msr = 1; - conf[0].imp_msr = atc->msr; - conf[0].vo = 0; - conf[1].pitch = atc_get_pitch(atc->rsr, - apcm->substream->runtime->rate); - conf[1].msr = conf[1].mix_msr = conf[1].imp_msr = 1; - conf[1].vo = 1; - *n_srcc = apcm->substream->runtime->channels * 2; - } else if (0x1000000 < pitch) { - /* Need one-stage SRCs, SRCIMPs and - * AMIXERs for converting format */ - conf[0].pitch = pitch; - conf[0].msr = conf[0].mix_msr - = conf[0].imp_msr = atc->msr; - conf[0].vo = 1; - *n_srcc = apcm->substream->runtime->channels; - } - } -} - -static int -atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src_mgr *src_mgr = atc->rsc_mgrs[SRC]; - 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 src_desc src_dsc = {0}; - struct src *src; - struct srcimp_desc srcimp_dsc = {0}; - struct srcimp *srcimp; - struct amixer_desc mix_dsc = {0}; - struct sum_desc sum_dsc = {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 */ - atc_pcm_release_resources(atc, apcm); - - /* The numbers of converting SRCs and SRCIMPs should be determined - * by pitch value. */ - - multi = apcm->substream->runtime->channels; - - /* get pitch and convert to fixed-point 8.24 format. */ - pitch = atc_get_pitch((atc->rsr * atc->msr), - apcm->substream->runtime->rate); - - 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; - if ((multi > 1) && (0x8000000 >= pitch)) { - /* Need extra AMIXERs and SRCIMPs for special treatment - * of interleaved recording of conjugate channels */ - n_amixer += multi * atc->msr; - n_srcimp += multi * atc->msr; - } else { - n_srcimp += multi; - } - - if (n_srcc) { - apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL); - if (!apcm->srccs) - return -ENOMEM; - } - if (n_amixer) { - apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); - if (!apcm->amixers) { - err = -ENOMEM; - goto error1; - } - } - apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL); - if (!apcm->srcimps) { - err = -ENOMEM; - goto error1; - } - - /* Allocate SRCs for sample rate conversion if needed */ - src_dsc.multi = 1; - src_dsc.mode = ARCRW; - for (i = 0, apcm->n_srcc = 0; i < n_srcc; i++) { - src_dsc.msr = src_node_conf[i/multi].msr; - err = src_mgr->get_src(src_mgr, &src_dsc, - (struct src **)&apcm->srccs[i]); - if (err) - goto error1; - - src = apcm->srccs[i]; - pitch = src_node_conf[i/multi].pitch; - src->ops->set_pitch(src, pitch); - src->ops->set_rom(src, select_rom(pitch)); - src->ops->set_vo(src, src_node_conf[i/multi].vo); - - apcm->n_srcc++; - } - - /* Allocate AMIXERs for routing SRCs of conversion if needed */ - for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) { - if (i < (n_sum*2)) - mix_dsc.msr = atc->msr; - else if (i < (n_sum*2+n_srcc)) - mix_dsc.msr = src_node_conf[(i-n_sum*2)/multi].mix_msr; - else - mix_dsc.msr = 1; - - err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc, - (struct amixer **)&apcm->amixers[i]); - if (err) - goto error1; - - apcm->n_amixer++; - } - - /* Allocate a SUM resource to mix all input channels together */ - sum_dsc.msr = atc->msr; - err = sum_mgr->get_sum(sum_mgr, &sum_dsc, (struct sum **)&apcm->mono); - if (err) - goto error1; - - pitch = atc_get_pitch((atc->rsr * atc->msr), - apcm->substream->runtime->rate); - /* Allocate SRCIMP resources */ - for (i = 0, apcm->n_srcimp = 0; i < n_srcimp; i++) { - if (i < (n_srcc)) - srcimp_dsc.msr = src_node_conf[i/multi].imp_msr; - else if (1 == multi) - srcimp_dsc.msr = (pitch <= 0x8000000) ? atc->msr : 1; - else - srcimp_dsc.msr = 1; - - err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, &srcimp); - if (err) - goto error1; - - apcm->srcimps[i] = srcimp; - apcm->n_srcimp++; - } - - /* Allocate a SRC for writing data to host memory */ - src_dsc.multi = apcm->substream->runtime->channels; - src_dsc.msr = 1; - src_dsc.mode = MEMWR; - err = src_mgr->get_src(src_mgr, &src_dsc, (struct src **)&apcm->src); - if (err) - goto error1; - - src = apcm->src; - src->ops->set_pitch(src, pitch); - - /* Set up device virtual mem map */ - err = ct_map_audio_buffer(atc, apcm); - if (err < 0) - goto error1; - - return 0; - -error1: - atc_pcm_release_resources(atc, apcm); - return err; -} - -static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src *src; - struct amixer *amixer; - struct srcimp *srcimp; - struct ct_mixer *mixer = atc->mixer; - struct sum *mono; - struct rsc *out_ports[8] = {NULL}; - int err, i, j, n_sum, multi; - unsigned int pitch; - int mix_base = 0, imp_base = 0; - - atc_pcm_release_resources(atc, apcm); - - /* Get needed resources. */ - err = atc_pcm_capture_get_resources(atc, apcm); - if (err) - return err; - - /* Connect resources */ - mixer->get_output_ports(mixer, MIX_PCMO_FRONT, - &out_ports[0], &out_ports[1]); - - multi = apcm->substream->runtime->channels; - if (1 == multi) { - mono = apcm->mono; - for (i = 0; i < 2; i++) { - amixer = apcm->amixers[i]; - amixer->ops->setup(amixer, out_ports[i], - MONO_SUM_SCALE, mono); - } - out_ports[0] = &mono->rsc; - n_sum = 1; - mix_base = n_sum * 2; - } - - for (i = 0; i < apcm->n_srcc; i++) { - src = apcm->srccs[i]; - srcimp = apcm->srcimps[imp_base+i]; - amixer = apcm->amixers[mix_base+i]; - srcimp->ops->map(srcimp, src, out_ports[i%multi]); - amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL); - out_ports[i%multi] = &amixer->rsc; - } - - pitch = atc_get_pitch((atc->rsr * atc->msr), - apcm->substream->runtime->rate); - - if ((multi > 1) && (pitch <= 0x8000000)) { - /* Special connection for interleaved - * recording with conjugate channels */ - for (i = 0; i < multi; i++) { - out_ports[i]->ops->master(out_ports[i]); - for (j = 0; j < atc->msr; j++) { - amixer = apcm->amixers[apcm->n_srcc+j*multi+i]; - amixer->ops->set_input(amixer, out_ports[i]); - amixer->ops->set_scale(amixer, INIT_VOL); - amixer->ops->set_sum(amixer, NULL); - amixer->ops->commit_raw_write(amixer); - out_ports[i]->ops->next_conj(out_ports[i]); - - srcimp = apcm->srcimps[apcm->n_srcc+j*multi+i]; - srcimp->ops->map(srcimp, apcm->src, - &amixer->rsc); - } - } - } else { - for (i = 0; i < multi; i++) { - srcimp = apcm->srcimps[apcm->n_srcc+i]; - srcimp->ops->map(srcimp, apcm->src, out_ports[i]); - } - } - - ct_timer_prepare(apcm->timer); - - return 0; -} - -static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src *src; - struct src_mgr *src_mgr = atc->rsc_mgrs[SRC]; - int i, multi; - - if (apcm->started) - return 0; - - apcm->started = 1; - multi = apcm->substream->runtime->channels; - /* Set up converting SRCs */ - for (i = 0; i < apcm->n_srcc; i++) { - src = apcm->srccs[i]; - src->ops->set_pm(src, ((i%multi) != (multi-1))); - src_mgr->src_disable(src_mgr, src); - } - - /* Set up recording SRC */ - src = apcm->src; - src->ops->set_sf(src, convert_format(apcm->substream->runtime->format)); - src->ops->set_sa(src, apcm->vm_block->addr); - src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size); - src->ops->set_ca(src, apcm->vm_block->addr); - src_mgr->src_disable(src_mgr, src); - - /* Disable relevant SRCs firstly */ - src_mgr->commit_write(src_mgr); - - /* Enable SRCs respectively */ - for (i = 0; i < apcm->n_srcc; i++) { - src = apcm->srccs[i]; - src->ops->set_state(src, SRC_STATE_RUN); - src->ops->commit_write(src); - src_mgr->src_enable_s(src_mgr, src); - } - src = apcm->src; - src->ops->set_bm(src, 1); - src->ops->set_state(src, SRC_STATE_RUN); - src->ops->commit_write(src); - src_mgr->src_enable_s(src_mgr, src); - - /* Enable relevant SRCs synchronously */ - src_mgr->commit_write(src_mgr); - - ct_timer_start(apcm->timer); - return 0; -} - -static int -atc_pcm_capture_position(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src *src = apcm->src; - - if (!src) - return 0; - return src->ops->get_ca(src) - apcm->vm_block->addr; -} - -static int spdif_passthru_playback_get_resources(struct ct_atc *atc, - struct ct_atc_pcm *apcm) -{ - struct src_mgr *src_mgr = atc->rsc_mgrs[SRC]; - struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER]; - struct src_desc desc = {0}; - struct amixer_desc mix_dsc = {0}; - 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); - - /* Get SRC resource */ - desc.multi = apcm->substream->runtime->channels; - desc.msr = 1; - while (apcm->substream->runtime->rate > (rsr * desc.msr)) - desc.msr <<= 1; - - desc.mode = MEMRD; - err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src); - if (err) - goto error1; - - pitch = atc_get_pitch(apcm->substream->runtime->rate, (rsr * desc.msr)); - src = apcm->src; - src->ops->set_pitch(src, pitch); - src->ops->set_rom(src, select_rom(pitch)); - src->ops->set_sf(src, convert_format(apcm->substream->runtime->format)); - src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL)); - src->ops->set_bp(src, 1); - - /* Get AMIXER resource */ - n_amixer = (n_amixer < 2) ? 2 : n_amixer; - apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); - if (!apcm->amixers) { - err = -ENOMEM; - goto error1; - } - mix_dsc.msr = desc.msr; - for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) { - err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc, - (struct amixer **)&apcm->amixers[i]); - if (err) - goto error1; - - apcm->n_amixer++; - } - - /* Set up device virtual mem map */ - err = ct_map_audio_buffer(atc, apcm); - if (err < 0) - goto error1; - - return 0; - -error1: - atc_pcm_release_resources(atc, apcm); - 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 int rate = apcm->substream->runtime->rate; - unsigned int status; - int err = 0; - unsigned char iec958_con_fs; - - switch (rate) { - case 48000: - iec958_con_fs = IEC958_AES3_CON_FS_48000; - break; - case 44100: - iec958_con_fs = IEC958_AES3_CON_FS_44100; - break; - case 32000: - iec958_con_fs = IEC958_AES3_CON_FS_32000; - break; - default: - return -ENOENT; - } - - mutex_lock(&atc->atc_mutex); - dao->ops->get_spos(dao, &status); - if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { - status &= ~(IEC958_AES3_CON_FS << 24); - status |= (iec958_con_fs << 24); - dao->ops->set_spos(dao, status); - dao->ops->commit_write(dao); - } - if ((rate != atc->pll_rate) && (32000 != rate)) - err = atc_pll_init(atc, rate); - mutex_unlock(&atc->atc_mutex); - - return err; -} - -static int -spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) -{ - struct src *src; - struct amixer *amixer; - struct dao *dao; - int err; - int i; - - atc_pcm_release_resources(atc, apcm); - - /* Configure SPDIFOO and PLL to passthrough mode; - * determine pll_rate. */ - err = spdif_passthru_playback_setup(atc, apcm); - if (err) - return err; - - /* Get needed resources. */ - err = spdif_passthru_playback_get_resources(atc, apcm); - if (err) - return err; - - /* Connect resources */ - src = apcm->src; - for (i = 0; i < apcm->n_amixer; i++) { - amixer = apcm->amixers[i]; - amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL); - src = src->ops->next_interleave(src); - if (!src) - src = apcm->src; - } - /* Connect to SPDIFOO */ - mutex_lock(&atc->atc_mutex); - dao = container_of(atc->daios[SPDIFOO], struct dao, daio); - amixer = apcm->amixers[0]; - dao->ops->set_left_input(dao, &amixer->rsc); - amixer = apcm->amixers[1]; - dao->ops->set_right_input(dao, &amixer->rsc); - mutex_unlock(&atc->atc_mutex); - - ct_timer_prepare(apcm->timer); - - return 0; -} - -static int atc_select_line_in(struct ct_atc *atc) -{ - struct hw *hw = atc->hw; - struct ct_mixer *mixer = atc->mixer; - struct src *src; - - if (hw->is_adc_source_selected(hw, ADC_LINEIN)) - return 0; - - mixer->set_input_left(mixer, MIX_MIC_IN, NULL); - mixer->set_input_right(mixer, MIX_MIC_IN, NULL); - - hw->select_adc_source(hw, ADC_LINEIN); - - src = atc->srcs[2]; - mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc); - src = atc->srcs[3]; - mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc); - - return 0; -} - -static int atc_select_mic_in(struct ct_atc *atc) -{ - struct hw *hw = atc->hw; - struct ct_mixer *mixer = atc->mixer; - struct src *src; - - if (hw->is_adc_source_selected(hw, ADC_MICIN)) - return 0; - - mixer->set_input_left(mixer, MIX_LINE_IN, NULL); - mixer->set_input_right(mixer, MIX_LINE_IN, NULL); - - hw->select_adc_source(hw, ADC_MICIN); - - src = atc->srcs[2]; - mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc); - src = atc->srcs[3]; - mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc); - - return 0; -} - -static struct capabilities atc_capabilities(struct ct_atc *atc) -{ - struct hw *hw = atc->hw; - - return hw->capabilities(hw); -} - -static int atc_output_switch_get(struct ct_atc *atc) -{ - struct hw *hw = atc->hw; - - return hw->output_switch_get(hw); -} - -static int atc_output_switch_put(struct ct_atc *atc, int position) -{ - struct hw *hw = atc->hw; - - return hw->output_switch_put(hw, position); -} - -static int atc_mic_source_switch_get(struct ct_atc *atc) -{ - struct hw *hw = atc->hw; - - return hw->mic_source_switch_get(hw); -} - -static int atc_mic_source_switch_put(struct ct_atc *atc, int position) -{ - struct hw *hw = atc->hw; - - return hw->mic_source_switch_put(hw, position); -} - -static int atc_select_digit_io(struct ct_atc *atc) -{ - struct hw *hw = atc->hw; - - if (hw->is_adc_source_selected(hw, ADC_NONE)) - return 0; - - hw->select_adc_source(hw, ADC_NONE); - - return 0; -} - -static int atc_daio_unmute(struct ct_atc *atc, unsigned char state, int type) -{ - struct daio_mgr *daio_mgr = atc->rsc_mgrs[DAIO]; - - if (state) - daio_mgr->daio_enable(daio_mgr, atc->daios[type]); - else - daio_mgr->daio_disable(daio_mgr, atc->daios[type]); - - daio_mgr->commit_write(daio_mgr); - - return 0; -} - -static int -atc_dao_get_status(struct ct_atc *atc, unsigned int *status, int type) -{ - struct dao *dao = container_of(atc->daios[type], struct dao, daio); - return dao->ops->get_spos(dao, status); -} - -static int -atc_dao_set_status(struct ct_atc *atc, unsigned int status, int type) -{ - struct dao *dao = container_of(atc->daios[type], struct dao, daio); - - dao->ops->set_spos(dao, status); - dao->ops->commit_write(dao); - return 0; -} - -static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, LINEO1); -} - -static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, LINEO2); -} - -static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, LINEO3); -} - -static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, LINEO4); -} - -static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, LINEIM); -} - -static int atc_mic_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, MIC); -} - -static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, SPDIFOO); -} - -static int atc_spdif_in_unmute(struct ct_atc *atc, unsigned char state) -{ - return atc_daio_unmute(atc, state, SPDIFIO); -} - -static int atc_spdif_out_get_status(struct ct_atc *atc, unsigned int *status) -{ - return atc_dao_get_status(atc, status, SPDIFOO); -} - -static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status) -{ - return atc_dao_set_status(atc, status, SPDIFOO); -} - -static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) -{ - struct dao_desc da_dsc = {0}; - struct dao *dao; - int err; - struct ct_mixer *mixer = atc->mixer; - struct rsc *rscs[2] = {NULL}; - unsigned int spos = 0; - - mutex_lock(&atc->atc_mutex); - dao = container_of(atc->daios[SPDIFOO], struct dao, daio); - da_dsc.msr = state ? 1 : atc->msr; - da_dsc.passthru = state ? 1 : 0; - err = dao->ops->reinit(dao, &da_dsc); - if (state) { - spos = IEC958_DEFAULT_CON; - } else { - mixer->get_output_ports(mixer, MIX_SPDIF_OUT, - &rscs[0], &rscs[1]); - 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 = atc_pll_init(atc, atc->rsr); - } - dao->ops->set_spos(dao, spos); - dao->ops->commit_write(dao); - mutex_unlock(&atc->atc_mutex); - - return err; -} - -static int atc_release_resources(struct ct_atc *atc) -{ - int i; - 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; - - /* disconnect internal mixer objects */ - if (atc->mixer) { - mixer = atc->mixer; - mixer->set_input_left(mixer, MIX_LINE_IN, NULL); - mixer->set_input_right(mixer, MIX_LINE_IN, NULL); - mixer->set_input_left(mixer, MIX_MIC_IN, NULL); - mixer->set_input_right(mixer, MIX_MIC_IN, NULL); - mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL); - mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL); - } - - if (atc->daios) { - daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; - for (i = 0; i < atc->n_daio; i++) { - daio = atc->daios[i]; - if (daio->type < LINEIM) { - dao = container_of(daio, struct dao, daio); - dao->ops->clear_left_input(dao); - dao->ops->clear_right_input(dao); - } else { - dai = container_of(daio, struct dai, daio); - /* some thing to do for dai ... */ - } - daio_mgr->put_daio(daio_mgr, daio); - } - kfree(atc->daios); - atc->daios = NULL; - } - - if (atc->pcm) { - sum_mgr = atc->rsc_mgrs[SUM]; - for (i = 0; i < atc->n_pcm; i++) - sum_mgr->put_sum(sum_mgr, atc->pcm[i]); - - kfree(atc->pcm); - atc->pcm = NULL; - } - - if (atc->srcs) { - src_mgr = atc->rsc_mgrs[SRC]; - for (i = 0; i < atc->n_src; i++) - src_mgr->put_src(src_mgr, atc->srcs[i]); - - kfree(atc->srcs); - atc->srcs = NULL; - } - - if (atc->srcimps) { - srcimp_mgr = atc->rsc_mgrs[SRCIMP]; - for (i = 0; i < atc->n_srcimp; i++) { - srcimp = atc->srcimps[i]; - srcimp->ops->unmap(srcimp); - srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]); - } - kfree(atc->srcimps); - atc->srcimps = NULL; - } - - return 0; -} - -static int ct_atc_destroy(struct ct_atc *atc) -{ - int i = 0; - - if (!atc) - return 0; - - if (atc->timer) { - ct_timer_free(atc->timer); - atc->timer = NULL; - } - - atc_release_resources(atc); - - /* Destroy internal mixer objects */ - if (atc->mixer) - ct_mixer_destroy(atc->mixer); - - for (i = 0; i < NUM_RSCTYP; i++) { - if (rsc_mgr_funcs[i].destroy && atc->rsc_mgrs[i]) - rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]); - - } - - if (atc->hw) - destroy_hw_obj((struct hw *)atc->hw); - - /* Destroy device virtual memory manager object */ - if (atc->vm) { - ct_vm_destroy(atc->vm); - atc->vm = NULL; - } - - kfree(atc); - - return 0; -} - -static int atc_dev_free(struct snd_device *dev) -{ - struct ct_atc *atc = dev->device_data; - return ct_atc_destroy(atc); -} - -static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid) -{ - const struct snd_pci_quirk *p; - const struct snd_pci_quirk *list; - u16 vendor_id, device_id; - - 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; - default: - return -ENOENT; - } - if (ssid) { - vendor_id = ssid >> 16; - device_id = ssid & 0xffff; - } else { - vendor_id = atc->pci->subsystem_vendor; - device_id = atc->pci->subsystem_device; - } - p = snd_pci_quirk_lookup_id(vendor_id, device_id, list); - if (p) { - if (p->value < 0) { - printk(KERN_ERR "ctxfi: " - "Device %04x:%04x is black-listed\n", - vendor_id, device_id); - return -ENOENT; - } - atc->model = p->value; - } else { - if (atc->chip_type == ATC20K1) - atc->model = CT20K1_UNKNOWN; - else - atc->model = CT20K2_UNKNOWN; - } - 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, - vendor_id, device_id); - return 0; -} - -int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc) -{ - enum CTALSADEVS i; - int err; - - alsa_dev_funcs[MIXER].public_name = atc->chip_name; - - for (i = 0; i < NUM_CTALSADEVS; i++) { - if (!alsa_dev_funcs[i].create) - continue; - - err = alsa_dev_funcs[i].create(atc, i, - alsa_dev_funcs[i].public_name); - if (err) { - printk(KERN_ERR "ctxfi: " - "Creating alsa device %d failed!\n", i); - return err; - } - } - - return 0; -} - -static int __devinit atc_create_hw_devs(struct ct_atc *atc) -{ - struct hw *hw; - struct card_conf info = {0}; - int i, err; - - 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; - } - atc->hw = hw; - - /* Initialize card hardware. */ - info.rsr = atc->rsr; - info.msr = atc->msr; - info.vm_pgt_phys = atc_get_ptp_phys(atc, 0); - err = hw->card_init(hw, &info); - if (err < 0) - return err; - - for (i = 0; i < NUM_RSCTYP; i++) { - if (!rsc_mgr_funcs[i].create) - continue; - - err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]); - if (err) { - printk(KERN_ERR "ctxfi: " - "Failed to create rsc_mgr %d!!!\n", i); - return err; - } - } - - return 0; -} - -static int atc_get_resources(struct ct_atc *atc) -{ - struct daio_desc da_desc = {0}; - struct daio_mgr *daio_mgr; - struct src_desc src_dsc = {0}; - struct src_mgr *src_mgr; - struct srcimp_desc srcimp_dsc = {0}; - struct srcimp_mgr *srcimp_mgr; - struct sum_desc sum_dsc = {0}; - struct sum_mgr *sum_mgr; - int err, i, num_srcs, num_daios; - - num_daios = ((atc->model == CTSB1270) ? 8 : 7); - num_srcs = ((atc->model == CTSB1270) ? 6 : 4); - - atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL); - if (!atc->daios) - return -ENOMEM; - - atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); - if (!atc->srcs) - return -ENOMEM; - - atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL); - if (!atc->srcimps) - return -ENOMEM; - - atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL); - if (!atc->pcm) - return -ENOMEM; - - daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; - da_desc.msr = atc->msr; - for (i = 0, atc->n_daio = 0; i < num_daios; i++) { - da_desc.type = (atc->model != CTSB073X) ? i : - ((i == SPDIFIO) ? SPDIFI1 : i); - err = daio_mgr->get_daio(daio_mgr, &da_desc, - (struct daio **)&atc->daios[i]); - if (err) { - printk(KERN_ERR "ctxfi: Failed to get DAIO " - "resource %d!!!\n", i); - return err; - } - atc->n_daio++; - } - - src_mgr = atc->rsc_mgrs[SRC]; - src_dsc.multi = 1; - src_dsc.msr = atc->msr; - src_dsc.mode = ARCRW; - for (i = 0, atc->n_src = 0; i < num_srcs; i++) { - err = src_mgr->get_src(src_mgr, &src_dsc, - (struct src **)&atc->srcs[i]); - if (err) - return err; - - atc->n_src++; - } - - srcimp_mgr = atc->rsc_mgrs[SRCIMP]; - srcimp_dsc.msr = 8; - for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) { - err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, - (struct srcimp **)&atc->srcimps[i]); - if (err) - return err; - - atc->n_srcimp++; - } - - sum_mgr = atc->rsc_mgrs[SUM]; - sum_dsc.msr = atc->msr; - for (i = 0, atc->n_pcm = 0; i < (2*4); i++) { - err = sum_mgr->get_sum(sum_mgr, &sum_dsc, - (struct sum **)&atc->pcm[i]); - if (err) - return err; - - atc->n_pcm++; - } - - return 0; -} - -static void -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; - struct srcimp *srcimp; - int i = 0; - - rscs[0] = &dai->daio.rscl; - rscs[1] = &dai->daio.rscr; - for (i = 0; i < 2; i++) { - src = srcs[i]; - srcimp = srcimps[i]; - srcimp->ops->map(srcimp, src, rscs[i]); - src_mgr->src_disable(src_mgr, src); - } - - src_mgr->commit_write(src_mgr); /* Actually disable SRCs */ - - src = srcs[0]; - src->ops->set_pm(src, 1); - for (i = 0; i < 2; i++) { - src = srcs[i]; - src->ops->set_state(src, SRC_STATE_RUN); - src->ops->commit_write(src); - src_mgr->src_enable_s(src_mgr, src); - } - - dai->ops->set_srt_srcl(dai, &(srcs[0]->rsc)); - dai->ops->set_srt_srcr(dai, &(srcs[1]->rsc)); - - dai->ops->set_enb_src(dai, 1); - dai->ops->set_enb_srt(dai, 1); - dai->ops->commit_write(dai); - - src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */ -} - -static void atc_connect_resources(struct ct_atc *atc) -{ - struct dai *dai; - struct dao *dao; - struct src *src; - struct sum *sum; - struct ct_mixer *mixer; - struct rsc *rscs[2] = {NULL}; - int i, j; - - mixer = atc->mixer; - - for (i = MIX_WAVE_FRONT, j = LINEO1; i <= MIX_SPDIF_OUT; i++, j++) { - mixer->get_output_ports(mixer, i, &rscs[0], &rscs[1]); - dao = container_of(atc->daios[j], struct dao, daio); - dao->ops->set_left_input(dao, rscs[0]); - dao->ops->set_right_input(dao, rscs[1]); - } - - dai = container_of(atc->daios[LINEIM], struct dai, daio); - atc_connect_dai(atc->rsc_mgrs[SRC], dai, - (struct src **)&atc->srcs[2], - (struct srcimp **)&atc->srcimps[2]); - src = atc->srcs[2]; - mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc); - src = atc->srcs[3]; - mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc); - - if (atc->model == CTSB1270) { - /* Titanium HD has a dedicated ADC for the Mic. */ - dai = container_of(atc->daios[MIC], struct dai, daio); - atc_connect_dai(atc->rsc_mgrs[SRC], dai, - (struct src **)&atc->srcs[4], - (struct srcimp **)&atc->srcimps[4]); - src = atc->srcs[4]; - mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc); - src = atc->srcs[5]; - mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc); - } - - dai = container_of(atc->daios[SPDIFIO], struct dai, daio); - atc_connect_dai(atc->rsc_mgrs[SRC], dai, - (struct src **)&atc->srcs[0], - (struct srcimp **)&atc->srcimps[0]); - - src = atc->srcs[0]; - mixer->set_input_left(mixer, MIX_SPDIF_IN, &src->rsc); - src = atc->srcs[1]; - mixer->set_input_right(mixer, MIX_SPDIF_IN, &src->rsc); - - for (i = MIX_PCMI_FRONT, j = 0; i <= MIX_PCMI_SURROUND; i++, j += 2) { - sum = atc->pcm[j]; - mixer->set_input_left(mixer, i, &sum->rsc); - sum = atc->pcm[j+1]; - mixer->set_input_right(mixer, i, &sum->rsc); - } -} - -#ifdef CONFIG_PM -static int atc_suspend(struct ct_atc *atc, pm_message_t state) -{ - int i; - struct hw *hw = atc->hw; - - snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot); - - for (i = FRONT; i < NUM_PCMS; i++) { - if (!atc->pcms[i]) - continue; - - snd_pcm_suspend_all(atc->pcms[i]); - } - - atc_release_resources(atc); - - hw->suspend(hw, state); - - return 0; -} - -static int atc_hw_resume(struct ct_atc *atc) -{ - struct hw *hw = atc->hw; - struct card_conf info = {0}; - - /* Re-initialize card hardware. */ - info.rsr = atc->rsr; - info.msr = atc->msr; - info.vm_pgt_phys = atc_get_ptp_phys(atc, 0); - return hw->resume(hw, &info); -} - -static int atc_resources_resume(struct ct_atc *atc) -{ - struct ct_mixer *mixer; - int err = 0; - - /* Get resources */ - err = atc_get_resources(atc); - if (err < 0) { - atc_release_resources(atc); - return err; - } - - /* Build topology */ - atc_connect_resources(atc); - - mixer = atc->mixer; - mixer->resume(mixer); - - return 0; -} - -static int atc_resume(struct ct_atc *atc) -{ - int err = 0; - - /* Do hardware resume. */ - err = atc_hw_resume(atc); - if (err < 0) { - printk(KERN_ERR "ctxfi: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(atc->card); - return err; - } - - err = atc_resources_resume(atc); - if (err < 0) - return err; - - snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0); - - return 0; -} -#endif - -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, - .mic_unmute = atc_mic_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, - .capabilities = atc_capabilities, - .output_switch_get = atc_output_switch_get, - .output_switch_put = atc_output_switch_put, - .mic_source_switch_get = atc_mic_source_switch_get, - .mic_source_switch_put = atc_mic_source_switch_put, -#ifdef CONFIG_PM - .suspend = atc_suspend, - .resume = atc_resume, -#endif -}; - -/** - * ct_atc_create - create and initialize a hardware manager - * @card: corresponding alsa card object - * @pci: corresponding kernel pci device object - * @ratc: return created object address in it - * - * Creates and initializes a hardware manager. - * - * Creates kmallocated ct_atc structure. Initializes hardware. - * Returns 0 if succeeds, or negative error code if fails. - */ - -int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, - unsigned int rsr, unsigned int msr, - int chip_type, unsigned int ssid, - struct ct_atc **ratc) -{ - struct ct_atc *atc; - static struct snd_device_ops ops = { - .dev_free = atc_dev_free, - }; - int err; - - *ratc = NULL; - - atc = kzalloc(sizeof(*atc), GFP_KERNEL); - if (!atc) - return -ENOMEM; - - /* Set operations */ - *atc = atc_preset; - - atc->card = card; - atc->pci = pci; - atc->rsr = rsr; - atc->msr = msr; - atc->chip_type = chip_type; - - mutex_init(&atc->atc_mutex); - - /* Find card model */ - err = atc_identify_card(atc, ssid); - if (err < 0) { - printk(KERN_ERR "ctatc: Card not recognised\n"); - goto error1; - } - - /* Set up device virtual memory management object */ - err = ct_vm_create(&atc->vm, pci); - if (err < 0) - goto error1; - - /* Create all atc hw devices */ - err = atc_create_hw_devs(atc); - if (err < 0) - goto error1; - - err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer); - if (err) { - printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n"); - goto error1; - } - - /* Get resources */ - err = atc_get_resources(atc); - if (err < 0) - goto error1; - - /* Build topology */ - atc_connect_resources(atc); - - atc->timer = ct_timer_new(atc); - if (!atc->timer) - goto error1; - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); - if (err < 0) - goto error1; - - snd_card_set_dev(card, &pci->dev); - - *ratc = atc; - return 0; - -error1: - ct_atc_destroy(atc); - printk(KERN_ERR "ctxfi: Something wrong!!!\n"); - return err; -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.h deleted file mode 100644 index 3a0def65..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - * 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 ctatc.h - * - * @Brief - * This file contains the definition of the device resource management object. - * - * @Author Liu Chun - * @Date Mar 28 2008 - * - */ - -#ifndef CTATC_H -#define CTATC_H - -#include <linux/types.h> -#include <linux/mutex.h> -#include <linux/pci.h> -#include <linux/timer.h> -#include <sound/core.h> - -#include "ctvmem.h" -#include "cthardware.h" -#include "ctresource.h" - -enum CTALSADEVS { /* Types of alsa devices */ - FRONT, - SURROUND, - CLFE, - SIDE, - IEC958, - MIXER, - NUM_CTALSADEVS /* This should always be the last */ -}; - -struct ct_atc_chip_sub_details { - u16 subsys; - const char *nm_model; -}; - -struct ct_atc_chip_details { - u16 vendor; - u16 device; - const struct ct_atc_chip_sub_details *sub_details; - const char *nm_card; -}; - -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; - - /* Only mono and interleaved modes are supported now. */ - struct ct_vm_block *vm_block; - void *src; /* SRC for interacting with host memory */ - void **srccs; /* SRCs for sample rate conversion */ - void **srcimps; /* SRC Input Mappers */ - void **amixers; /* AMIXERs for routing converted data */ - void *mono; /* A SUM resource for mixing chs to one */ - unsigned char n_srcc; /* Number of converting SRCs */ - unsigned char n_srcimp; /* Number of SRC Input Mappers */ - unsigned char n_amixer; /* Number of AMIXERs */ -}; - -/* Chip resource management object */ -struct ct_atc { - struct pci_dev *pci; - struct snd_card *card; - unsigned int rsr; /* reference sample rate in Hz */ - unsigned int msr; /* master sample rate in rsr */ - unsigned int pll_rate; /* current rate of Phase Lock Loop */ - - 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); - void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); - unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); - - struct mutex atc_mutex; - - int (*pcm_playback_prepare)(struct ct_atc *atc, - struct ct_atc_pcm *apcm); - int (*pcm_playback_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm); - int (*pcm_playback_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm); - int (*pcm_playback_position)(struct ct_atc *atc, - struct ct_atc_pcm *apcm); - int (*spdif_passthru_playback_prepare)(struct ct_atc *atc, - struct ct_atc_pcm *apcm); - int (*pcm_capture_prepare)(struct ct_atc *atc, struct ct_atc_pcm *apcm); - int (*pcm_capture_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm); - int (*pcm_capture_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm); - int (*pcm_capture_position)(struct ct_atc *atc, - struct ct_atc_pcm *apcm); - int (*pcm_release_resources)(struct ct_atc *atc, - struct ct_atc_pcm *apcm); - int (*select_line_in)(struct ct_atc *atc); - int (*select_mic_in)(struct ct_atc *atc); - int (*select_digit_io)(struct ct_atc *atc); - int (*line_front_unmute)(struct ct_atc *atc, unsigned char state); - int (*line_surround_unmute)(struct ct_atc *atc, unsigned char state); - int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state); - int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state); - int (*line_in_unmute)(struct ct_atc *atc, unsigned char state); - int (*mic_unmute)(struct ct_atc *atc, unsigned char state); - int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state); - int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state); - int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status); - int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status); - int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state); - struct capabilities (*capabilities)(struct ct_atc *atc); - int (*output_switch_get)(struct ct_atc *atc); - int (*output_switch_put)(struct ct_atc *atc, int position); - int (*mic_source_switch_get)(struct ct_atc *atc); - int (*mic_source_switch_put)(struct ct_atc *atc, int position); - - /* Don't touch! Used for internal object. */ - void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */ - void *mixer; /* internal mixer object */ - void *hw; /* chip specific hardware access object */ - void **daios; /* digital audio io resources */ - void **pcm; /* SUMs for collecting all pcm stream */ - void **srcs; /* Sample Rate Converters for input signal */ - void **srcimps; /* input mappers for SRCs */ - unsigned char n_daio; - unsigned char n_src; - unsigned char n_srcimp; - unsigned char n_pcm; - - struct ct_timer *timer; - -#ifdef CONFIG_PM - int (*suspend)(struct ct_atc *atc, pm_message_t state); - int (*resume)(struct ct_atc *atc); -#define NUM_PCMS (NUM_CTALSADEVS - 1) - struct snd_pcm *pcms[NUM_PCMS]; -#endif -}; - - -int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, - unsigned int rsr, unsigned int msr, int chip_type, - unsigned int subsysid, struct ct_atc **ratc); -int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc); - -#endif /* CTATC_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.c deleted file mode 100644 index 0c00eb40..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.c +++ /dev/null @@ -1,762 +0,0 @@ -/** - * 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 ctdaio.c - * - * @Brief - * This file contains the implementation of Digital Audio Input Output - * resource management object. - * - * @Author Liu Chun - * @Date May 23 2008 - * - */ - -#include "ctdaio.h" -#include "cthardware.h" -#include "ctimap.h" -#include <linux/slab.h> -#include <linux/kernel.h> - -#define DAIO_OUT_MAX SPDIFOO - -struct daio_usage { - unsigned short data; -}; - -struct daio_rsc_idx { - unsigned short left; - unsigned short right; -}; - -struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = { - [LINEO1] = {.left = 0x00, .right = 0x01}, - [LINEO2] = {.left = 0x18, .right = 0x19}, - [LINEO3] = {.left = 0x08, .right = 0x09}, - [LINEO4] = {.left = 0x10, .right = 0x11}, - [LINEIM] = {.left = 0x1b5, .right = 0x1bd}, - [SPDIFOO] = {.left = 0x20, .right = 0x21}, - [SPDIFIO] = {.left = 0x15, .right = 0x1d}, - [SPDIFI1] = {.left = 0x95, .right = 0x9d}, -}; - -struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = { - [LINEO1] = {.left = 0x40, .right = 0x41}, - [LINEO2] = {.left = 0x60, .right = 0x61}, - [LINEO3] = {.left = 0x50, .right = 0x51}, - [LINEO4] = {.left = 0x70, .right = 0x71}, - [LINEIM] = {.left = 0x45, .right = 0xc5}, - [MIC] = {.left = 0x55, .right = 0xd5}, - [SPDIFOO] = {.left = 0x00, .right = 0x01}, - [SPDIFIO] = {.left = 0x05, .right = 0x85}, -}; - -static int daio_master(struct rsc *rsc) -{ - /* Actually, this is not the resource index of DAIO. - * For DAO, it is the input mapper index. And, for DAI, - * it is the output time-slot index. */ - return rsc->conj = rsc->idx; -} - -static int daio_index(const struct rsc *rsc) -{ - return rsc->conj; -} - -static int daio_out_next_conj(struct rsc *rsc) -{ - return rsc->conj += 2; -} - -static int daio_in_next_conj_20k1(struct rsc *rsc) -{ - return rsc->conj += 0x200; -} - -static int daio_in_next_conj_20k2(struct rsc *rsc) -{ - return rsc->conj += 0x100; -} - -static struct rsc_ops daio_out_rsc_ops = { - .master = daio_master, - .next_conj = daio_out_next_conj, - .index = daio_index, - .output_slot = NULL, -}; - -static struct rsc_ops daio_in_rsc_ops_20k1 = { - .master = daio_master, - .next_conj = daio_in_next_conj_20k1, - .index = NULL, - .output_slot = daio_index, -}; - -static struct rsc_ops daio_in_rsc_ops_20k2 = { - .master = daio_master, - .next_conj = daio_in_next_conj_20k2, - .index = NULL, - .output_slot = daio_index, -}; - -static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw) -{ - switch (hw->chip_type) { - case ATC20K1: - switch (type) { - case SPDIFOO: return 0; - case SPDIFIO: return 0; - case SPDIFI1: return 1; - case LINEO1: return 4; - case LINEO2: return 7; - case LINEO3: return 5; - case LINEO4: return 6; - case LINEIM: return 7; - default: return -EINVAL; - } - case ATC20K2: - switch (type) { - case SPDIFOO: return 0; - case SPDIFIO: return 0; - case LINEO1: return 4; - case LINEO2: return 7; - case LINEO3: return 5; - case LINEO4: return 6; - case LINEIM: return 4; - case MIC: return 5; - default: return -EINVAL; - } - default: - return -EINVAL; - } -} - -static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc); - -static int dao_spdif_get_spos(struct dao *dao, unsigned int *spos) -{ - ((struct hw *)dao->hw)->dao_get_spos(dao->ctrl_blk, spos); - return 0; -} - -static int dao_spdif_set_spos(struct dao *dao, unsigned int spos) -{ - ((struct hw *)dao->hw)->dao_set_spos(dao->ctrl_blk, spos); - return 0; -} - -static int dao_commit_write(struct dao *dao) -{ - ((struct hw *)dao->hw)->dao_commit_write(dao->hw, - daio_device_index(dao->daio.type, dao->hw), dao->ctrl_blk); - return 0; -} - -static int dao_set_left_input(struct dao *dao, struct rsc *input) -{ - struct imapper *entry; - struct daio *daio = &dao->daio; - int i; - - entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - dao->ops->clear_left_input(dao); - /* Program master and conjugate resources */ - input->ops->master(input); - daio->rscl.ops->master(&daio->rscl); - for (i = 0; i < daio->rscl.msr; i++, entry++) { - entry->slot = input->ops->output_slot(input); - entry->user = entry->addr = daio->rscl.ops->index(&daio->rscl); - dao->mgr->imap_add(dao->mgr, entry); - dao->imappers[i] = entry; - - input->ops->next_conj(input); - daio->rscl.ops->next_conj(&daio->rscl); - } - input->ops->master(input); - daio->rscl.ops->master(&daio->rscl); - - return 0; -} - -static int dao_set_right_input(struct dao *dao, struct rsc *input) -{ - struct imapper *entry; - struct daio *daio = &dao->daio; - int i; - - entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - dao->ops->clear_right_input(dao); - /* Program master and conjugate resources */ - input->ops->master(input); - daio->rscr.ops->master(&daio->rscr); - for (i = 0; i < daio->rscr.msr; i++, entry++) { - entry->slot = input->ops->output_slot(input); - entry->user = entry->addr = daio->rscr.ops->index(&daio->rscr); - dao->mgr->imap_add(dao->mgr, entry); - dao->imappers[daio->rscl.msr + i] = entry; - - input->ops->next_conj(input); - daio->rscr.ops->next_conj(&daio->rscr); - } - input->ops->master(input); - daio->rscr.ops->master(&daio->rscr); - - return 0; -} - -static int dao_clear_left_input(struct dao *dao) -{ - struct imapper *entry; - struct daio *daio = &dao->daio; - int i; - - if (!dao->imappers[0]) - return 0; - - entry = dao->imappers[0]; - dao->mgr->imap_delete(dao->mgr, entry); - /* Program conjugate resources */ - for (i = 1; i < daio->rscl.msr; i++) { - entry = dao->imappers[i]; - dao->mgr->imap_delete(dao->mgr, entry); - dao->imappers[i] = NULL; - } - - kfree(dao->imappers[0]); - dao->imappers[0] = NULL; - - return 0; -} - -static int dao_clear_right_input(struct dao *dao) -{ - struct imapper *entry; - struct daio *daio = &dao->daio; - int i; - - if (!dao->imappers[daio->rscl.msr]) - return 0; - - entry = dao->imappers[daio->rscl.msr]; - dao->mgr->imap_delete(dao->mgr, entry); - /* Program conjugate resources */ - for (i = 1; i < daio->rscr.msr; i++) { - entry = dao->imappers[daio->rscl.msr + i]; - dao->mgr->imap_delete(dao->mgr, entry); - dao->imappers[daio->rscl.msr + i] = NULL; - } - - kfree(dao->imappers[daio->rscl.msr]); - dao->imappers[daio->rscl.msr] = NULL; - - return 0; -} - -static struct dao_rsc_ops dao_ops = { - .set_spos = dao_spdif_set_spos, - .commit_write = dao_commit_write, - .get_spos = dao_spdif_get_spos, - .reinit = dao_rsc_reinit, - .set_left_input = dao_set_left_input, - .set_right_input = dao_set_right_input, - .clear_left_input = dao_clear_left_input, - .clear_right_input = dao_clear_right_input, -}; - -static int dai_set_srt_srcl(struct dai *dai, struct rsc *src) -{ - src->ops->master(src); - ((struct hw *)dai->hw)->dai_srt_set_srcm(dai->ctrl_blk, - src->ops->index(src)); - return 0; -} - -static int dai_set_srt_srcr(struct dai *dai, struct rsc *src) -{ - src->ops->master(src); - ((struct hw *)dai->hw)->dai_srt_set_srco(dai->ctrl_blk, - src->ops->index(src)); - return 0; -} - -static int dai_set_srt_msr(struct dai *dai, unsigned int msr) -{ - unsigned int rsr; - - for (rsr = 0; msr > 1; msr >>= 1) - rsr++; - - ((struct hw *)dai->hw)->dai_srt_set_rsr(dai->ctrl_blk, rsr); - return 0; -} - -static int dai_set_enb_src(struct dai *dai, unsigned int enb) -{ - ((struct hw *)dai->hw)->dai_srt_set_ec(dai->ctrl_blk, enb); - return 0; -} - -static int dai_set_enb_srt(struct dai *dai, unsigned int enb) -{ - ((struct hw *)dai->hw)->dai_srt_set_et(dai->ctrl_blk, enb); - return 0; -} - -static int dai_commit_write(struct dai *dai) -{ - ((struct hw *)dai->hw)->dai_commit_write(dai->hw, - daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk); - return 0; -} - -static struct dai_rsc_ops dai_ops = { - .set_srt_srcl = dai_set_srt_srcl, - .set_srt_srcr = dai_set_srt_srcr, - .set_srt_msr = dai_set_srt_msr, - .set_enb_src = dai_set_enb_src, - .set_enb_srt = dai_set_enb_srt, - .commit_write = dai_commit_write, -}; - -static int daio_rsc_init(struct daio *daio, - const struct daio_desc *desc, - void *hw) -{ - int err; - unsigned int idx_l, idx_r; - - switch (((struct hw *)hw)->chip_type) { - case ATC20K1: - idx_l = idx_20k1[desc->type].left; - idx_r = idx_20k1[desc->type].right; - break; - case ATC20K2: - idx_l = idx_20k2[desc->type].left; - idx_r = idx_20k2[desc->type].right; - break; - default: - return -EINVAL; - } - err = rsc_init(&daio->rscl, idx_l, DAIO, desc->msr, hw); - if (err) - return err; - - err = rsc_init(&daio->rscr, idx_r, DAIO, desc->msr, hw); - if (err) - goto error1; - - /* Set daio->rscl/r->ops to daio specific ones */ - if (desc->type <= DAIO_OUT_MAX) { - daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops; - } else { - switch (((struct hw *)hw)->chip_type) { - case ATC20K1: - daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1; - break; - case ATC20K2: - daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k2; - break; - default: - break; - } - } - daio->type = desc->type; - - return 0; - -error1: - rsc_uninit(&daio->rscl); - return err; -} - -static int daio_rsc_uninit(struct daio *daio) -{ - rsc_uninit(&daio->rscl); - rsc_uninit(&daio->rscr); - - return 0; -} - -static int dao_rsc_init(struct dao *dao, - const struct daio_desc *desc, - struct daio_mgr *mgr) -{ - struct hw *hw = mgr->mgr.hw; - unsigned int conf; - int err; - - err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw); - if (err) - return err; - - dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL); - if (!dao->imappers) { - err = -ENOMEM; - goto error1; - } - dao->ops = &dao_ops; - dao->mgr = mgr; - dao->hw = hw; - err = hw->dao_get_ctrl_blk(&dao->ctrl_blk); - if (err) - goto error2; - - hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, - daio_device_index(dao->daio.type, hw)); - hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); - - 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, - daio_device_index(dao->daio.type, hw)); - hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); - - return 0; - -error2: - kfree(dao->imappers); - dao->imappers = NULL; -error1: - daio_rsc_uninit(&dao->daio); - return err; -} - -static int dao_rsc_uninit(struct dao *dao) -{ - if (dao->imappers) { - if (dao->imappers[0]) - dao_clear_left_input(dao); - - if (dao->imappers[dao->daio.rscl.msr]) - dao_clear_right_input(dao); - - kfree(dao->imappers); - dao->imappers = NULL; - } - ((struct hw *)dao->hw)->dao_put_ctrl_blk(dao->ctrl_blk); - dao->hw = dao->ctrl_blk = NULL; - daio_rsc_uninit(&dao->daio); - - return 0; -} - -static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc) -{ - struct daio_mgr *mgr = dao->mgr; - struct daio_desc dsc = {0}; - - dsc.type = dao->daio.type; - dsc.msr = desc->msr; - dsc.passthru = desc->passthru; - dao_rsc_uninit(dao); - return dao_rsc_init(dao, &dsc, mgr); -} - -static int dai_rsc_init(struct dai *dai, - const struct daio_desc *desc, - struct daio_mgr *mgr) -{ - int err; - struct hw *hw = mgr->mgr.hw; - unsigned int rsr, msr; - - err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw); - if (err) - return err; - - dai->ops = &dai_ops; - dai->hw = mgr->mgr.hw; - err = hw->dai_get_ctrl_blk(&dai->ctrl_blk); - if (err) - goto error1; - - for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1) - rsr++; - - hw->dai_srt_set_rsr(dai->ctrl_blk, rsr); - hw->dai_srt_set_drat(dai->ctrl_blk, 0); - /* default to disabling control of a SRC */ - hw->dai_srt_set_ec(dai->ctrl_blk, 0); - hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */ - hw->dai_commit_write(hw, - daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk); - - return 0; - -error1: - daio_rsc_uninit(&dai->daio); - return err; -} - -static int dai_rsc_uninit(struct dai *dai) -{ - ((struct hw *)dai->hw)->dai_put_ctrl_blk(dai->ctrl_blk); - dai->hw = dai->ctrl_blk = NULL; - daio_rsc_uninit(&dai->daio); - return 0; -} - -static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type) -{ - if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type)) - return -ENOENT; - - ((struct daio_usage *)mgr->rscs)->data |= (0x1 << type); - - return 0; -} - -static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type) -{ - ((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type); - - return 0; -} - -static int get_daio_rsc(struct daio_mgr *mgr, - const struct daio_desc *desc, - struct daio **rdaio) -{ - int err; - struct dai *dai = NULL; - struct dao *dao = NULL; - unsigned long flags; - - *rdaio = NULL; - - /* Check whether there are sufficient daio resources to meet request. */ - spin_lock_irqsave(&mgr->mgr_lock, flags); - err = daio_mgr_get_rsc(&mgr->mgr, desc->type); - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - if (err) { - printk(KERN_ERR "Can't meet DAIO resource request!\n"); - return err; - } - - /* Allocate mem for daio resource */ - if (desc->type <= DAIO_OUT_MAX) { - dao = kzalloc(sizeof(*dao), GFP_KERNEL); - if (!dao) { - err = -ENOMEM; - goto error; - } - err = dao_rsc_init(dao, desc, mgr); - if (err) - goto error; - - *rdaio = &dao->daio; - } else { - dai = kzalloc(sizeof(*dai), GFP_KERNEL); - if (!dai) { - err = -ENOMEM; - goto error; - } - err = dai_rsc_init(dai, desc, mgr); - if (err) - goto error; - - *rdaio = &dai->daio; - } - - mgr->daio_enable(mgr, *rdaio); - mgr->commit_write(mgr); - - return 0; - -error: - if (dao) - kfree(dao); - else if (dai) - kfree(dai); - - spin_lock_irqsave(&mgr->mgr_lock, flags); - daio_mgr_put_rsc(&mgr->mgr, desc->type); - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - return err; -} - -static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio) -{ - unsigned long flags; - - mgr->daio_disable(mgr, daio); - mgr->commit_write(mgr); - - spin_lock_irqsave(&mgr->mgr_lock, flags); - daio_mgr_put_rsc(&mgr->mgr, daio->type); - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - - if (daio->type <= DAIO_OUT_MAX) { - dao_rsc_uninit(container_of(daio, struct dao, daio)); - kfree(container_of(daio, struct dao, daio)); - } else { - dai_rsc_uninit(container_of(daio, struct dai, daio)); - kfree(container_of(daio, struct dai, daio)); - } - - return 0; -} - -static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio) -{ - struct hw *hw = mgr->mgr.hw; - - if (DAIO_OUT_MAX >= daio->type) { - hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, - daio_device_index(daio->type, hw)); - } else { - hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk, - daio_device_index(daio->type, hw)); - } - return 0; -} - -static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio) -{ - struct hw *hw = mgr->mgr.hw; - - if (DAIO_OUT_MAX >= daio->type) { - hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, - daio_device_index(daio->type, hw)); - } else { - hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk, - daio_device_index(daio->type, hw)); - } - return 0; -} - -static int daio_map_op(void *data, struct imapper *entry) -{ - struct rsc_mgr *mgr = &((struct daio_mgr *)data)->mgr; - struct hw *hw = mgr->hw; - - hw->daio_mgr_set_imaparc(mgr->ctrl_blk, entry->slot); - hw->daio_mgr_set_imapnxt(mgr->ctrl_blk, entry->next); - hw->daio_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr); - hw->daio_mgr_commit_write(mgr->hw, mgr->ctrl_blk); - - return 0; -} - -static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry) -{ - unsigned long flags; - int err; - - spin_lock_irqsave(&mgr->imap_lock, flags); - if (!entry->addr && mgr->init_imap_added) { - input_mapper_delete(&mgr->imappers, mgr->init_imap, - daio_map_op, mgr); - mgr->init_imap_added = 0; - } - err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr); - spin_unlock_irqrestore(&mgr->imap_lock, flags); - - return err; -} - -static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry) -{ - unsigned long flags; - int err; - - spin_lock_irqsave(&mgr->imap_lock, flags); - err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr); - if (list_empty(&mgr->imappers)) { - input_mapper_add(&mgr->imappers, mgr->init_imap, - daio_map_op, mgr); - mgr->init_imap_added = 1; - } - spin_unlock_irqrestore(&mgr->imap_lock, flags); - - return err; -} - -static int daio_mgr_commit_write(struct daio_mgr *mgr) -{ - struct hw *hw = mgr->mgr.hw; - - hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); - return 0; -} - -int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr) -{ - int err, i; - struct daio_mgr *daio_mgr; - struct imapper *entry; - - *rdaio_mgr = NULL; - daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL); - if (!daio_mgr) - return -ENOMEM; - - err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw); - if (err) - goto error1; - - spin_lock_init(&daio_mgr->mgr_lock); - spin_lock_init(&daio_mgr->imap_lock); - INIT_LIST_HEAD(&daio_mgr->imappers); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) { - err = -ENOMEM; - goto error2; - } - entry->slot = entry->addr = entry->next = entry->user = 0; - list_add(&entry->list, &daio_mgr->imappers); - daio_mgr->init_imap = entry; - daio_mgr->init_imap_added = 1; - - daio_mgr->get_daio = get_daio_rsc; - daio_mgr->put_daio = put_daio_rsc; - daio_mgr->daio_enable = daio_mgr_enb_daio; - daio_mgr->daio_disable = daio_mgr_dsb_daio; - daio_mgr->imap_add = daio_imap_add; - daio_mgr->imap_delete = daio_imap_delete; - daio_mgr->commit_write = daio_mgr_commit_write; - - for (i = 0; i < 8; i++) { - ((struct hw *)hw)->daio_mgr_dsb_dao(daio_mgr->mgr.ctrl_blk, i); - ((struct hw *)hw)->daio_mgr_dsb_dai(daio_mgr->mgr.ctrl_blk, i); - } - ((struct hw *)hw)->daio_mgr_commit_write(hw, daio_mgr->mgr.ctrl_blk); - - *rdaio_mgr = daio_mgr; - - return 0; - -error2: - rsc_mgr_uninit(&daio_mgr->mgr); -error1: - kfree(daio_mgr); - return err; -} - -int daio_mgr_destroy(struct daio_mgr *daio_mgr) -{ - unsigned long flags; - - /* free daio input mapper list */ - spin_lock_irqsave(&daio_mgr->imap_lock, flags); - free_input_mapper_list(&daio_mgr->imappers); - spin_unlock_irqrestore(&daio_mgr->imap_lock, flags); - - rsc_mgr_uninit(&daio_mgr->mgr); - kfree(daio_mgr); - - return 0; -} - diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.h deleted file mode 100644 index 85ccb6ee..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * 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 ctdaio.h - * - * @Brief - * This file contains the definition of Digital Audio Input Output - * resource management object. - * - * @Author Liu Chun - * @Date May 23 2008 - * - */ - -#ifndef CTDAIO_H -#define CTDAIO_H - -#include "ctresource.h" -#include "ctimap.h" -#include <linux/spinlock.h> -#include <linux/list.h> - -/* Define the descriptor of a daio resource */ -enum DAIOTYP { - LINEO1, - LINEO2, - LINEO3, - LINEO4, - SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */ - LINEIM, - SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */ - MIC, /* Dedicated mic on Titanium HD */ - SPDIFI1, /* S/PDIF In on internal Drive Bay */ - NUM_DAIOTYP -}; - -struct dao_rsc_ops; -struct dai_rsc_ops; -struct daio_mgr; - -struct daio { - struct rsc rscl; /* Basic resource info for left TX/RX */ - struct rsc rscr; /* Basic resource info for right TX/RX */ - enum DAIOTYP type; -}; - -struct dao { - struct daio daio; - struct dao_rsc_ops *ops; /* DAO specific operations */ - struct imapper **imappers; - struct daio_mgr *mgr; - void *hw; - void *ctrl_blk; -}; - -struct dai { - struct daio daio; - struct dai_rsc_ops *ops; /* DAI specific operations */ - void *hw; - void *ctrl_blk; -}; - -struct dao_desc { - unsigned int msr:4; - unsigned int passthru:1; -}; - -struct dao_rsc_ops { - int (*set_spos)(struct dao *dao, unsigned int spos); - int (*commit_write)(struct dao *dao); - int (*get_spos)(struct dao *dao, unsigned int *spos); - int (*reinit)(struct dao *dao, const struct dao_desc *desc); - int (*set_left_input)(struct dao *dao, struct rsc *input); - int (*set_right_input)(struct dao *dao, struct rsc *input); - int (*clear_left_input)(struct dao *dao); - int (*clear_right_input)(struct dao *dao); -}; - -struct dai_rsc_ops { - int (*set_srt_srcl)(struct dai *dai, struct rsc *src); - int (*set_srt_srcr)(struct dai *dai, struct rsc *src); - int (*set_srt_msr)(struct dai *dai, unsigned int msr); - int (*set_enb_src)(struct dai *dai, unsigned int enb); - int (*set_enb_srt)(struct dai *dai, unsigned int enb); - int (*commit_write)(struct dai *dai); -}; - -/* Define daio resource request description info */ -struct daio_desc { - unsigned int type:4; - unsigned int msr:4; - unsigned int passthru:1; -}; - -struct daio_mgr { - struct rsc_mgr mgr; /* Basic resource manager info */ - spinlock_t mgr_lock; - spinlock_t imap_lock; - struct list_head imappers; - struct imapper *init_imap; - unsigned int init_imap_added; - - /* request one daio resource */ - int (*get_daio)(struct daio_mgr *mgr, - const struct daio_desc *desc, struct daio **rdaio); - /* return one daio resource */ - int (*put_daio)(struct daio_mgr *mgr, struct daio *daio); - int (*daio_enable)(struct daio_mgr *mgr, struct daio *daio); - int (*daio_disable)(struct daio_mgr *mgr, struct daio *daio); - int (*imap_add)(struct daio_mgr *mgr, struct imapper *entry); - int (*imap_delete)(struct daio_mgr *mgr, struct imapper *entry); - int (*commit_write)(struct daio_mgr *mgr); -}; - -/* Constructor and destructor of daio resource manager */ -int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr); -int daio_mgr_destroy(struct daio_mgr *daio_mgr); - -#endif /* CTDAIO_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.c b/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.c deleted file mode 100644 index 8e64f486..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.c +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 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 cthardware.c - * - * @Brief - * This file contains the implementation of hardware access methord. - * - * @Author Liu Chun - * @Date Jun 26 2008 - * - */ - -#include "cthardware.h" -#include "cthw20k1.h" -#include "cthw20k2.h" -#include <linux/bug.h> - -int __devinit create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type, - enum CTCARDS model, struct hw **rhw) -{ - int err; - - switch (chip_type) { - case ATC20K1: - err = create_20k1_hw_obj(rhw); - break; - case ATC20K2: - err = create_20k2_hw_obj(rhw); - break; - default: - err = -ENODEV; - break; - } - if (err) - return err; - - (*rhw)->pci = pci; - (*rhw)->chip_type = chip_type; - (*rhw)->model = model; - - return 0; -} - -int destroy_hw_obj(struct hw *hw) -{ - int err; - - switch (hw->pci->device) { - case 0x0005: /* 20k1 device */ - err = destroy_20k1_hw_obj(hw); - break; - case 0x000B: /* 20k2 device */ - err = destroy_20k2_hw_obj(hw); - break; - default: - err = -ENODEV; - break; - } - - return err; -} - -unsigned int get_field(unsigned int data, unsigned int field) -{ - int i; - - BUG_ON(!field); - /* @field should always be greater than 0 */ - for (i = 0; !(field & (1 << i)); ) - i++; - - return (data & field) >> i; -} - -void set_field(unsigned int *data, unsigned int field, unsigned int value) -{ - int i; - - BUG_ON(!field); - /* @field should always be greater than 0 */ - for (i = 0; !(field & (1 << i)); ) - i++; - - *data = (*data & (~field)) | ((value << i) & field); -} - diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.h b/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.h deleted file mode 100644 index 908315be..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.h +++ /dev/null @@ -1,215 +0,0 @@ -/** - * 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 cthardware.h - * - * @Brief - * This file contains the definition of hardware access methord. - * - * @Author Liu Chun - * @Date May 13 2008 - * - */ - -#ifndef CTHARDWARE_H -#define CTHARDWARE_H - -#include <linux/types.h> -#include <linux/pci.h> - -enum CHIPTYP { - ATC20K1, - ATC20K2, - ATCNONE -}; - -enum CTCARDS { - /* 20k1 models */ - CTSB055X, - CT20K1_MODEL_FIRST = CTSB055X, - CTSB073X, - CTUAA, - CT20K1_UNKNOWN, - /* 20k2 models */ - CTSB0760, - CT20K2_MODEL_FIRST = CTSB0760, - CTHENDRIX, - CTSB0880, - CTSB1270, - CT20K2_UNKNOWN, - NUM_CTCARDS /* This should always be the last */ -}; - -/* Type of input source for ADC */ -enum ADCSRC{ - ADC_MICIN, - ADC_LINEIN, - ADC_VIDEO, - ADC_AUX, - ADC_NONE /* Switch to digital input */ -}; - -struct card_conf { - /* device virtual mem page table page physical addr - * (supporting one page table page now) */ - unsigned long vm_pgt_phys; - unsigned int rsr; /* reference sample rate in Hzs*/ - unsigned int msr; /* master sample rate in rsrs */ -}; - -struct capabilities { - unsigned int digit_io_switch:1; - unsigned int dedicated_mic:1; - unsigned int output_switch:1; - unsigned int mic_source_switch:1; -}; - -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); -#ifdef CONFIG_PM - int (*suspend)(struct hw *hw, pm_message_t state); - int (*resume)(struct hw *hw, struct card_conf *info); -#endif - int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); - int (*select_adc_source)(struct hw *hw, enum ADCSRC source); - struct capabilities (*capabilities)(struct hw *hw); - int (*output_switch_get)(struct hw *hw); - int (*output_switch_put)(struct hw *hw, int position); - int (*mic_source_switch_get)(struct hw *hw); - int (*mic_source_switch_put)(struct hw *hw, int position); - - /* SRC operations */ - int (*src_rsc_get_ctrl_blk)(void **rblk); - int (*src_rsc_put_ctrl_blk)(void *blk); - int (*src_set_state)(void *blk, unsigned int state); - int (*src_set_bm)(void *blk, unsigned int bm); - int (*src_set_rsr)(void *blk, unsigned int rsr); - int (*src_set_sf)(void *blk, unsigned int sf); - int (*src_set_wr)(void *blk, unsigned int wr); - int (*src_set_pm)(void *blk, unsigned int pm); - int (*src_set_rom)(void *blk, unsigned int rom); - int (*src_set_vo)(void *blk, unsigned int vo); - int (*src_set_st)(void *blk, unsigned int st); - int (*src_set_ie)(void *blk, unsigned int ie); - int (*src_set_ilsz)(void *blk, unsigned int ilsz); - int (*src_set_bp)(void *blk, unsigned int bp); - int (*src_set_cisz)(void *blk, unsigned int cisz); - int (*src_set_ca)(void *blk, unsigned int ca); - int (*src_set_sa)(void *blk, unsigned int sa); - int (*src_set_la)(void *blk, unsigned int la); - int (*src_set_pitch)(void *blk, unsigned int pitch); - int (*src_set_clear_zbufs)(void *blk, unsigned int clear); - int (*src_set_dirty)(void *blk, unsigned int flags); - int (*src_set_dirty_all)(void *blk); - int (*src_commit_write)(struct hw *hw, unsigned int idx, void *blk); - int (*src_get_ca)(struct hw *hw, unsigned int idx, void *blk); - unsigned int (*src_get_dirty)(void *blk); - unsigned int (*src_dirty_conj_mask)(void); - int (*src_mgr_get_ctrl_blk)(void **rblk); - int (*src_mgr_put_ctrl_blk)(void *blk); - /* syncly enable src @idx */ - int (*src_mgr_enbs_src)(void *blk, unsigned int idx); - /* enable src @idx */ - int (*src_mgr_enb_src)(void *blk, unsigned int idx); - /* disable src @idx */ - int (*src_mgr_dsb_src)(void *blk, unsigned int idx); - int (*src_mgr_commit_write)(struct hw *hw, void *blk); - - /* SRC Input Mapper operations */ - int (*srcimp_mgr_get_ctrl_blk)(void **rblk); - int (*srcimp_mgr_put_ctrl_blk)(void *blk); - int (*srcimp_mgr_set_imaparc)(void *blk, unsigned int slot); - int (*srcimp_mgr_set_imapuser)(void *blk, unsigned int user); - int (*srcimp_mgr_set_imapnxt)(void *blk, unsigned int next); - int (*srcimp_mgr_set_imapaddr)(void *blk, unsigned int addr); - int (*srcimp_mgr_commit_write)(struct hw *hw, void *blk); - - /* AMIXER operations */ - int (*amixer_rsc_get_ctrl_blk)(void **rblk); - int (*amixer_rsc_put_ctrl_blk)(void *blk); - int (*amixer_mgr_get_ctrl_blk)(void **rblk); - int (*amixer_mgr_put_ctrl_blk)(void *blk); - int (*amixer_set_mode)(void *blk, unsigned int mode); - int (*amixer_set_iv)(void *blk, unsigned int iv); - int (*amixer_set_x)(void *blk, unsigned int x); - int (*amixer_set_y)(void *blk, unsigned int y); - int (*amixer_set_sadr)(void *blk, unsigned int sadr); - int (*amixer_set_se)(void *blk, unsigned int se); - int (*amixer_set_dirty)(void *blk, unsigned int flags); - int (*amixer_set_dirty_all)(void *blk); - int (*amixer_commit_write)(struct hw *hw, unsigned int idx, void *blk); - int (*amixer_get_y)(void *blk); - unsigned int (*amixer_get_dirty)(void *blk); - - /* DAIO operations */ - int (*dai_get_ctrl_blk)(void **rblk); - int (*dai_put_ctrl_blk)(void *blk); - int (*dai_srt_set_srco)(void *blk, unsigned int src); - int (*dai_srt_set_srcm)(void *blk, unsigned int src); - int (*dai_srt_set_rsr)(void *blk, unsigned int rsr); - int (*dai_srt_set_drat)(void *blk, unsigned int drat); - int (*dai_srt_set_ec)(void *blk, unsigned int ec); - int (*dai_srt_set_et)(void *blk, unsigned int et); - int (*dai_commit_write)(struct hw *hw, unsigned int idx, void *blk); - int (*dao_get_ctrl_blk)(void **rblk); - int (*dao_put_ctrl_blk)(void *blk); - int (*dao_set_spos)(void *blk, unsigned int spos); - int (*dao_commit_write)(struct hw *hw, unsigned int idx, void *blk); - int (*dao_get_spos)(void *blk, unsigned int *spos); - - int (*daio_mgr_get_ctrl_blk)(struct hw *hw, void **rblk); - int (*daio_mgr_put_ctrl_blk)(void *blk); - int (*daio_mgr_enb_dai)(void *blk, unsigned int idx); - int (*daio_mgr_dsb_dai)(void *blk, unsigned int idx); - int (*daio_mgr_enb_dao)(void *blk, unsigned int idx); - int (*daio_mgr_dsb_dao)(void *blk, unsigned int idx); - int (*daio_mgr_dao_init)(void *blk, unsigned int idx, - unsigned int conf); - int (*daio_mgr_set_imaparc)(void *blk, unsigned int slot); - int (*daio_mgr_set_imapnxt)(void *blk, unsigned int next); - 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); - unsigned int (*get_wc)(struct hw *hw); - - 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; - unsigned long mem_base; - - enum CHIPTYP chip_type; - enum CTCARDS model; -}; - -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); -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/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.c b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.c deleted file mode 100644 index a7df1979..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.c +++ /dev/null @@ -1,2304 +0,0 @@ -/** - * 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 <linux/types.h> -#include <linux/slab.h> -#include <linux/pci.h> -#include <linux/io.h> -#include <linux/string.h> -#include <linux/spinlock.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include "cthw20k1.h" -#include "ct20k1reg.h" - -#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; - 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 (!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; - - 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; - unsigned int ret; - - 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 (!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 (!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 (!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 (!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 (!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 (!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; - - 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 (!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; -} - -/* 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; -} - -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 */ -}; - -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; - u32 spdorg; - - /* 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; - u32 ptp_phys_low, ptp_phys_high; - - /* 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 */ - 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); - hw_write_20kx(hw, TRNCTL, trnctl); - hw_write_20kx(hw, TRNIS, 0x200c01); /* really 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; - - 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; - - 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; - u16 gpioorg; - unsigned int ret; - - 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; - u16 gpioorg; - unsigned int ret; - - if (hw->model == CTSB055X) { - /* 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) -{ - return 0; -} - -static int is_adc_input_selected_SBx(struct hw *hw, enum ADCSRC type) -{ - u32 data; - - 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; - - 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) -{ - switch (hw->model) { - case CTSB055X: - return is_adc_input_selected_SB055x(hw, type); - case CTSB073X: - return is_adc_input_selected_hendrix(hw, type); - case CTUAA: - return is_adc_input_selected_hendrix(hw, type); - default: - 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; - - /* - * 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; - u32 i2c_data; - unsigned int ret; - - 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; - u32 i2c_data; - unsigned int ret; - - 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) -{ - 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 CTUAA: - return adc_input_select_hendrix(hw, type, state); - default: - return adc_input_select_SBx(hw, type, state); - } -} - -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; - unsigned int ret; - - 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: - adcdata = 0x0; - 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) -{ - if (hw->model == CTSB055X) - return adc_init_SB055x(hw, info->input, info->mic20db); - else - return adc_init_SBx(hw, info->input, info->mic20db); -} - -static struct capabilities hw_capabilities(struct hw *hw) -{ - struct capabilities cap; - - /* SB073x and Vista compatible cards have no digit IO switch */ - cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA); - cap.dedicated_mic = 0; - cap.output_switch = 0; - cap.mic_source_switch = 0; - - return cap; -} - -#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 -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; - unsigned int data[4] = {0}; - unsigned int io_base; - void *mem_base; - 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'); - 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); - mem_base = ioremap(io_base, pci_resource_len(pci, 0)); - if (!mem_base) - return -ENOENT; - - /* 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 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; - struct pci_dev *pci = hw->pci; - - err = pci_enable_device(pci); - if (err < 0) - return err; - - /* Set DMA transfer mask */ - 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%llx\n", - CT_XFI_DMA_MASK); - err = -ENXIO; - goto error1; - } - - if (!hw->io_base) { - err = pci_request_regions(pci, "XFi"); - if (err < 0) - goto error1; - - if (hw->model == CTUAA) - hw->io_base = pci_resource_start(pci, 5); - else - hw->io_base = pci_resource_start(pci, 0); - - } - - /* Switch to X-Fi mode from UAA mode if neeeded */ - if (hw->model == CTUAA) { - err = uaa_to_xfi(pci); - if (err) - goto error2; - - } - - if (hw->irq < 0) { - err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, - KBUILD_MODNAME, 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); - - 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) -{ - unsigned int data; - - /* disable transport bus master and queueing of request */ - hw_write_20kx(hw, TRNCTL, 0x00); - - /* disable pll */ - data = hw_read_20kx(hw, PLLCTL); - hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12)))); - - /* TODO: Disable interrupt and so on... */ - if (hw->irq >= 0) - synchronize_irq(hw->irq); - return 0; -} - -static int hw_card_shutdown(struct hw *hw) -{ - if (hw->irq >= 0) - free_irq(hw->irq, hw); - - hw->irq = -1; - - if (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; - u32 data; - 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. */ - 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); - - /* Detect the card ID and configure GPIO accordingly. */ - switch (hw->model) { - case CTSB055X: - hw_write_20kx(hw, GPIOCTL, 0x13fe); - break; - case CTSB073X: - hw_write_20kx(hw, GPIOCTL, 0x00e6); - break; - case CTUAA: - hw_write_20kx(hw, GPIOCTL, 0x00c2); - break; - default: - hw_write_20kx(hw, GPIOCTL, 0x01e6); - break; - } - - 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; -} - -#ifdef CONFIG_PM -static int hw_suspend(struct hw *hw, pm_message_t state) -{ - struct pci_dev *pci = hw->pci; - - hw_card_stop(hw); - - if (hw->model == CTUAA) { - /* Switch to UAA config space. */ - pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0); - } - - pci_disable_device(pci); - pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); - - return 0; -} - -static int hw_resume(struct hw *hw, struct card_conf *info) -{ - struct pci_dev *pci = hw->pci; - - pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); - - /* Re-initialize card hardware. */ - return hw_card_init(hw, info); -} -#endif - -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); -} - -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, - .capabilities = hw_capabilities, -#ifdef CONFIG_PM - .suspend = hw_suspend, - .resume = hw_resume, -#endif - - .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, - .get_wc = get_wc, -}; - -int __devinit create_20k1_hw_obj(struct hw **rhw) -{ - struct hw20k1 *hw20k1; - - *rhw = NULL; - hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL); - if (!hw20k1) - return -ENOMEM; - - spin_lock_init(&hw20k1->reg_20k1_lock); - spin_lock_init(&hw20k1->reg_pci_lock); - - hw20k1->hw = ct20k1_preset; - - *rhw = &hw20k1->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; -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.h b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.h deleted file mode 100644 index 02f72fb4..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * 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.h - * - * @Brief - * This file contains the definition of hardware access methord. - * - * @Author Liu Chun - * @Date May 13 2008 - * - */ - -#ifndef CTHW20K1_H -#define CTHW20K1_H - -#include "cthardware.h" - -int create_20k1_hw_obj(struct hw **rhw); -int destroy_20k1_hw_obj(struct hw *hw); - -#endif /* CTHW20K1_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.c b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.c deleted file mode 100644 index d6c54b52..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.c +++ /dev/null @@ -1,2370 +0,0 @@ -/** - * 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 cthw20k2.c - * - * @Brief - * This file contains the implementation of hardware access method for 20k2. - * - * @Author Liu Chun - * @Date May 14 2008 - * - */ - -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/pci.h> -#include <linux/io.h> -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include "cthw20k2.h" -#include "ct20k2reg.h" - -#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 hw20k2 { - struct hw hw; - /* for i2c */ - unsigned char dev_id; - unsigned char addr_size; - unsigned char data_size; - - int mic_source; -}; - -static u32 hw_read_20kx(struct hw *hw, u32 reg); -static void hw_write_20kx(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 0x0FFFFFFF -#define SRCCA_RS 0xE0000000 - -#define SRCSA_SA 0x0FFFFFFF - -#define SRCLA_LA 0x0FFFFFFF - -/* 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 (!blk) - return -ENOMEM; - - *rblk = blk; - - return 0; -} - -static int src_put_rsc_ctrl_blk(void *blk) -{ - kfree(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; - - if (ctl->dirty.bf.czbfs) { - /* Clear Z-Buffer registers */ - for (i = 0; i < 8; i++) - hw_write_20kx(hw, SRC_UPZ+idx*0x100+i*0x4, 0); - - for (i = 0; i < 4; i++) - hw_write_20kx(hw, SRC_DN0Z+idx*0x100+i*0x4, 0); - - for (i = 0; i < 8; i++) - hw_write_20kx(hw, SRC_DN1Z+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, MIXER_PRING_LO_HI+4*pm_idx, ctl->mpr); - hw_write_20kx(hw, MIXER_PMOPLO+8*pm_idx, 0x3); - hw_write_20kx(hw, MIXER_PMOPHI+8*pm_idx, 0x0); - ctl->dirty.bf.mpr = 0; - } - if (ctl->dirty.bf.sa) { - hw_write_20kx(hw, SRC_SA+idx*0x100, ctl->sa); - ctl->dirty.bf.sa = 0; - } - if (ctl->dirty.bf.la) { - hw_write_20kx(hw, SRC_LA+idx*0x100, ctl->la); - ctl->dirty.bf.la = 0; - } - if (ctl->dirty.bf.ca) { - hw_write_20kx(hw, SRC_CA+idx*0x100, ctl->ca); - ctl->dirty.bf.ca = 0; - } - - /* Write srccf register */ - hw_write_20kx(hw, SRC_CF+idx*0x100, 0x0); - - if (ctl->dirty.bf.ccr) { - hw_write_20kx(hw, SRC_CCR+idx*0x100, ctl->ccr); - ctl->dirty.bf.ccr = 0; - } - if (ctl->dirty.bf.ctl) { - hw_write_20kx(hw, SRC_CTL+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, SRC_CA+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 |= (0x1 << ((idx%128)/4)); - ((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; - unsigned int ret; - - if (ctl->dirty.bf.enbsa) { - do { - ret = hw_read_20kx(hw, SRC_ENBSTAT); - } while (ret & 0x1); - hw_write_20kx(hw, SRC_ENBSA, ctl->enbsa); - ctl->dirty.bf.enbsa = 0; - } - for (i = 0; i < 8; i++) { - if ((ctl->dirty.data & (0x1 << i))) { - hw_write_20kx(hw, SRC_ENB+(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 (!blk) - return -ENOMEM; - - *rblk = blk; - - return 0; -} - -static int src_mgr_put_ctrl_blk(void *blk) -{ - kfree(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 (!blk) - return -ENOMEM; - - *rblk = blk; - - return 0; -} - -static int srcimp_mgr_put_ctrl_blk(void *blk) -{ - kfree(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 *)blk)->srcimap.idx = addr; - ((struct srcimp_mgr_ctrl_blk *)blk)->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, SRC_IMAP+ctl->srcimap.idx*0x100, - ctl->srcimap.srcaim); - ctl->dirty.bf.srcimap = 0; - } - - return 0; -} - -/* - * AMIXER control block definitions. - */ - -#define AMOPLO_M 0x00000003 -#define AMOPLO_IV 0x00000004 -#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) -{ - struct amixer_rsc_ctrl_blk *ctl = blk; - - set_field(&ctl->amoplo, AMOPLO_IV, iv); - ctl->dirty.bf.amoplo = 1; - 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, MIXER_AMOPLO+idx*8, ctl->amoplo); - ctl->dirty.bf.amoplo = 0; - hw_write_20kx(hw, MIXER_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 (!blk) - return -ENOMEM; - - *rblk = blk; - - return 0; -} - -static int amixer_rsc_put_ctrl_blk(void *blk) -{ - kfree(blk); - - return 0; -} - -static int amixer_mgr_get_ctrl_blk(void **rblk) -{ - *rblk = NULL; - - return 0; -} - -static int amixer_mgr_put_ctrl_blk(void *blk) -{ - return 0; -} - -/* - * DAIO control block definitions. - */ - -/* Receiver Sample Rate Tracker Control register */ -#define SRTCTL_SRCO 0x000000FF -#define SRTCTL_SRCM 0x0000FF00 -#define SRTCTL_RSR 0x00030000 -#define SRTCTL_DRAT 0x00300000 -#define SRTCTL_EC 0x01000000 -#define SRTCTL_ET 0x10000000 - -/* DAIO Receiver register dirty flags */ -union dai_dirty { - struct { - u16 srt:1; - u16 rsv:15; - } bf; - u16 data; -}; - -/* DAIO Receiver control block */ -struct dai_ctrl_blk { - unsigned int srt; - union dai_dirty dirty; -}; - -/* Audio Input Mapper RAM */ -#define AIM_ARC 0x00000FFF -#define AIM_NXT 0x007F0000 - -struct daoimap { - unsigned int aim; - unsigned int idx; -}; - -/* Audio Transmitter Control and Status register */ -#define ATXCTL_EN 0x00000001 -#define ATXCTL_MODE 0x00000010 -#define ATXCTL_CD 0x00000020 -#define ATXCTL_RAW 0x00000100 -#define ATXCTL_MT 0x00000200 -#define ATXCTL_NUC 0x00003000 -#define ATXCTL_BEN 0x00010000 -#define ATXCTL_BMUX 0x00700000 -#define ATXCTL_B24 0x01000000 -#define ATXCTL_CPF 0x02000000 -#define ATXCTL_RIV 0x10000000 -#define ATXCTL_LIV 0x20000000 -#define ATXCTL_RSAT 0x40000000 -#define ATXCTL_LSAT 0x80000000 - -/* XDIF Transmitter register dirty flags */ -union dao_dirty { - struct { - u16 atxcsl:1; - u16 rsv:15; - } bf; - u16 data; -}; - -/* XDIF Transmitter control block */ -struct dao_ctrl_blk { - /* XDIF Transmitter Channel Status Low Register */ - unsigned int atxcsl; - union dao_dirty dirty; -}; - -/* Audio Receiver Control register */ -#define ARXCTL_EN 0x00000001 - -/* DAIO manager register dirty flags */ -union daio_mgr_dirty { - struct { - u32 atxctl:8; - u32 arxctl:8; - u32 daoimap:1; - u32 rsv:15; - } bf; - u32 data; -}; - -/* DAIO manager control block */ -struct daio_mgr_ctrl_blk { - struct daoimap daoimap; - unsigned int txctl[8]; - unsigned int rxctl[8]; - union daio_mgr_dirty dirty; -}; - -static int dai_srt_set_srco(void *blk, unsigned int src) -{ - struct dai_ctrl_blk *ctl = blk; - - set_field(&ctl->srt, SRTCTL_SRCO, src); - ctl->dirty.bf.srt = 1; - return 0; -} - -static int dai_srt_set_srcm(void *blk, unsigned int src) -{ - struct dai_ctrl_blk *ctl = blk; - - set_field(&ctl->srt, SRTCTL_SRCM, src); - ctl->dirty.bf.srt = 1; - return 0; -} - -static int dai_srt_set_rsr(void *blk, unsigned int rsr) -{ - struct dai_ctrl_blk *ctl = blk; - - set_field(&ctl->srt, SRTCTL_RSR, rsr); - ctl->dirty.bf.srt = 1; - return 0; -} - -static int dai_srt_set_drat(void *blk, unsigned int drat) -{ - struct dai_ctrl_blk *ctl = blk; - - set_field(&ctl->srt, SRTCTL_DRAT, drat); - ctl->dirty.bf.srt = 1; - return 0; -} - -static int dai_srt_set_ec(void *blk, unsigned int ec) -{ - struct dai_ctrl_blk *ctl = blk; - - set_field(&ctl->srt, SRTCTL_EC, ec ? 1 : 0); - ctl->dirty.bf.srt = 1; - return 0; -} - -static int dai_srt_set_et(void *blk, unsigned int et) -{ - struct dai_ctrl_blk *ctl = blk; - - set_field(&ctl->srt, SRTCTL_ET, et ? 1 : 0); - ctl->dirty.bf.srt = 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.srt) { - hw_write_20kx(hw, AUDIO_IO_RX_SRT_CTL+0x40*idx, ctl->srt); - ctl->dirty.bf.srt = 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 (!blk) - return -ENOMEM; - - *rblk = blk; - - return 0; -} - -static int dai_put_ctrl_blk(void *blk) -{ - kfree(blk); - - return 0; -} - -static int dao_set_spos(void *blk, unsigned int spos) -{ - ((struct dao_ctrl_blk *)blk)->atxcsl = spos; - ((struct dao_ctrl_blk *)blk)->dirty.bf.atxcsl = 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.atxcsl) { - if (idx < 4) { - /* S/PDIF SPOSx */ - hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+0x40*idx, - ctl->atxcsl); - } - ctl->dirty.bf.atxcsl = 0; - } - - return 0; -} - -static int dao_get_spos(void *blk, unsigned int *spos) -{ - *spos = ((struct dao_ctrl_blk *)blk)->atxcsl; - return 0; -} - -static int dao_get_ctrl_blk(void **rblk) -{ - struct dao_ctrl_blk *blk; - - *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); - if (!blk) - return -ENOMEM; - - *rblk = blk; - - return 0; -} - -static int dao_put_ctrl_blk(void *blk) -{ - kfree(blk); - - return 0; -} - -static int daio_mgr_enb_dai(void *blk, unsigned int idx) -{ - struct daio_mgr_ctrl_blk *ctl = blk; - - set_field(&ctl->rxctl[idx], ARXCTL_EN, 1); - ctl->dirty.bf.arxctl |= (0x1 << idx); - return 0; -} - -static int daio_mgr_dsb_dai(void *blk, unsigned int idx) -{ - struct daio_mgr_ctrl_blk *ctl = blk; - - set_field(&ctl->rxctl[idx], ARXCTL_EN, 0); - - ctl->dirty.bf.arxctl |= (0x1 << idx); - return 0; -} - -static int daio_mgr_enb_dao(void *blk, unsigned int idx) -{ - struct daio_mgr_ctrl_blk *ctl = blk; - - set_field(&ctl->txctl[idx], ATXCTL_EN, 1); - ctl->dirty.bf.atxctl |= (0x1 << idx); - return 0; -} - -static int daio_mgr_dsb_dao(void *blk, unsigned int idx) -{ - struct daio_mgr_ctrl_blk *ctl = blk; - - set_field(&ctl->txctl[idx], ATXCTL_EN, 0); - ctl->dirty.bf.atxctl |= (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 1: - set_field(&ctl->txctl[idx], ATXCTL_NUC, 0); - break; - case 2: - set_field(&ctl->txctl[idx], ATXCTL_NUC, 1); - break; - case 4: - set_field(&ctl->txctl[idx], ATXCTL_NUC, 2); - break; - case 8: - set_field(&ctl->txctl[idx], ATXCTL_NUC, 3); - break; - default: - break; - } - /* CDIF */ - set_field(&ctl->txctl[idx], ATXCTL_CD, (!(conf & 0x7))); - /* Non-audio */ - set_field(&ctl->txctl[idx], ATXCTL_LIV, (conf >> 4) & 0x1); - /* Non-audio */ - set_field(&ctl->txctl[idx], ATXCTL_RIV, (conf >> 4) & 0x1); - set_field(&ctl->txctl[idx], ATXCTL_RAW, - ((conf >> 3) & 0x1) ? 0 : 0); - ctl->dirty.bf.atxctl |= (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 *)blk)->daoimap.idx = addr; - ((struct daio_mgr_ctrl_blk *)blk)->dirty.bf.daoimap = 1; - return 0; -} - -static int daio_mgr_commit_write(struct hw *hw, void *blk) -{ - struct daio_mgr_ctrl_blk *ctl = blk; - unsigned int data; - int i; - - for (i = 0; i < 8; i++) { - if ((ctl->dirty.bf.atxctl & (0x1 << i))) { - data = ctl->txctl[i]; - hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data); - ctl->dirty.bf.atxctl &= ~(0x1 << i); - mdelay(1); - } - if ((ctl->dirty.bf.arxctl & (0x1 << i))) { - data = ctl->rxctl[i]; - hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data); - ctl->dirty.bf.arxctl &= ~(0x1 << i); - mdelay(1); - } - } - if (ctl->dirty.bf.daoimap) { - hw_write_20kx(hw, AUDIO_IO_AIM+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; - int i; - - *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); - if (!blk) - return -ENOMEM; - - for (i = 0; i < 8; i++) { - blk->txctl[i] = hw_read_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i)); - blk->rxctl[i] = hw_read_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i)); - } - - *rblk = blk; - - return 0; -} - -static int daio_mgr_put_ctrl_blk(void *blk) -{ - kfree(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; -} - -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 */ -}; - -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 data; - int i; - - /* Program I2S with proper sample rate and enable the correct I2S - * channel. ED(0/8/16/24): Enable all I2S/I2X master clock output */ - if (1 == info->msr) { - hw_write_20kx(hw, AUDIO_IO_MCLK, 0x01010101); - hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101); - hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); - } else if (2 == info->msr) { - if (hw->model != CTSB1270) { - hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111); - } else { - /* PCM4220 on Titanium HD is different. */ - hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111); - } - /* Specify all playing 96khz - * EA [0] - Enabled - * RTA [4:5] - 96kHz - * EB [8] - Enabled - * RTB [12:13] - 96kHz - * EC [16] - Enabled - * RTC [20:21] - 96kHz - * ED [24] - Enabled - * RTD [28:29] - 96kHz */ - hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111); - hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); - } else if ((4 == info->msr) && (hw->model == CTSB1270)) { - hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111); - hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121); - hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); - } else { - printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n"); - return -EINVAL; - } - - for (i = 0; i < 8; i++) { - if (i <= 3) { - /* This comment looks wrong since loop is over 4 */ - /* channels and emu20k2 supports 4 spdif IOs. */ - /* 1st 3 channels are SPDIFs (SB0960) */ - if (i == 3) - data = 0x1001001; - else - data = 0x1000001; - - hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data); - hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data); - - /* Initialize the SPDIF Out Channel status registers. - * The value specified here is based on the typical - * values provided in the specification, namely: Clock - * Accuracy of 1000ppm, Sample Rate of 48KHz, - * unspecified source number, Generation status = 1, - * Category code = 0x12 (Digital Signal Mixer), - * Mode = 0, Emph = 0, Copy Permitted, AN = 0 - * (indicating that we're transmitting digital audio, - * and the Professional Use bit is 0. */ - - hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+(0x40*i), - 0x02109204); /* Default to 48kHz */ - - hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B); - } else { - /* Again, loop is over 4 channels not 5. */ - /* Next 5 channels are I2S (SB0960) */ - data = 0x11; - hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data); - if (2 == info->msr) { - /* Four channels per sample period */ - data |= 0x1000; - } else if (4 == info->msr) { - /* FIXME: check this against the chip spec */ - data |= 0x2000; - } - hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data); - } - } - - return 0; -} - -/* TRANSPORT operations */ -static int hw_trn_init(struct hw *hw, const struct trn_conf *info) -{ - u32 vmctl, data; - u32 ptp_phys_low, ptp_phys_high; - int i; - - /* Set up device page table */ - if ((~0UL) == info->vm_pgt_phys) { - printk(KERN_ALERT "ctxfi: " - "Wrong device page table page address!!!\n"); - return -1; - } - - vmctl = 0x80000C0F; /* 32-bit, 4k-size page */ - 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); - hw_write_20kx(hw, VMEM_PTPAH+(16*i), ptp_phys_high); - } - /* Enable virtual memory transfer */ - hw_write_20kx(hw, VMEM_CTL, vmctl); - /* Enable transport bus master and queueing of request */ - hw_write_20kx(hw, TRANSPORT_CTL, 0x03); - hw_write_20kx(hw, TRANSPORT_INT, 0x200c01); - /* Enable transport ring */ - data = hw_read_20kx(hw, TRANSPORT_ENB); - hw_write_20kx(hw, TRANSPORT_ENB, (data | 0x03)); - - return 0; -} - -/* Card initialization */ -#define GCTL_AIE 0x00000001 -#define GCTL_UAA 0x00000002 -#define GCTL_DPC 0x00000004 -#define GCTL_DBP 0x00000008 -#define GCTL_ABP 0x00000010 -#define GCTL_TBP 0x00000020 -#define GCTL_SBP 0x00000040 -#define GCTL_FBP 0x00000080 -#define GCTL_ME 0x00000100 -#define GCTL_AID 0x00001000 - -#define PLLCTL_SRC 0x00000007 -#define PLLCTL_SPE 0x00000008 -#define PLLCTL_RD 0x000000F0 -#define PLLCTL_FD 0x0001FF00 -#define PLLCTL_OD 0x00060000 -#define PLLCTL_B 0x00080000 -#define PLLCTL_AS 0x00100000 -#define PLLCTL_LF 0x03E00000 -#define PLLCTL_SPS 0x1C000000 -#define PLLCTL_AD 0x60000000 - -#define PLLSTAT_CCS 0x00000007 -#define PLLSTAT_SPL 0x00000008 -#define PLLSTAT_CRD 0x000000F0 -#define PLLSTAT_CFD 0x0001FF00 -#define PLLSTAT_SL 0x00020000 -#define PLLSTAT_FAS 0x00040000 -#define PLLSTAT_B 0x00080000 -#define PLLSTAT_PD 0x00100000 -#define PLLSTAT_OCA 0x00200000 -#define PLLSTAT_NCA 0x00400000 - -static int hw_pll_init(struct hw *hw, unsigned int rsr) -{ - unsigned int pllenb; - unsigned int pllctl; - unsigned int pllstat; - int i; - - pllenb = 0xB; - hw_write_20kx(hw, PLL_ENB, pllenb); - pllctl = 0x20C00000; - set_field(&pllctl, PLLCTL_B, 0); - set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4); - set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1); - hw_write_20kx(hw, PLL_CTL, pllctl); - mdelay(40); - - pllctl = hw_read_20kx(hw, PLL_CTL); - set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2); - hw_write_20kx(hw, PLL_CTL, pllctl); - mdelay(40); - - for (i = 0; i < 1000; i++) { - pllstat = hw_read_20kx(hw, PLL_STAT); - if (get_field(pllstat, PLLSTAT_PD)) - continue; - - if (get_field(pllstat, PLLSTAT_B) != - get_field(pllctl, PLLCTL_B)) - continue; - - if (get_field(pllstat, PLLSTAT_CCS) != - get_field(pllctl, PLLCTL_SRC)) - continue; - - if (get_field(pllstat, PLLSTAT_CRD) != - get_field(pllctl, PLLCTL_RD)) - continue; - - if (get_field(pllstat, PLLSTAT_CFD) != - get_field(pllctl, PLLCTL_FD)) - continue; - - break; - } - if (i >= 1000) { - printk(KERN_ALERT "ctxfi: 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, GLOBAL_CNTL_GCTL); - set_field(&gctl, GCTL_AIE, 0); - hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); - set_field(&gctl, GCTL_AIE, 1); - hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); - mdelay(10); - for (i = 0; i < 400000; i++) { - gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL); - if (get_field(gctl, GCTL_AID)) - break; - } - if (!get_field(gctl, GCTL_AID)) { - printk(KERN_ALERT "ctxfi: Card Auto-init failed!!!\n"); - return -EBUSY; - } - - return 0; -} - -/* DAC operations */ - -#define CS4382_MC1 0x1 -#define CS4382_MC2 0x2 -#define CS4382_MC3 0x3 -#define CS4382_FC 0x4 -#define CS4382_IC 0x5 -#define CS4382_XC1 0x6 -#define CS4382_VCA1 0x7 -#define CS4382_VCB1 0x8 -#define CS4382_XC2 0x9 -#define CS4382_VCA2 0xA -#define CS4382_VCB2 0xB -#define CS4382_XC3 0xC -#define CS4382_VCA3 0xD -#define CS4382_VCB3 0xE -#define CS4382_XC4 0xF -#define CS4382_VCA4 0x10 -#define CS4382_VCB4 0x11 -#define CS4382_CREV 0x12 - -/* I2C status */ -#define STATE_LOCKED 0x00 -#define STATE_UNLOCKED 0xAA -#define DATA_READY 0x800000 /* Used with I2C_IF_STATUS */ -#define DATA_ABORT 0x10000 /* Used with I2C_IF_STATUS */ - -#define I2C_STATUS_DCM 0x00000001 -#define I2C_STATUS_BC 0x00000006 -#define I2C_STATUS_APD 0x00000008 -#define I2C_STATUS_AB 0x00010000 -#define I2C_STATUS_DR 0x00800000 - -#define I2C_ADDRESS_PTAD 0x0000FFFF -#define I2C_ADDRESS_SLAD 0x007F0000 - -struct regs_cs4382 { - u32 mode_control_1; - u32 mode_control_2; - u32 mode_control_3; - - u32 filter_control; - u32 invert_control; - - u32 mix_control_P1; - u32 vol_control_A1; - u32 vol_control_B1; - - u32 mix_control_P2; - u32 vol_control_A2; - u32 vol_control_B2; - - u32 mix_control_P3; - u32 vol_control_A3; - u32 vol_control_B3; - - u32 mix_control_P4; - u32 vol_control_A4; - u32 vol_control_B4; -}; - -static int hw20k2_i2c_unlock_full_access(struct hw *hw) -{ - u8 UnlockKeySequence_FLASH_FULLACCESS_MODE[2] = {0xB3, 0xD4}; - - /* Send keys for forced BIOS mode */ - hw_write_20kx(hw, I2C_IF_WLOCK, - UnlockKeySequence_FLASH_FULLACCESS_MODE[0]); - hw_write_20kx(hw, I2C_IF_WLOCK, - UnlockKeySequence_FLASH_FULLACCESS_MODE[1]); - /* Check whether the chip is unlocked */ - if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_UNLOCKED) - return 0; - - return -1; -} - -static int hw20k2_i2c_lock_chip(struct hw *hw) -{ - /* Write twice */ - hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED); - hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED); - if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_LOCKED) - return 0; - - return -1; -} - -static int hw20k2_i2c_init(struct hw *hw, u8 dev_id, u8 addr_size, u8 data_size) -{ - struct hw20k2 *hw20k2 = (struct hw20k2 *)hw; - int err; - unsigned int i2c_status; - unsigned int i2c_addr; - - err = hw20k2_i2c_unlock_full_access(hw); - if (err < 0) - return err; - - hw20k2->addr_size = addr_size; - hw20k2->data_size = data_size; - hw20k2->dev_id = dev_id; - - i2c_addr = 0; - set_field(&i2c_addr, I2C_ADDRESS_SLAD, dev_id); - - hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr); - - i2c_status = hw_read_20kx(hw, I2C_IF_STATUS); - - set_field(&i2c_status, I2C_STATUS_DCM, 1); /* Direct control mode */ - - hw_write_20kx(hw, I2C_IF_STATUS, i2c_status); - - return 0; -} - -static int hw20k2_i2c_uninit(struct hw *hw) -{ - unsigned int i2c_status; - unsigned int i2c_addr; - - i2c_addr = 0; - set_field(&i2c_addr, I2C_ADDRESS_SLAD, 0x57); /* I2C id */ - - hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr); - - i2c_status = hw_read_20kx(hw, I2C_IF_STATUS); - - set_field(&i2c_status, I2C_STATUS_DCM, 0); /* I2C mode */ - - hw_write_20kx(hw, I2C_IF_STATUS, i2c_status); - - return hw20k2_i2c_lock_chip(hw); -} - -static int hw20k2_i2c_wait_data_ready(struct hw *hw) -{ - int i = 0x400000; - unsigned int ret; - - do { - ret = hw_read_20kx(hw, I2C_IF_STATUS); - } while ((!(ret & DATA_READY)) && --i); - - return i; -} - -static int hw20k2_i2c_read(struct hw *hw, u16 addr, u32 *datap) -{ - struct hw20k2 *hw20k2 = (struct hw20k2 *)hw; - unsigned int i2c_status; - - i2c_status = hw_read_20kx(hw, I2C_IF_STATUS); - set_field(&i2c_status, I2C_STATUS_BC, - (4 == hw20k2->addr_size) ? 0 : hw20k2->addr_size); - hw_write_20kx(hw, I2C_IF_STATUS, i2c_status); - if (!hw20k2_i2c_wait_data_ready(hw)) - return -1; - - hw_write_20kx(hw, I2C_IF_WDATA, addr); - if (!hw20k2_i2c_wait_data_ready(hw)) - return -1; - - /* Force a read operation */ - hw_write_20kx(hw, I2C_IF_RDATA, 0); - if (!hw20k2_i2c_wait_data_ready(hw)) - return -1; - - *datap = hw_read_20kx(hw, I2C_IF_RDATA); - - return 0; -} - -static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data) -{ - struct hw20k2 *hw20k2 = (struct hw20k2 *)hw; - unsigned int i2c_data = (data << (hw20k2->addr_size * 8)) | addr; - unsigned int i2c_status; - - i2c_status = hw_read_20kx(hw, I2C_IF_STATUS); - - set_field(&i2c_status, I2C_STATUS_BC, - (4 == (hw20k2->addr_size + hw20k2->data_size)) ? - 0 : (hw20k2->addr_size + hw20k2->data_size)); - - hw_write_20kx(hw, I2C_IF_STATUS, i2c_status); - hw20k2_i2c_wait_data_ready(hw); - /* Dummy write to trigger the write operation */ - hw_write_20kx(hw, I2C_IF_WDATA, 0); - hw20k2_i2c_wait_data_ready(hw); - - /* This is the real data */ - hw_write_20kx(hw, I2C_IF_WDATA, i2c_data); - hw20k2_i2c_wait_data_ready(hw); - - return 0; -} - -static void hw_dac_stop(struct hw *hw) -{ - u32 data; - data = hw_read_20kx(hw, GPIO_DATA); - data &= 0xFFFFFFFD; - hw_write_20kx(hw, GPIO_DATA, data); - mdelay(10); -} - -static void hw_dac_start(struct hw *hw) -{ - u32 data; - data = hw_read_20kx(hw, GPIO_DATA); - data |= 0x2; - hw_write_20kx(hw, GPIO_DATA, data); - mdelay(50); -} - -static void hw_dac_reset(struct hw *hw) -{ - hw_dac_stop(hw); - hw_dac_start(hw); -} - -static int hw_dac_init(struct hw *hw, const struct dac_conf *info) -{ - int err; - u32 data; - int i; - struct regs_cs4382 cs_read = {0}; - struct regs_cs4382 cs_def = { - 0x00000001, /* Mode Control 1 */ - 0x00000000, /* Mode Control 2 */ - 0x00000084, /* Mode Control 3 */ - 0x00000000, /* Filter Control */ - 0x00000000, /* Invert Control */ - 0x00000024, /* Mixing Control Pair 1 */ - 0x00000000, /* Vol Control A1 */ - 0x00000000, /* Vol Control B1 */ - 0x00000024, /* Mixing Control Pair 2 */ - 0x00000000, /* Vol Control A2 */ - 0x00000000, /* Vol Control B2 */ - 0x00000024, /* Mixing Control Pair 3 */ - 0x00000000, /* Vol Control A3 */ - 0x00000000, /* Vol Control B3 */ - 0x00000024, /* Mixing Control Pair 4 */ - 0x00000000, /* Vol Control A4 */ - 0x00000000 /* Vol Control B4 */ - }; - - if (hw->model == CTSB1270) { - hw_dac_stop(hw); - data = hw_read_20kx(hw, GPIO_DATA); - data &= ~0x0600; - if (1 == info->msr) - data |= 0x0000; /* Single Speed Mode 0-50kHz */ - else if (2 == info->msr) - data |= 0x0200; /* Double Speed Mode 50-100kHz */ - else - data |= 0x0600; /* Quad Speed Mode 100-200kHz */ - hw_write_20kx(hw, GPIO_DATA, data); - hw_dac_start(hw); - return 0; - } - - /* Set DAC reset bit as output */ - data = hw_read_20kx(hw, GPIO_CTRL); - data |= 0x02; - hw_write_20kx(hw, GPIO_CTRL, data); - - err = hw20k2_i2c_init(hw, 0x18, 1, 1); - if (err < 0) - goto End; - - for (i = 0; i < 2; i++) { - /* Reset DAC twice just in-case the chip - * didn't initialized properly */ - hw_dac_reset(hw); - hw_dac_reset(hw); - - if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_MC2, &cs_read.mode_control_2)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_MC3, &cs_read.mode_control_3)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_FC, &cs_read.filter_control)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_IC, &cs_read.invert_control)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_XC1, &cs_read.mix_control_P1)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCA1, &cs_read.vol_control_A1)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCB1, &cs_read.vol_control_B1)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_XC2, &cs_read.mix_control_P2)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCA2, &cs_read.vol_control_A2)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCB2, &cs_read.vol_control_B2)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_XC3, &cs_read.mix_control_P3)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCA3, &cs_read.vol_control_A3)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCB3, &cs_read.vol_control_B3)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_XC4, &cs_read.mix_control_P4)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCA4, &cs_read.vol_control_A4)) - continue; - - if (hw20k2_i2c_read(hw, CS4382_VCB4, &cs_read.vol_control_B4)) - continue; - - if (memcmp(&cs_read, &cs_def, sizeof(cs_read))) - continue; - else - break; - } - - if (i >= 2) - goto End; - - /* Note: Every I2C write must have some delay. - * This is not a requirement but the delay works here... */ - hw20k2_i2c_write(hw, CS4382_MC1, 0x80); - hw20k2_i2c_write(hw, CS4382_MC2, 0x10); - if (1 == info->msr) { - hw20k2_i2c_write(hw, CS4382_XC1, 0x24); - hw20k2_i2c_write(hw, CS4382_XC2, 0x24); - hw20k2_i2c_write(hw, CS4382_XC3, 0x24); - hw20k2_i2c_write(hw, CS4382_XC4, 0x24); - } else if (2 == info->msr) { - hw20k2_i2c_write(hw, CS4382_XC1, 0x25); - hw20k2_i2c_write(hw, CS4382_XC2, 0x25); - hw20k2_i2c_write(hw, CS4382_XC3, 0x25); - hw20k2_i2c_write(hw, CS4382_XC4, 0x25); - } else { - hw20k2_i2c_write(hw, CS4382_XC1, 0x26); - hw20k2_i2c_write(hw, CS4382_XC2, 0x26); - hw20k2_i2c_write(hw, CS4382_XC3, 0x26); - hw20k2_i2c_write(hw, CS4382_XC4, 0x26); - } - - return 0; -End: - - hw20k2_i2c_uninit(hw); - return -1; -} - -/* ADC operations */ -#define MAKE_WM8775_ADDR(addr, data) (u32)(((addr<<1)&0xFE)|((data>>8)&0x1)) -#define MAKE_WM8775_DATA(data) (u32)(data&0xFF) - -#define WM8775_IC 0x0B -#define WM8775_MMC 0x0C -#define WM8775_AADCL 0x0E -#define WM8775_AADCR 0x0F -#define WM8775_ADCMC 0x15 -#define WM8775_RESET 0x17 - -static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) -{ - u32 data; - if (hw->model == CTSB1270) { - /* Titanium HD has two ADC chips, one for line in and one */ - /* for MIC. We don't need to switch the ADC input. */ - return 1; - } - data = hw_read_20kx(hw, GPIO_DATA); - switch (type) { - case ADC_MICIN: - data = (data & (0x1 << 14)) ? 1 : 0; - break; - case ADC_LINEIN: - data = (data & (0x1 << 14)) ? 0 : 1; - break; - default: - data = 0; - } - return data; -} - -#define MIC_BOOST_0DB 0xCF -#define MIC_BOOST_STEPS_PER_DB 2 - -static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db) -{ - u32 adcmc, gain; - - if (input > 3) - input = 3; - - adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */ - - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc), - MAKE_WM8775_DATA(adcmc)); - - if (gain_in_db < -103) - gain_in_db = -103; - if (gain_in_db > 24) - gain_in_db = 24; - - gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB; - - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain), - MAKE_WM8775_DATA(gain)); - /* ...so there should be no need for the following. */ - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain), - MAKE_WM8775_DATA(gain)); -} - -static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) -{ - u32 data; - data = hw_read_20kx(hw, GPIO_DATA); - switch (type) { - case ADC_MICIN: - data |= (0x1 << 14); - hw_write_20kx(hw, GPIO_DATA, data); - hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */ - break; - case ADC_LINEIN: - data &= ~(0x1 << 14); - hw_write_20kx(hw, GPIO_DATA, data); - hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */ - break; - default: - break; - } - - return 0; -} - -static int hw_adc_init(struct hw *hw, const struct adc_conf *info) -{ - int err; - u32 data, ctl; - - /* Set ADC reset bit as output */ - data = hw_read_20kx(hw, GPIO_CTRL); - data |= (0x1 << 15); - hw_write_20kx(hw, GPIO_CTRL, data); - - /* Initialize I2C */ - err = hw20k2_i2c_init(hw, 0x1A, 1, 1); - if (err < 0) { - printk(KERN_ALERT "ctxfi: Failure to acquire I2C!!!\n"); - goto error; - } - - /* Reset the ADC (reset is active low). */ - data = hw_read_20kx(hw, GPIO_DATA); - data &= ~(0x1 << 15); - hw_write_20kx(hw, GPIO_DATA, data); - - if (hw->model == CTSB1270) { - /* Set up the PCM4220 ADC on Titanium HD */ - data &= ~0x0C; - if (1 == info->msr) - data |= 0x00; /* Single Speed Mode 32-50kHz */ - else if (2 == info->msr) - data |= 0x08; /* Double Speed Mode 50-108kHz */ - else - data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */ - hw_write_20kx(hw, GPIO_DATA, data); - } - - mdelay(10); - /* Return the ADC to normal operation. */ - data |= (0x1 << 15); - hw_write_20kx(hw, GPIO_DATA, data); - mdelay(50); - - /* I2C write to register offset 0x0B to set ADC LRCLK polarity */ - /* invert bit, interface format to I2S, word length to 24-bit, */ - /* enable ADC high pass filter. Fixes bug 5323? */ - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26), - MAKE_WM8775_DATA(0x26)); - - /* Set the master mode (256fs) */ - if (1 == info->msr) { - /* slave mode, 128x oversampling 256fs */ - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02), - MAKE_WM8775_DATA(0x02)); - } else if ((2 == info->msr) || (4 == info->msr)) { - /* slave mode, 64x oversampling, 256fs */ - hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A), - MAKE_WM8775_DATA(0x0A)); - } else { - printk(KERN_ALERT "ctxfi: Invalid master sampling " - "rate (msr %d)!!!\n", info->msr); - err = -EINVAL; - goto error; - } - - if (hw->model != CTSB1270) { - /* Configure GPIO bit 14 change to line-in/mic-in */ - ctl = hw_read_20kx(hw, GPIO_CTRL); - ctl |= 0x1 << 14; - hw_write_20kx(hw, GPIO_CTRL, ctl); - hw_adc_input_select(hw, ADC_LINEIN); - } else { - hw_wm8775_input_select(hw, 0, 0); - } - - return 0; -error: - hw20k2_i2c_uninit(hw); - return err; -} - -static struct capabilities hw_capabilities(struct hw *hw) -{ - struct capabilities cap; - - cap.digit_io_switch = 0; - cap.dedicated_mic = hw->model == CTSB1270; - cap.output_switch = hw->model == CTSB1270; - cap.mic_source_switch = hw->model == CTSB1270; - - return cap; -} - -static int hw_output_switch_get(struct hw *hw) -{ - u32 data = hw_read_20kx(hw, GPIO_EXT_DATA); - - switch (data & 0x30) { - case 0x00: - return 0; - case 0x10: - return 1; - case 0x20: - return 2; - default: - return 3; - } -} - -static int hw_output_switch_put(struct hw *hw, int position) -{ - u32 data; - - if (position == hw_output_switch_get(hw)) - return 0; - - /* Mute line and headphones (intended for anti-pop). */ - data = hw_read_20kx(hw, GPIO_DATA); - data |= (0x03 << 11); - hw_write_20kx(hw, GPIO_DATA, data); - - data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30; - switch (position) { - case 0: - break; - case 1: - data |= 0x10; - break; - default: - data |= 0x20; - } - hw_write_20kx(hw, GPIO_EXT_DATA, data); - - /* Unmute line and headphones. */ - data = hw_read_20kx(hw, GPIO_DATA); - data &= ~(0x03 << 11); - hw_write_20kx(hw, GPIO_DATA, data); - - return 1; -} - -static int hw_mic_source_switch_get(struct hw *hw) -{ - struct hw20k2 *hw20k2 = (struct hw20k2 *)hw; - - return hw20k2->mic_source; -} - -static int hw_mic_source_switch_put(struct hw *hw, int position) -{ - struct hw20k2 *hw20k2 = (struct hw20k2 *)hw; - - if (position == hw20k2->mic_source) - return 0; - - switch (position) { - case 0: - hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */ - break; - case 1: - hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */ - break; - case 2: - hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */ - break; - default: - return 0; - } - - hw20k2->mic_source = position; - - return 1; -} - -static irqreturn_t ct_20k2_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; - struct pci_dev *pci = hw->pci; - unsigned int gctl; - - err = pci_enable_device(pci); - if (err < 0) - return err; - - /* Set DMA transfer mask */ - 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 "ctxfi: architecture does not support PCI " - "busmaster DMA with mask 0x%llx\n", CT_XFI_DMA_MASK); - err = -ENXIO; - goto error1; - } - - if (!hw->io_base) { - err = pci_request_regions(pci, "XFi"); - if (err < 0) - goto error1; - - hw->io_base = pci_resource_start(hw->pci, 2); - hw->mem_base = (unsigned long)ioremap(hw->io_base, - pci_resource_len(hw->pci, 2)); - if (!hw->mem_base) { - err = -ENOENT; - goto error2; - } - } - - /* Switch to 20k2 mode from UAA mode. */ - gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL); - set_field(&gctl, GCTL_UAA, 0); - hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); - - if (hw->irq < 0) { - err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED, - KBUILD_MODNAME, 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); - - return 0; - -/*error3: - iounmap((void *)hw->mem_base); - hw->mem_base = (unsigned long)NULL;*/ -error2: - pci_release_regions(pci); - hw->io_base = 0; -error1: - pci_disable_device(pci); - return err; -} - -static int hw_card_stop(struct hw *hw) -{ - unsigned int data; - - /* disable transport bus master and queueing of request */ - hw_write_20kx(hw, TRANSPORT_CTL, 0x00); - - /* disable pll */ - data = hw_read_20kx(hw, PLL_ENB); - hw_write_20kx(hw, PLL_ENB, (data & (~0x07))); - - /* 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 (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; - 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/memory base address and - * do 20kx core switch if needed. */ - 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; - - gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL); - set_field(&gctl, GCTL_DBP, 1); - set_field(&gctl, GCTL_TBP, 1); - set_field(&gctl, GCTL_FBP, 1); - set_field(&gctl, GCTL_DPC, 0); - hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); - - /* Reset all global pending interrupts */ - hw_write_20kx(hw, GIE, 0); - /* Reset all SRC pending interrupts */ - hw_write_20kx(hw, SRC_IP, 0); - - if (hw->model != CTSB1270) { - /* TODO: detect the card ID and configure GPIO accordingly. */ - /* Configures GPIO (0xD802 0x98028) */ - /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/ - /* Configures GPIO (SB0880) */ - /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/ - hw_write_20kx(hw, GPIO_CTRL, 0xD802); - } else { - hw_write_20kx(hw, GPIO_CTRL, 0x9E5F); - } - /* Enable audio ring */ - hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01); - - 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, SRC_MCTL); - data |= 0x1; /* Enables input from the audio ring */ - hw_write_20kx(hw, SRC_MCTL, data); - - return 0; -} - -#ifdef CONFIG_PM -static int hw_suspend(struct hw *hw, pm_message_t state) -{ - struct pci_dev *pci = hw->pci; - - hw_card_stop(hw); - - pci_disable_device(pci); - pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); - - return 0; -} - -static int hw_resume(struct hw *hw, struct card_conf *info) -{ - struct pci_dev *pci = hw->pci; - - pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); - - /* Re-initialize card hardware. */ - return hw_card_init(hw, info); -} -#endif - -static u32 hw_read_20kx(struct hw *hw, u32 reg) -{ - return readl((void *)(hw->mem_base + reg)); -} - -static void hw_write_20kx(struct hw *hw, u32 reg, u32 data) -{ - writel(data, (void *)(hw->mem_base + reg)); -} - -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, - .capabilities = hw_capabilities, - .output_switch_get = hw_output_switch_get, - .output_switch_put = hw_output_switch_put, - .mic_source_switch_get = hw_mic_source_switch_get, - .mic_source_switch_put = hw_mic_source_switch_put, -#ifdef CONFIG_PM - .suspend = hw_suspend, - .resume = hw_resume, -#endif - - .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, - - .set_timer_irq = set_timer_irq, - .set_timer_tick = set_timer_tick, - .get_wc = get_wc, -}; - -int __devinit create_20k2_hw_obj(struct hw **rhw) -{ - struct hw20k2 *hw20k2; - - *rhw = NULL; - hw20k2 = kzalloc(sizeof(*hw20k2), GFP_KERNEL); - if (!hw20k2) - return -ENOMEM; - - hw20k2->hw = ct20k2_preset; - *rhw = &hw20k2->hw; - - return 0; -} - -int destroy_20k2_hw_obj(struct hw *hw) -{ - if (hw->io_base) - hw_card_shutdown(hw); - - kfree(hw); - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.h b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.h deleted file mode 100644 index d2b7daab..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * 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 cthw20k2.h - * - * @Brief - * This file contains the definition of hardware access methord. - * - * @Author Liu Chun - * @Date May 13 2008 - * - */ - -#ifndef CTHW20K2_H -#define CTHW20K2_H - -#include "cthardware.h" - -int create_20k2_hw_obj(struct hw **rhw); -int destroy_20k2_hw_obj(struct hw *hw); - -#endif /* CTHW20K2_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.c deleted file mode 100644 index 0b73368a..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 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 ctimap.c - * - * @Brief - * This file contains the implementation of generic input mapper operations - * for input mapper management. - * - * @Author Liu Chun - * @Date May 23 2008 - * - */ - -#include "ctimap.h" -#include <linux/slab.h> - -int input_mapper_add(struct list_head *mappers, struct imapper *entry, - int (*map_op)(void *, struct imapper *), void *data) -{ - struct list_head *pos, *pre, *head; - struct imapper *pre_ent, *pos_ent; - - head = mappers; - - if (list_empty(head)) { - entry->next = entry->addr; - map_op(data, entry); - list_add(&entry->list, head); - return 0; - } - - list_for_each(pos, head) { - pos_ent = list_entry(pos, struct imapper, list); - if (pos_ent->slot > entry->slot) { - /* found a position in list */ - break; - } - } - - if (pos != head) { - pre = pos->prev; - if (pre == head) - pre = head->prev; - - __list_add(&entry->list, pos->prev, pos); - } else { - pre = head->prev; - pos = head->next; - list_add_tail(&entry->list, head); - } - - pre_ent = list_entry(pre, struct imapper, list); - pos_ent = list_entry(pos, struct imapper, list); - - entry->next = pos_ent->addr; - map_op(data, entry); - pre_ent->next = entry->addr; - map_op(data, pre_ent); - - return 0; -} - -int input_mapper_delete(struct list_head *mappers, struct imapper *entry, - int (*map_op)(void *, struct imapper *), void *data) -{ - struct list_head *next, *pre, *head; - struct imapper *pre_ent, *next_ent; - - head = mappers; - - if (list_empty(head)) - return 0; - - pre = (entry->list.prev == head) ? head->prev : entry->list.prev; - next = (entry->list.next == head) ? head->next : entry->list.next; - - if (pre == &entry->list) { - /* entry is the only one node in mappers list */ - entry->next = entry->addr = entry->user = entry->slot = 0; - map_op(data, entry); - list_del(&entry->list); - return 0; - } - - pre_ent = list_entry(pre, struct imapper, list); - next_ent = list_entry(next, struct imapper, list); - - pre_ent->next = next_ent->addr; - map_op(data, pre_ent); - list_del(&entry->list); - - return 0; -} - -void free_input_mapper_list(struct list_head *head) -{ - struct imapper *entry; - struct list_head *pos; - - while (!list_empty(head)) { - pos = head->next; - list_del(pos); - entry = list_entry(pos, struct imapper, list); - kfree(entry); - } -} - diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.h deleted file mode 100644 index 53ccf9be..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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 ctimap.h - * - * @Brief - * This file contains the definition of generic input mapper operations - * for input mapper management. - * - * @Author Liu Chun - * @Date May 23 2008 - * - */ - -#ifndef CTIMAP_H -#define CTIMAP_H - -#include <linux/list.h> - -struct imapper { - unsigned short slot; /* the id of the slot containing input data */ - unsigned short user; /* the id of the user resource consuming data */ - unsigned short addr; /* the input mapper ram id */ - unsigned short next; /* the next input mapper ram id */ - struct list_head list; -}; - -int input_mapper_add(struct list_head *mappers, struct imapper *entry, - int (*map_op)(void *, struct imapper *), void *data); - -int input_mapper_delete(struct list_head *mappers, struct imapper *entry, - int (*map_op)(void *, struct imapper *), void *data); - -void free_input_mapper_list(struct list_head *mappers); - -#endif /* CTIMAP_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.c deleted file mode 100644 index 0cc13eee..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.c +++ /dev/null @@ -1,1227 +0,0 @@ -/** - * 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 ctmixer.c - * - * @Brief - * This file contains the implementation of alsa mixer device functions. - * - * @Author Liu Chun - * @Date May 28 2008 - * - */ - - -#include "ctmixer.h" -#include "ctamixer.h" -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/control.h> -#include <sound/asoundef.h> -#include <sound/pcm.h> -#include <sound/tlv.h> - -enum CT_SUM_CTL { - SUM_IN_F, - SUM_IN_R, - SUM_IN_C, - SUM_IN_S, - SUM_IN_F_C, - - NUM_CT_SUMS -}; - -enum CT_AMIXER_CTL { - /* volume control mixers */ - AMIXER_MASTER_F, - AMIXER_MASTER_R, - AMIXER_MASTER_C, - AMIXER_MASTER_S, - AMIXER_PCM_F, - AMIXER_PCM_R, - AMIXER_PCM_C, - AMIXER_PCM_S, - AMIXER_SPDIFI, - AMIXER_LINEIN, - AMIXER_MIC, - AMIXER_SPDIFO, - AMIXER_WAVE_F, - AMIXER_WAVE_R, - AMIXER_WAVE_C, - AMIXER_WAVE_S, - AMIXER_MASTER_F_C, - AMIXER_PCM_F_C, - AMIXER_SPDIFI_C, - AMIXER_LINEIN_C, - AMIXER_MIC_C, - - /* this should always be the last one */ - NUM_CT_AMIXERS -}; - -enum CTALSA_MIXER_CTL { - /* volume control mixers */ - MIXER_MASTER_P, - MIXER_PCM_P, - MIXER_LINEIN_P, - MIXER_MIC_P, - MIXER_SPDIFI_P, - MIXER_SPDIFO_P, - MIXER_WAVEF_P, - MIXER_WAVER_P, - MIXER_WAVEC_P, - MIXER_WAVES_P, - MIXER_MASTER_C, - MIXER_PCM_C, - MIXER_LINEIN_C, - MIXER_MIC_C, - MIXER_SPDIFI_C, - - /* switch control mixers */ - MIXER_PCM_C_S, - MIXER_LINEIN_C_S, - MIXER_MIC_C_S, - MIXER_SPDIFI_C_S, - MIXER_SPDIFO_P_S, - MIXER_WAVEF_P_S, - MIXER_WAVER_P_S, - MIXER_WAVEC_P_S, - MIXER_WAVES_P_S, - MIXER_DIGITAL_IO_S, - MIXER_IEC958_MASK, - MIXER_IEC958_DEFAULT, - MIXER_IEC958_STREAM, - - /* this should always be the last one */ - NUM_CTALSA_MIXERS -}; - -#define VOL_MIXER_START MIXER_MASTER_P -#define VOL_MIXER_END MIXER_SPDIFI_C -#define VOL_MIXER_NUM (VOL_MIXER_END - VOL_MIXER_START + 1) -#define SWH_MIXER_START MIXER_PCM_C_S -#define SWH_MIXER_END MIXER_DIGITAL_IO_S -#define SWH_CAPTURE_START MIXER_PCM_C_S -#define SWH_CAPTURE_END MIXER_SPDIFI_C_S - -#define CHN_NUM 2 - -struct ct_kcontrol_init { - unsigned char ctl; - char *name; -}; - -static struct ct_kcontrol_init -ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = { - [MIXER_MASTER_P] = { - .ctl = 1, - .name = "Master Playback Volume", - }, - [MIXER_MASTER_C] = { - .ctl = 1, - .name = "Master Capture Volume", - }, - [MIXER_PCM_P] = { - .ctl = 1, - .name = "PCM Playback Volume", - }, - [MIXER_PCM_C] = { - .ctl = 1, - .name = "PCM Capture Volume", - }, - [MIXER_LINEIN_P] = { - .ctl = 1, - .name = "Line Playback Volume", - }, - [MIXER_LINEIN_C] = { - .ctl = 1, - .name = "Line Capture Volume", - }, - [MIXER_MIC_P] = { - .ctl = 1, - .name = "Mic Playback Volume", - }, - [MIXER_MIC_C] = { - .ctl = 1, - .name = "Mic Capture Volume", - }, - [MIXER_SPDIFI_P] = { - .ctl = 1, - .name = "IEC958 Playback Volume", - }, - [MIXER_SPDIFI_C] = { - .ctl = 1, - .name = "IEC958 Capture Volume", - }, - [MIXER_SPDIFO_P] = { - .ctl = 1, - .name = "Digital Playback Volume", - }, - [MIXER_WAVEF_P] = { - .ctl = 1, - .name = "Front Playback Volume", - }, - [MIXER_WAVES_P] = { - .ctl = 1, - .name = "Side Playback Volume", - }, - [MIXER_WAVEC_P] = { - .ctl = 1, - .name = "Center/LFE Playback Volume", - }, - [MIXER_WAVER_P] = { - .ctl = 1, - .name = "Surround Playback Volume", - }, - [MIXER_PCM_C_S] = { - .ctl = 1, - .name = "PCM Capture Switch", - }, - [MIXER_LINEIN_C_S] = { - .ctl = 1, - .name = "Line Capture Switch", - }, - [MIXER_MIC_C_S] = { - .ctl = 1, - .name = "Mic Capture Switch", - }, - [MIXER_SPDIFI_C_S] = { - .ctl = 1, - .name = "IEC958 Capture Switch", - }, - [MIXER_SPDIFO_P_S] = { - .ctl = 1, - .name = "Digital Playback Switch", - }, - [MIXER_WAVEF_P_S] = { - .ctl = 1, - .name = "Front Playback Switch", - }, - [MIXER_WAVES_P_S] = { - .ctl = 1, - .name = "Side Playback Switch", - }, - [MIXER_WAVEC_P_S] = { - .ctl = 1, - .name = "Center/LFE Playback Switch", - }, - [MIXER_WAVER_P_S] = { - .ctl = 1, - .name = "Surround Playback Switch", - }, - [MIXER_DIGITAL_IO_S] = { - .ctl = 0, - .name = "Digit-IO Playback Switch", - }, -}; - -static void -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); - -/* FIXME: this static looks like it would fail if more than one card was */ -/* installed. */ -static struct snd_kcontrol *kctls[2] = {NULL}; - -static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index) -{ - switch (alsa_index) { - case MIXER_MASTER_P: return AMIXER_MASTER_F; - case MIXER_MASTER_C: return AMIXER_MASTER_F_C; - case MIXER_PCM_P: return AMIXER_PCM_F; - case MIXER_PCM_C: - case MIXER_PCM_C_S: return AMIXER_PCM_F_C; - case MIXER_LINEIN_P: return AMIXER_LINEIN; - case MIXER_LINEIN_C: - case MIXER_LINEIN_C_S: return AMIXER_LINEIN_C; - case MIXER_MIC_P: return AMIXER_MIC; - case MIXER_MIC_C: - case MIXER_MIC_C_S: return AMIXER_MIC_C; - case MIXER_SPDIFI_P: return AMIXER_SPDIFI; - case MIXER_SPDIFI_C: - case MIXER_SPDIFI_C_S: return AMIXER_SPDIFI_C; - case MIXER_SPDIFO_P: return AMIXER_SPDIFO; - case MIXER_WAVEF_P: return AMIXER_WAVE_F; - case MIXER_WAVES_P: return AMIXER_WAVE_S; - case MIXER_WAVEC_P: return AMIXER_WAVE_C; - case MIXER_WAVER_P: return AMIXER_WAVE_R; - default: return NUM_CT_AMIXERS; - } -} - -static enum CT_AMIXER_CTL get_recording_amixer(enum CT_AMIXER_CTL index) -{ - switch (index) { - case AMIXER_MASTER_F: return AMIXER_MASTER_F_C; - case AMIXER_PCM_F: return AMIXER_PCM_F_C; - case AMIXER_SPDIFI: return AMIXER_SPDIFI_C; - case AMIXER_LINEIN: return AMIXER_LINEIN_C; - case AMIXER_MIC: return AMIXER_MIC_C; - default: return NUM_CT_AMIXERS; - } -} - -static unsigned char -get_switch_state(struct ct_mixer *mixer, enum CTALSA_MIXER_CTL type) -{ - return (mixer->switch_state & (0x1 << (type - SWH_MIXER_START))) - ? 1 : 0; -} - -static void -set_switch_state(struct ct_mixer *mixer, - enum CTALSA_MIXER_CTL type, unsigned char state) -{ - if (state) - mixer->switch_state |= (0x1 << (type - SWH_MIXER_START)); - else - mixer->switch_state &= ~(0x1 << (type - SWH_MIXER_START)); -} - -#if 0 /* not used */ -/* Map integer value ranging from 0 to 65535 to 14-bit float value ranging - * from 2^-6 to (1+1023/1024) */ -static unsigned int uint16_to_float14(unsigned int x) -{ - unsigned int i; - - if (x < 17) - return 0; - - x *= 2031; - x /= 65535; - x += 16; - - /* i <= 6 */ - for (i = 0; !(x & 0x400); i++) - x <<= 1; - - x = (((7 - i) & 0x7) << 10) | (x & 0x3ff); - - return x; -} - -static unsigned int float14_to_uint16(unsigned int x) -{ - unsigned int e; - - if (!x) - return x; - - e = (x >> 10) & 0x7; - x &= 0x3ff; - x += 1024; - x >>= (7 - e); - x -= 16; - x *= 65535; - x /= 2031; - - return x; -} -#endif /* not used */ - -#define VOL_SCALE 0x1c -#define VOL_MAX 0x100 - -static const DECLARE_TLV_DB_SCALE(ct_vol_db_scale, -6400, 25, 1); - -static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = VOL_MAX; - - return 0; -} - -static int ct_alsa_mix_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); - struct amixer *amixer; - int i, val; - - for (i = 0; i < 2; i++) { - amixer = ((struct ct_mixer *)atc->mixer)-> - amixers[type*CHN_NUM+i]; - val = amixer->ops->get_scale(amixer) / VOL_SCALE; - if (val < 0) - val = 0; - else if (val > VOL_MAX) - val = VOL_MAX; - ucontrol->value.integer.value[i] = val; - } - - return 0; -} - -static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - struct ct_mixer *mixer = atc->mixer; - enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value); - struct amixer *amixer; - int i, j, val, oval, change = 0; - - for (i = 0; i < 2; i++) { - val = ucontrol->value.integer.value[i]; - if (val < 0) - val = 0; - else if (val > VOL_MAX) - val = VOL_MAX; - val *= VOL_SCALE; - amixer = mixer->amixers[type*CHN_NUM+i]; - oval = amixer->ops->get_scale(amixer); - if (val != oval) { - amixer->ops->set_scale(amixer, val); - amixer->ops->commit_write(amixer); - change = 1; - /* Synchronize Master/PCM playback AMIXERs. */ - if (AMIXER_MASTER_F == type || AMIXER_PCM_F == type) { - for (j = 1; j < 4; j++) { - amixer = mixer-> - amixers[(type+j)*CHN_NUM+i]; - amixer->ops->set_scale(amixer, val); - amixer->ops->commit_write(amixer); - } - } - } - } - - return change; -} - -static struct snd_kcontrol_new vol_ctl = { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = ct_alsa_mix_volume_info, - .get = ct_alsa_mix_volume_get, - .put = ct_alsa_mix_volume_put, - .tlv = { .p = ct_vol_db_scale }, -}; - -static int output_switch_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - static const char *const names[3] = { - "FP Headphones", "Headphones", "Speakers" - }; - - return snd_ctl_enum_info(info, 1, 3, names); -} - -static int output_switch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = atc->output_switch_get(atc); - return 0; -} - -static int output_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - if (ucontrol->value.enumerated.item[0] > 2) - return -EINVAL; - return atc->output_switch_put(atc, ucontrol->value.enumerated.item[0]); -} - -static struct snd_kcontrol_new output_ctl = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Output Playback Enum", - .info = output_switch_info, - .get = output_switch_get, - .put = output_switch_put, -}; - -static int mic_source_switch_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - static const char *const names[3] = { - "Mic", "FP Mic", "Aux" - }; - - return snd_ctl_enum_info(info, 1, 3, names); -} - -static int mic_source_switch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = atc->mic_source_switch_get(atc); - return 0; -} - -static int mic_source_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - if (ucontrol->value.enumerated.item[0] > 2) - return -EINVAL; - return atc->mic_source_switch_put(atc, - ucontrol->value.enumerated.item[0]); -} - -static struct snd_kcontrol_new mic_source_ctl = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Source Capture Enum", - .info = mic_source_switch_info, - .get = mic_source_switch_get, - .put = mic_source_switch_put, -}; - -static void -do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type) -{ - - if (MIXER_LINEIN_C_S == type) { - atc->select_line_in(atc); - set_switch_state(atc->mixer, MIXER_MIC_C_S, 0); - snd_ctl_notify(atc->card, SNDRV_CTL_EVENT_MASK_VALUE, - &kctls[1]->id); - } else if (MIXER_MIC_C_S == type) { - atc->select_mic_in(atc); - set_switch_state(atc->mixer, MIXER_LINEIN_C_S, 0); - snd_ctl_notify(atc->card, SNDRV_CTL_EVENT_MASK_VALUE, - &kctls[0]->id); - } -} - -static void -do_digit_io_switch(struct ct_atc *atc, int state) -{ - struct ct_mixer *mixer = atc->mixer; - - if (state) { - atc->select_digit_io(atc); - atc->spdif_out_unmute(atc, - get_switch_state(mixer, MIXER_SPDIFO_P_S)); - atc->spdif_in_unmute(atc, 1); - atc->line_in_unmute(atc, 0); - return; - } - - if (get_switch_state(mixer, MIXER_LINEIN_C_S)) - atc->select_line_in(atc); - else if (get_switch_state(mixer, MIXER_MIC_C_S)) - atc->select_mic_in(atc); - - atc->spdif_out_unmute(atc, 0); - atc->spdif_in_unmute(atc, 0); - atc->line_in_unmute(atc, 1); - return; -} - -static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state) -{ - struct ct_mixer *mixer = atc->mixer; - struct capabilities cap = atc->capabilities(atc); - - /* Do changes in mixer. */ - if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) { - if (state) { - ct_mixer_recording_select(mixer, - get_amixer_index(type)); - } else { - ct_mixer_recording_unselect(mixer, - get_amixer_index(type)); - } - } - /* Do changes out of mixer. */ - if (!cap.dedicated_mic && - (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) { - if (state) - do_line_mic_switch(atc, type); - atc->line_in_unmute(atc, state); - } else if (cap.dedicated_mic && (MIXER_LINEIN_C_S == type)) - atc->line_in_unmute(atc, state); - else if (cap.dedicated_mic && (MIXER_MIC_C_S == type)) - atc->mic_unmute(atc, state); - else if (MIXER_SPDIFI_C_S == type) - atc->spdif_in_unmute(atc, state); - else if (MIXER_WAVEF_P_S == type) - atc->line_front_unmute(atc, state); - else if (MIXER_WAVES_P_S == type) - atc->line_surround_unmute(atc, state); - else if (MIXER_WAVEC_P_S == type) - atc->line_clfe_unmute(atc, state); - else if (MIXER_WAVER_P_S == type) - atc->line_rear_unmute(atc, state); - else if (MIXER_SPDIFO_P_S == type) - atc->spdif_out_unmute(atc, state); - else if (MIXER_DIGITAL_IO_S == type) - do_digit_io_switch(atc, state); - - return; -} - -static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - uinfo->value.integer.step = 1; - - return 0; -} - -static int ct_alsa_mix_switch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_mixer *mixer = - ((struct ct_atc *)snd_kcontrol_chip(kcontrol))->mixer; - enum CTALSA_MIXER_CTL type = kcontrol->private_value; - - ucontrol->value.integer.value[0] = get_switch_state(mixer, type); - return 0; -} - -static int ct_alsa_mix_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct ct_atc *atc = snd_kcontrol_chip(kcontrol); - struct ct_mixer *mixer = atc->mixer; - enum CTALSA_MIXER_CTL type = kcontrol->private_value; - int state; - - state = ucontrol->value.integer.value[0]; - if (get_switch_state(mixer, type) == state) - return 0; - - set_switch_state(mixer, type, state); - do_switch(atc, type, state); - - return 1; -} - -static struct snd_kcontrol_new swh_ctl = { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = ct_alsa_mix_switch_info, - .get = ct_alsa_mix_switch_get, - .put = ct_alsa_mix_switch_put -}; - -static int ct_spdif_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - return 0; -} - -static int ct_spdif_get_mask(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.iec958.status[0] = 0xff; - ucontrol->value.iec958.status[1] = 0xff; - ucontrol->value.iec958.status[2] = 0xff; - ucontrol->value.iec958.status[3] = 0xff; - return 0; -} - -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; - - atc->spdif_out_get_status(atc, &status); - - if (status == 0) - status = SNDRV_PCM_DEFAULT_CON_SPDIF; - - ucontrol->value.iec958.status[0] = (status >> 0) & 0xff; - ucontrol->value.iec958.status[1] = (status >> 8) & 0xff; - ucontrol->value.iec958.status[2] = (status >> 16) & 0xff; - ucontrol->value.iec958.status[3] = (status >> 24) & 0xff; - - return 0; -} - -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; - unsigned int status, old_status; - - status = (ucontrol->value.iec958.status[0] << 0) | - (ucontrol->value.iec958.status[1] << 8) | - (ucontrol->value.iec958.status[2] << 16) | - (ucontrol->value.iec958.status[3] << 24); - - atc->spdif_out_get_status(atc, &old_status); - change = (old_status != status); - if (change) - atc->spdif_out_set_status(atc, status); - - return change; -} - -static struct snd_kcontrol_new iec958_mask_ctl = { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK), - .count = 1, - .info = ct_spdif_info, - .get = ct_spdif_get_mask, - .private_value = MIXER_IEC958_MASK -}; - -static struct snd_kcontrol_new iec958_default_ctl = { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), - .count = 1, - .info = ct_spdif_info, - .get = ct_spdif_get, - .put = ct_spdif_put, - .private_value = MIXER_IEC958_DEFAULT -}; - -static struct snd_kcontrol_new iec958_ctl = { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), - .count = 1, - .info = ct_spdif_info, - .get = ct_spdif_get, - .put = ct_spdif_put, - .private_value = MIXER_IEC958_STREAM -}; - -#define NUM_IEC958_CTL 3 - -static int -ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new) -{ - struct snd_kcontrol *kctl; - int err; - - kctl = snd_ctl_new1(new, mixer->atc); - if (!kctl) - return -ENOMEM; - - if (SNDRV_CTL_ELEM_IFACE_PCM == kctl->id.iface) - kctl->id.device = IEC958; - - err = snd_ctl_add(mixer->atc->card, kctl); - if (err) - return err; - - switch (new->private_value) { - case MIXER_LINEIN_C_S: - kctls[0] = kctl; break; - case MIXER_MIC_C_S: - kctls[1] = kctl; break; - default: - break; - } - - return 0; -} - -static int ct_mixer_kcontrols_create(struct ct_mixer *mixer) -{ - enum CTALSA_MIXER_CTL type; - struct ct_atc *atc = mixer->atc; - struct capabilities cap = atc->capabilities(atc); - int err; - - /* Create snd kcontrol instances on demand */ - for (type = VOL_MIXER_START; type <= VOL_MIXER_END; type++) { - if (ct_kcontrol_init_table[type].ctl) { - vol_ctl.name = ct_kcontrol_init_table[type].name; - vol_ctl.private_value = (unsigned long)type; - err = ct_mixer_kcontrol_new(mixer, &vol_ctl); - if (err) - return err; - } - } - - ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = cap.digit_io_switch; - - for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) { - if (ct_kcontrol_init_table[type].ctl) { - swh_ctl.name = ct_kcontrol_init_table[type].name; - swh_ctl.private_value = (unsigned long)type; - err = ct_mixer_kcontrol_new(mixer, &swh_ctl); - if (err) - return err; - } - } - - err = ct_mixer_kcontrol_new(mixer, &iec958_mask_ctl); - if (err) - return err; - - err = ct_mixer_kcontrol_new(mixer, &iec958_default_ctl); - if (err) - return err; - - err = ct_mixer_kcontrol_new(mixer, &iec958_ctl); - if (err) - return err; - - if (cap.output_switch) { - err = ct_mixer_kcontrol_new(mixer, &output_ctl); - if (err) - return err; - } - - if (cap.mic_source_switch) { - err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl); - if (err) - return err; - } - atc->line_front_unmute(atc, 1); - set_switch_state(mixer, MIXER_WAVEF_P_S, 1); - atc->line_surround_unmute(atc, 0); - set_switch_state(mixer, MIXER_WAVES_P_S, 0); - atc->line_clfe_unmute(atc, 0); - set_switch_state(mixer, MIXER_WAVEC_P_S, 0); - atc->line_rear_unmute(atc, 0); - set_switch_state(mixer, MIXER_WAVER_P_S, 0); - atc->spdif_out_unmute(atc, 0); - set_switch_state(mixer, MIXER_SPDIFO_P_S, 0); - atc->line_in_unmute(atc, 0); - if (cap.dedicated_mic) - atc->mic_unmute(atc, 0); - atc->spdif_in_unmute(atc, 0); - set_switch_state(mixer, MIXER_PCM_C_S, 0); - set_switch_state(mixer, MIXER_LINEIN_C_S, 0); - set_switch_state(mixer, MIXER_SPDIFI_C_S, 0); - - return 0; -} - -static void -ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type) -{ - struct amixer *amix_d; - struct sum *sum_c; - int i; - - for (i = 0; i < 2; i++) { - amix_d = mixer->amixers[type*CHN_NUM+i]; - sum_c = mixer->sums[SUM_IN_F_C*CHN_NUM+i]; - amix_d->ops->set_sum(amix_d, sum_c); - amix_d->ops->commit_write(amix_d); - } -} - -static void -ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type) -{ - struct amixer *amix_d; - int i; - - for (i = 0; i < 2; i++) { - amix_d = mixer->amixers[type*CHN_NUM+i]; - amix_d->ops->set_sum(amix_d, NULL); - amix_d->ops->commit_write(amix_d); - } -} - -static int ct_mixer_get_resources(struct ct_mixer *mixer) -{ - struct sum_mgr *sum_mgr; - struct sum *sum; - struct sum_desc sum_desc = {0}; - struct amixer_mgr *amixer_mgr; - struct amixer *amixer; - struct amixer_desc am_desc = {0}; - int err; - int i; - - /* Allocate sum resources for mixer obj */ - sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM]; - sum_desc.msr = mixer->atc->msr; - for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) { - err = sum_mgr->get_sum(sum_mgr, &sum_desc, &sum); - if (err) { - printk(KERN_ERR "ctxfi:Failed to get sum resources for " - "front output!\n"); - break; - } - mixer->sums[i] = sum; - } - if (err) - goto error1; - - /* Allocate amixer resources for mixer obj */ - amixer_mgr = (struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER]; - am_desc.msr = mixer->atc->msr; - for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) { - err = amixer_mgr->get_amixer(amixer_mgr, &am_desc, &amixer); - if (err) { - printk(KERN_ERR "ctxfi:Failed to get amixer resources " - "for mixer obj!\n"); - break; - } - mixer->amixers[i] = amixer; - } - if (err) - goto error2; - - return 0; - -error2: - for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) { - if (NULL != mixer->amixers[i]) { - amixer = mixer->amixers[i]; - amixer_mgr->put_amixer(amixer_mgr, amixer); - mixer->amixers[i] = NULL; - } - } -error1: - for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) { - if (NULL != mixer->sums[i]) { - sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]); - mixer->sums[i] = NULL; - } - } - - return err; -} - -static int ct_mixer_get_mem(struct ct_mixer **rmixer) -{ - struct ct_mixer *mixer; - int err; - - *rmixer = NULL; - /* Allocate mem for mixer obj */ - mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); - if (!mixer) - return -ENOMEM; - - mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM), - GFP_KERNEL); - if (!mixer->amixers) { - err = -ENOMEM; - goto error1; - } - mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL); - if (!mixer->sums) { - err = -ENOMEM; - goto error2; - } - - *rmixer = mixer; - return 0; - -error2: - kfree(mixer->amixers); -error1: - kfree(mixer); - return err; -} - -static int ct_mixer_topology_build(struct ct_mixer *mixer) -{ - struct sum *sum; - struct amixer *amix_d, *amix_s; - enum CT_AMIXER_CTL i, j; - - /* Build topology from destination to source */ - - /* Set up Master mixer */ - for (i = AMIXER_MASTER_F, j = SUM_IN_F; - i <= AMIXER_MASTER_S; i++, j++) { - amix_d = mixer->amixers[i*CHN_NUM]; - sum = mixer->sums[j*CHN_NUM]; - amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); - amix_d = mixer->amixers[i*CHN_NUM+1]; - sum = mixer->sums[j*CHN_NUM+1]; - amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); - } - - /* Set up Wave-out mixer */ - for (i = AMIXER_WAVE_F, j = AMIXER_MASTER_F; - i <= AMIXER_WAVE_S; i++, j++) { - amix_d = mixer->amixers[i*CHN_NUM]; - amix_s = mixer->amixers[j*CHN_NUM]; - amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL); - amix_d = mixer->amixers[i*CHN_NUM+1]; - amix_s = mixer->amixers[j*CHN_NUM+1]; - amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL); - } - - /* Set up S/PDIF-out mixer */ - amix_d = mixer->amixers[AMIXER_SPDIFO*CHN_NUM]; - amix_s = mixer->amixers[AMIXER_MASTER_F*CHN_NUM]; - amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL); - amix_d = mixer->amixers[AMIXER_SPDIFO*CHN_NUM+1]; - amix_s = mixer->amixers[AMIXER_MASTER_F*CHN_NUM+1]; - amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL); - - /* Set up PCM-in mixer */ - for (i = AMIXER_PCM_F, j = SUM_IN_F; i <= AMIXER_PCM_S; i++, j++) { - amix_d = mixer->amixers[i*CHN_NUM]; - sum = mixer->sums[j*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[i*CHN_NUM+1]; - sum = mixer->sums[j*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - } - - /* Set up Line-in mixer */ - amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM]; - sum = mixer->sums[SUM_IN_F*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - - /* Set up Mic-in mixer */ - amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM]; - sum = mixer->sums[SUM_IN_F*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - - /* Set up S/PDIF-in mixer */ - amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM]; - sum = mixer->sums[SUM_IN_F*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - - /* Set up Master recording mixer */ - amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM]; - amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); - amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1]; - amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); - - /* Set up PCM-in recording mixer */ - amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - - /* Set up Line-in recording mixer */ - amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - - /* Set up Mic-in recording mixer */ - amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - - /* Set up S/PDIF-in recording mixer */ - amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM+1]; - sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1]; - amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); - - return 0; -} - -static int mixer_set_input_port(struct amixer *amixer, struct rsc *rsc) -{ - amixer->ops->set_input(amixer, rsc); - amixer->ops->commit_write(amixer); - - return 0; -} - -static enum CT_AMIXER_CTL port_to_amixer(enum MIXER_PORT_T type) -{ - switch (type) { - case MIX_WAVE_FRONT: return AMIXER_WAVE_F; - case MIX_WAVE_SURROUND: return AMIXER_WAVE_S; - case MIX_WAVE_CENTLFE: return AMIXER_WAVE_C; - case MIX_WAVE_REAR: return AMIXER_WAVE_R; - case MIX_PCMO_FRONT: return AMIXER_MASTER_F_C; - case MIX_SPDIF_OUT: return AMIXER_SPDIFO; - case MIX_LINE_IN: return AMIXER_LINEIN; - case MIX_MIC_IN: return AMIXER_MIC; - case MIX_SPDIF_IN: return AMIXER_SPDIFI; - case MIX_PCMI_FRONT: return AMIXER_PCM_F; - case MIX_PCMI_SURROUND: return AMIXER_PCM_S; - case MIX_PCMI_CENTLFE: return AMIXER_PCM_C; - case MIX_PCMI_REAR: return AMIXER_PCM_R; - default: return 0; - } -} - -static int mixer_get_output_ports(struct ct_mixer *mixer, - enum MIXER_PORT_T type, - struct rsc **rleft, struct rsc **rright) -{ - enum CT_AMIXER_CTL amix = port_to_amixer(type); - - if (NULL != rleft) - *rleft = &((struct amixer *)mixer->amixers[amix*CHN_NUM])->rsc; - - if (NULL != rright) - *rright = - &((struct amixer *)mixer->amixers[amix*CHN_NUM+1])->rsc; - - return 0; -} - -static int mixer_set_input_left(struct ct_mixer *mixer, - enum MIXER_PORT_T type, struct rsc *rsc) -{ - enum CT_AMIXER_CTL amix = port_to_amixer(type); - - mixer_set_input_port(mixer->amixers[amix*CHN_NUM], rsc); - amix = get_recording_amixer(amix); - if (amix < NUM_CT_AMIXERS) - mixer_set_input_port(mixer->amixers[amix*CHN_NUM], rsc); - - return 0; -} - -static int -mixer_set_input_right(struct ct_mixer *mixer, - enum MIXER_PORT_T type, struct rsc *rsc) -{ - enum CT_AMIXER_CTL amix = port_to_amixer(type); - - mixer_set_input_port(mixer->amixers[amix*CHN_NUM+1], rsc); - amix = get_recording_amixer(amix); - if (amix < NUM_CT_AMIXERS) - mixer_set_input_port(mixer->amixers[amix*CHN_NUM+1], rsc); - - return 0; -} - -#ifdef CONFIG_PM -static int mixer_resume(struct ct_mixer *mixer) -{ - int i, state; - struct amixer *amixer; - - /* resume topology and volume gain. */ - for (i = 0; i < NUM_CT_AMIXERS*CHN_NUM; i++) { - amixer = mixer->amixers[i]; - amixer->ops->commit_write(amixer); - } - - /* resume switch state. */ - for (i = SWH_MIXER_START; i <= SWH_MIXER_END; i++) { - state = get_switch_state(mixer, i); - do_switch(mixer->atc, i, state); - } - - return 0; -} -#endif - -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; - int i = 0; - - /* Release amixer resources */ - for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) { - if (NULL != mixer->amixers[i]) { - amixer = mixer->amixers[i]; - amixer_mgr->put_amixer(amixer_mgr, amixer); - } - } - - /* Release sum resources */ - for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) { - if (NULL != mixer->sums[i]) - sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]); - } - - /* Release mem assigned to mixer object */ - kfree(mixer->sums); - kfree(mixer->amixers); - kfree(mixer); - - return 0; -} - -int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer) -{ - struct ct_mixer *mixer; - int err; - - *rmixer = NULL; - - /* Allocate mem for mixer obj */ - err = ct_mixer_get_mem(&mixer); - if (err) - return err; - - mixer->switch_state = 0; - mixer->atc = atc; - /* Set operations */ - mixer->get_output_ports = mixer_get_output_ports; - mixer->set_input_left = mixer_set_input_left; - mixer->set_input_right = mixer_set_input_right; -#ifdef CONFIG_PM - mixer->resume = mixer_resume; -#endif - - /* Allocate chip resources for mixer obj */ - err = ct_mixer_get_resources(mixer); - if (err) - goto error; - - /* Build internal mixer topology */ - ct_mixer_topology_build(mixer); - - *rmixer = mixer; - - return 0; - -error: - ct_mixer_destroy(mixer); - return err; -} - -int ct_alsa_mix_create(struct ct_atc *atc, - enum CTALSADEVS device, - const char *device_name) -{ - int err; - - /* Create snd kcontrol instances on demand */ - /* vol_ctl.device = swh_ctl.device = device; */ /* better w/ device 0 */ - err = ct_mixer_kcontrols_create((struct ct_mixer *)atc->mixer); - if (err) - return err; - - strcpy(atc->card->mixername, device_name); - - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.h deleted file mode 100644 index b009e989..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 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 ctmixer.h - * - * @Brief - * This file contains the definition of the mixer device functions. - * - * @Author Liu Chun - * @Date Mar 28 2008 - * - */ - -#ifndef CTMIXER_H -#define CTMIXER_H - -#include "ctatc.h" -#include "ctresource.h" - -#define INIT_VOL 0x1c00 - -enum MIXER_PORT_T { - MIX_WAVE_FRONT, - MIX_WAVE_REAR, - MIX_WAVE_CENTLFE, - MIX_WAVE_SURROUND, - MIX_SPDIF_OUT, - MIX_PCMO_FRONT, - MIX_MIC_IN, - MIX_LINE_IN, - MIX_SPDIF_IN, - MIX_PCMI_FRONT, - MIX_PCMI_REAR, - MIX_PCMI_CENTLFE, - MIX_PCMI_SURROUND, - - NUM_MIX_PORTS -}; - -/* alsa mixer descriptor */ -struct ct_mixer { - struct ct_atc *atc; - - void **amixers; /* amixer resources for volume control */ - void **sums; /* sum resources for signal collection */ - unsigned int switch_state; /* A bit-map to indicate state of switches */ - - int (*get_output_ports)(struct ct_mixer *mixer, enum MIXER_PORT_T type, - struct rsc **rleft, struct rsc **rright); - - int (*set_input_left)(struct ct_mixer *mixer, - enum MIXER_PORT_T type, struct rsc *rsc); - int (*set_input_right)(struct ct_mixer *mixer, - enum MIXER_PORT_T type, struct rsc *rsc); -#ifdef CONFIG_PM - int (*resume)(struct ct_mixer *mixer); -#endif -}; - -int ct_alsa_mix_create(struct ct_atc *atc, - enum CTALSADEVS device, - const char *device_name); -int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer); -int ct_mixer_destroy(struct ct_mixer *mixer); - -#endif /* CTMIXER_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.c deleted file mode 100644 index 2c862261..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.c +++ /dev/null @@ -1,435 +0,0 @@ -/** - * 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 ctpcm.c - * - * @Brief - * This file contains the definition of the pcm device functions. - * - * @Author Liu Chun - * @Date Apr 2 2008 - * - */ - -#include "ctpcm.h" -#include "cttimer.h" -#include <linux/slab.h> -#include <sound/pcm.h> - -/* Hardware descriptions for playback */ -static struct snd_pcm_hardware ct_pcm_playback_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE), - .formats = (SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_FLOAT_LE), - .rates = (SNDRV_PCM_RATE_CONTINUOUS | - SNDRV_PCM_RATE_8000_192000), - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = (64), - .period_bytes_max = (128*1024), - .periods_min = 2, - .periods_max = 1024, - .fifo_size = 0, -}; - -static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = (SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_32000), - .rate_min = 32000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = (64), - .period_bytes_max = (128*1024), - .periods_min = 2, - .periods_max = 1024, - .fifo_size = 0, -}; - -/* Hardware descriptions for capture */ -static struct snd_pcm_hardware ct_pcm_capture_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = (SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_FLOAT_LE), - .rates = (SNDRV_PCM_RATE_CONTINUOUS | - SNDRV_PCM_RATE_8000_96000), - .rate_min = 8000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (128*1024), - .period_bytes_min = (384), - .period_bytes_max = (64*1024), - .periods_min = 2, - .periods_max = 1024, - .fifo_size = 0, -}; - -static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm) -{ - struct ct_atc_pcm *apcm = atc_pcm; - - if (!apcm->substream) - return; - - snd_pcm_period_elapsed(apcm->substream); -} - -static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime) -{ - struct ct_atc_pcm *apcm = runtime->private_data; - 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; -} - -/* pcm playback operations */ -static int ct_pcm_playback_open(struct snd_pcm_substream *substream) -{ - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm; - int err; - - apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); - if (!apcm) - return -ENOMEM; - - apcm->substream = substream; - apcm->interrupt = ct_atc_pcm_interrupt; - if (IEC958 == substream->pcm->device) { - runtime->hw = ct_spdif_passthru_playback_hw; - atc->spdif_out_passthru(atc, 1); - } else { - runtime->hw = ct_pcm_playback_hw; - if (FRONT == substream->pcm->device) - runtime->hw.channels_max = 8; - } - - err = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) { - kfree(apcm); - return err; - } - err = snd_pcm_hw_constraint_minmax(runtime, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024, UINT_MAX); - if (err < 0) { - kfree(apcm); - return err; - } - - apcm->timer = ct_timer_instance_new(atc->timer, apcm); - if (!apcm->timer) { - kfree(apcm); - return -ENOMEM; - } - runtime->private_data = apcm; - runtime->private_free = ct_atc_pcm_free_substream; - - return 0; -} - -static int ct_pcm_playback_close(struct snd_pcm_substream *substream) -{ - struct ct_atc *atc = snd_pcm_substream_chip(substream); - - /* TODO: Notify mixer inactive. */ - if (IEC958 == substream->pcm->device) - atc->spdif_out_passthru(atc, 0); - - /* The ct_atc_pcm object will be freed by runtime->private_free */ - - return 0; -} - -static int ct_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct ct_atc_pcm *apcm = substream->runtime->private_data; - int err; - - err = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (err < 0) - return err; - /* clear previous resources */ - atc->pcm_release_resources(atc, apcm); - return err; -} - -static int ct_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct ct_atc_pcm *apcm = substream->runtime->private_data; - - /* clear previous resources */ - atc->pcm_release_resources(atc, apcm); - /* Free snd-allocated pages */ - return snd_pcm_lib_free_pages(substream); -} - - -static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream) -{ - int err; - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm = runtime->private_data; - - if (IEC958 == substream->pcm->device) - err = atc->spdif_passthru_playback_prepare(atc, apcm); - else - err = atc->pcm_playback_prepare(atc, apcm); - - if (err < 0) { - printk(KERN_ERR "ctxfi: Preparing pcm playback failed!!!\n"); - return err; - } - - return 0; -} - -static int -ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm = runtime->private_data; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - atc->pcm_playback_start(atc, apcm); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - atc->pcm_playback_stop(atc, apcm); - break; - default: - break; - } - - return 0; -} - -static snd_pcm_uframes_t -ct_pcm_playback_pointer(struct snd_pcm_substream *substream) -{ - unsigned long position; - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm = runtime->private_data; - - /* Read out playback position */ - position = atc->pcm_playback_position(atc, apcm); - position = bytes_to_frames(runtime, position); - if (position >= runtime->buffer_size) - position = 0; - return position; -} - -/* pcm capture operations */ -static int ct_pcm_capture_open(struct snd_pcm_substream *substream) -{ - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm; - int err; - - apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); - if (!apcm) - return -ENOMEM; - - apcm->started = 0; - apcm->substream = substream; - apcm->interrupt = ct_atc_pcm_interrupt; - runtime->hw = ct_pcm_capture_hw; - runtime->hw.rate_max = atc->rsr * atc->msr; - - err = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) { - kfree(apcm); - return err; - } - err = snd_pcm_hw_constraint_minmax(runtime, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024, UINT_MAX); - if (err < 0) { - kfree(apcm); - return err; - } - - apcm->timer = ct_timer_instance_new(atc->timer, apcm); - if (!apcm->timer) { - kfree(apcm); - return -ENOMEM; - } - runtime->private_data = apcm; - runtime->private_free = ct_atc_pcm_free_substream; - - return 0; -} - -static int ct_pcm_capture_close(struct snd_pcm_substream *substream) -{ - /* The ct_atc_pcm object will be freed by runtime->private_free */ - /* TODO: Notify mixer inactive. */ - return 0; -} - -static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream) -{ - int err; - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm = runtime->private_data; - - err = atc->pcm_capture_prepare(atc, apcm); - if (err < 0) { - printk(KERN_ERR "ctxfi: Preparing pcm capture failed!!!\n"); - return err; - } - - return 0; -} - -static int -ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm = runtime->private_data; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - atc->pcm_capture_start(atc, apcm); - break; - case SNDRV_PCM_TRIGGER_STOP: - atc->pcm_capture_stop(atc, apcm); - break; - default: - atc->pcm_capture_stop(atc, apcm); - break; - } - - return 0; -} - -static snd_pcm_uframes_t -ct_pcm_capture_pointer(struct snd_pcm_substream *substream) -{ - unsigned long position; - struct ct_atc *atc = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct ct_atc_pcm *apcm = runtime->private_data; - - /* Read out playback position */ - position = atc->pcm_capture_position(atc, apcm); - position = bytes_to_frames(runtime, position); - if (position >= runtime->buffer_size) - position = 0; - return position; -} - -/* PCM operators for playback */ -static struct snd_pcm_ops ct_pcm_playback_ops = { - .open = ct_pcm_playback_open, - .close = ct_pcm_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = ct_pcm_hw_params, - .hw_free = ct_pcm_hw_free, - .prepare = ct_pcm_playback_prepare, - .trigger = ct_pcm_playback_trigger, - .pointer = ct_pcm_playback_pointer, - .page = snd_pcm_sgbuf_ops_page, -}; - -/* PCM operators for capture */ -static struct snd_pcm_ops ct_pcm_capture_ops = { - .open = ct_pcm_capture_open, - .close = ct_pcm_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = ct_pcm_hw_params, - .hw_free = ct_pcm_hw_free, - .prepare = ct_pcm_capture_prepare, - .trigger = ct_pcm_capture_trigger, - .pointer = ct_pcm_capture_pointer, - .page = snd_pcm_sgbuf_ops_page, -}; - -/* Create ALSA pcm device */ -int ct_alsa_pcm_create(struct ct_atc *atc, - enum CTALSADEVS device, - const char *device_name) -{ - struct snd_pcm *pcm; - int err; - int playback_count, capture_count; - - playback_count = (IEC958 == device) ? 1 : 256; - capture_count = (FRONT == device) ? 1 : 0; - err = snd_pcm_new(atc->card, "ctxfi", device, - playback_count, capture_count, &pcm); - if (err < 0) { - printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err); - return err; - } - - pcm->private_data = atc; - pcm->info_flags = 0; - pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; - strlcpy(pcm->name, device_name, sizeof(pcm->name)); - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); - - if (FRONT == device) - snd_pcm_set_ops(pcm, - SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, - snd_dma_pci_data(atc->pci), 128*1024, 128*1024); - -#ifdef CONFIG_PM - atc->pcms[device] = pcm; -#endif - - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.h deleted file mode 100644 index 178da0dc..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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 ctpcm.h - * - * @Brief - * This file contains the definition of the pcm device functions. - * - * @Author Liu Chun - * @Date Mar 28 2008 - * - */ - -#ifndef CTPCM_H -#define CTPCM_H - -#include "ctatc.h" - -int ct_alsa_pcm_create(struct ct_atc *atc, - enum CTALSADEVS device, - const char *device_name); - -#endif /* CTPCM_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.c deleted file mode 100644 index 7dfaf673..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.c +++ /dev/null @@ -1,301 +0,0 @@ -/** - * 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 ctresource.c - * - * @Brief - * This file contains the implementation of some generic helper functions. - * - * @Author Liu Chun - * @Date May 15 2008 - * - */ - -#include "ctresource.h" -#include "cthardware.h" -#include <linux/err.h> -#include <linux/slab.h> - -#define AUDIO_SLOT_BLOCK_NUM 256 - -/* Resource allocation based on bit-map management mechanism */ -static int -get_resource(u8 *rscs, unsigned int amount, - unsigned int multi, unsigned int *ridx) -{ - int i, j, k, n; - - /* Check whether there are sufficient resources to meet request. */ - for (i = 0, n = multi; i < amount; i++) { - j = i / 8; - k = i % 8; - if (rscs[j] & ((u8)1 << k)) { - n = multi; - continue; - } - if (!(--n)) - break; /* found sufficient contiguous resources */ - } - - if (i >= amount) { - /* Can not find sufficient contiguous resources */ - return -ENOENT; - } - - /* Mark the contiguous bits in resource bit-map as used */ - for (n = multi; n > 0; n--) { - j = i / 8; - k = i % 8; - rscs[j] |= ((u8)1 << k); - i--; - } - - *ridx = i + 1; - - return 0; -} - -static int put_resource(u8 *rscs, unsigned int multi, unsigned int idx) -{ - unsigned int i, j, k, n; - - /* Mark the contiguous bits in resource bit-map as used */ - for (n = multi, i = idx; n > 0; n--) { - j = i / 8; - k = i % 8; - rscs[j] &= ~((u8)1 << k); - i++; - } - - return 0; -} - -int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx) -{ - int err; - - if (n > mgr->avail) - return -ENOENT; - - err = get_resource(mgr->rscs, mgr->amount, n, ridx); - if (!err) - mgr->avail -= n; - - return err; -} - -int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx) -{ - put_resource(mgr->rscs, n, idx); - mgr->avail += n; - - return 0; -} - -static unsigned char offset_in_audio_slot_block[NUM_RSCTYP] = { - /* SRC channel is at Audio Ring slot 1 every 16 slots. */ - [SRC] = 0x1, - [AMIXER] = 0x4, - [SUM] = 0xc, -}; - -static int rsc_index(const struct rsc *rsc) -{ - return rsc->conj; -} - -static int audio_ring_slot(const struct rsc *rsc) -{ - return (rsc->conj << 4) + offset_in_audio_slot_block[rsc->type]; -} - -static int rsc_next_conj(struct rsc *rsc) -{ - unsigned int i; - for (i = 0; (i < 8) && (!(rsc->msr & (0x1 << i))); ) - i++; - rsc->conj += (AUDIO_SLOT_BLOCK_NUM >> i); - return rsc->conj; -} - -static int rsc_master(struct rsc *rsc) -{ - return rsc->conj = rsc->idx; -} - -static struct rsc_ops rsc_generic_ops = { - .index = rsc_index, - .output_slot = audio_ring_slot, - .master = rsc_master, - .next_conj = rsc_next_conj, -}; - -int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw) -{ - int err = 0; - - rsc->idx = idx; - rsc->conj = idx; - rsc->type = type; - rsc->msr = msr; - rsc->hw = hw; - rsc->ops = &rsc_generic_ops; - if (!hw) { - rsc->ctrl_blk = NULL; - return 0; - } - - switch (type) { - case SRC: - err = ((struct hw *)hw)->src_rsc_get_ctrl_blk(&rsc->ctrl_blk); - break; - case AMIXER: - err = ((struct hw *)hw)-> - amixer_rsc_get_ctrl_blk(&rsc->ctrl_blk); - break; - case SRCIMP: - case SUM: - case DAIO: - break; - default: - printk(KERN_ERR - "ctxfi: Invalid resource type value %d!\n", type); - return -EINVAL; - } - - if (err) { - printk(KERN_ERR - "ctxfi: Failed to get resource control block!\n"); - return err; - } - - return 0; -} - -int rsc_uninit(struct rsc *rsc) -{ - if ((NULL != rsc->hw) && (NULL != rsc->ctrl_blk)) { - switch (rsc->type) { - case SRC: - ((struct hw *)rsc->hw)-> - src_rsc_put_ctrl_blk(rsc->ctrl_blk); - break; - case AMIXER: - ((struct hw *)rsc->hw)-> - amixer_rsc_put_ctrl_blk(rsc->ctrl_blk); - break; - case SUM: - case DAIO: - break; - default: - printk(KERN_ERR "ctxfi: " - "Invalid resource type value %d!\n", rsc->type); - break; - } - - rsc->hw = rsc->ctrl_blk = NULL; - } - - rsc->idx = rsc->conj = 0; - rsc->type = NUM_RSCTYP; - rsc->msr = 0; - - return 0; -} - -int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type, - unsigned int amount, void *hw_obj) -{ - int err = 0; - struct hw *hw = hw_obj; - - mgr->type = NUM_RSCTYP; - - mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL); - if (!mgr->rscs) - return -ENOMEM; - - switch (type) { - case SRC: - err = hw->src_mgr_get_ctrl_blk(&mgr->ctrl_blk); - break; - case SRCIMP: - err = hw->srcimp_mgr_get_ctrl_blk(&mgr->ctrl_blk); - break; - case AMIXER: - err = hw->amixer_mgr_get_ctrl_blk(&mgr->ctrl_blk); - break; - case DAIO: - err = hw->daio_mgr_get_ctrl_blk(hw, &mgr->ctrl_blk); - break; - case SUM: - break; - default: - printk(KERN_ERR - "ctxfi: Invalid resource type value %d!\n", type); - err = -EINVAL; - goto error; - } - - if (err) { - printk(KERN_ERR - "ctxfi: Failed to get manager control block!\n"); - goto error; - } - - mgr->type = type; - mgr->avail = mgr->amount = amount; - mgr->hw = hw; - - return 0; - -error: - kfree(mgr->rscs); - return err; -} - -int rsc_mgr_uninit(struct rsc_mgr *mgr) -{ - if (NULL != mgr->rscs) { - kfree(mgr->rscs); - mgr->rscs = NULL; - } - - if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) { - switch (mgr->type) { - case SRC: - ((struct hw *)mgr->hw)-> - src_mgr_put_ctrl_blk(mgr->ctrl_blk); - break; - case SRCIMP: - ((struct hw *)mgr->hw)-> - srcimp_mgr_put_ctrl_blk(mgr->ctrl_blk); - break; - case AMIXER: - ((struct hw *)mgr->hw)-> - amixer_mgr_put_ctrl_blk(mgr->ctrl_blk); - break; - case DAIO: - ((struct hw *)mgr->hw)-> - daio_mgr_put_ctrl_blk(mgr->ctrl_blk); - break; - case SUM: - break; - default: - printk(KERN_ERR "ctxfi: " - "Invalid resource type value %d!\n", mgr->type); - break; - } - - mgr->hw = mgr->ctrl_blk = NULL; - } - - mgr->type = NUM_RSCTYP; - mgr->avail = mgr->amount = 0; - - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.h deleted file mode 100644 index 0838c2e8..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * 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 ctresource.h - * - * @Brief - * This file contains the definition of generic hardware resources for - * resource management. - * - * @Author Liu Chun - * @Date May 13 2008 - * - */ - -#ifndef CTRESOURCE_H -#define CTRESOURCE_H - -#include <linux/types.h> - -enum RSCTYP { - SRC, - SRCIMP, - AMIXER, - SUM, - DAIO, - NUM_RSCTYP /* This must be the last one and less than 16 */ -}; - -struct rsc_ops; - -struct rsc { - u32 idx:12; /* The index of a resource */ - u32 type:4; /* The type (RSCTYP) of a resource */ - u32 conj:12; /* Current conjugate index */ - u32 msr:4; /* The Master Sample Rate a resource working on */ - void *ctrl_blk; /* Chip specific control info block for a resource */ - void *hw; /* Chip specific object for hardware access means */ - struct rsc_ops *ops; /* Generic resource operations */ -}; - -struct rsc_ops { - int (*master)(struct rsc *rsc); /* Move to master resource */ - int (*next_conj)(struct rsc *rsc); /* Move to next conjugate resource */ - int (*index)(const struct rsc *rsc); /* Return the index of resource */ - /* Return the output slot number */ - int (*output_slot)(const struct rsc *rsc); -}; - -int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw); -int rsc_uninit(struct rsc *rsc); - -struct rsc_mgr { - enum RSCTYP type; /* The type (RSCTYP) of resource to manage */ - unsigned int amount; /* The total amount of a kind of resource */ - unsigned int avail; /* The amount of currently available resources */ - unsigned char *rscs; /* The bit-map for resource allocation */ - void *ctrl_blk; /* Chip specific control info block */ - void *hw; /* Chip specific object for hardware access */ -}; - -/* Resource management is based on bit-map mechanism */ -int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type, - unsigned int amount, void *hw); -int rsc_mgr_uninit(struct rsc_mgr *mgr); -int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx); -int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx); - -#endif /* CTRESOURCE_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.c deleted file mode 100644 index 6e77e863..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.c +++ /dev/null @@ -1,885 +0,0 @@ -/** - * 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 ctsrc.c - * - * @Brief - * This file contains the implementation of the Sample Rate Convertor - * resource management object. - * - * @Author Liu Chun - * @Date May 13 2008 - * - */ - -#include "ctsrc.h" -#include "cthardware.h" -#include <linux/slab.h> - -#define SRC_RESOURCE_NUM 256 -#define SRCIMP_RESOURCE_NUM 256 - -static unsigned int conj_mask; - -static int src_default_config_memrd(struct src *src); -static int src_default_config_memwr(struct src *src); -static int src_default_config_arcrw(struct src *src); - -static int (*src_default_config[3])(struct src *) = { - [MEMRD] = src_default_config_memrd, - [MEMWR] = src_default_config_memwr, - [ARCRW] = src_default_config_arcrw -}; - -static int src_set_state(struct src *src, unsigned int state) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_state(src->rsc.ctrl_blk, state); - - return 0; -} - -static int src_set_bm(struct src *src, unsigned int bm) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_bm(src->rsc.ctrl_blk, bm); - - return 0; -} - -static int src_set_sf(struct src *src, unsigned int sf) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_sf(src->rsc.ctrl_blk, sf); - - return 0; -} - -static int src_set_pm(struct src *src, unsigned int pm) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_pm(src->rsc.ctrl_blk, pm); - - return 0; -} - -static int src_set_rom(struct src *src, unsigned int rom) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_rom(src->rsc.ctrl_blk, rom); - - return 0; -} - -static int src_set_vo(struct src *src, unsigned int vo) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_vo(src->rsc.ctrl_blk, vo); - - return 0; -} - -static int src_set_st(struct src *src, unsigned int st) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_st(src->rsc.ctrl_blk, st); - - return 0; -} - -static int src_set_bp(struct src *src, unsigned int bp) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_bp(src->rsc.ctrl_blk, bp); - - return 0; -} - -static int src_set_cisz(struct src *src, unsigned int cisz) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_cisz(src->rsc.ctrl_blk, cisz); - - return 0; -} - -static int src_set_ca(struct src *src, unsigned int ca) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_ca(src->rsc.ctrl_blk, ca); - - return 0; -} - -static int src_set_sa(struct src *src, unsigned int sa) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_sa(src->rsc.ctrl_blk, sa); - - return 0; -} - -static int src_set_la(struct src *src, unsigned int la) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_la(src->rsc.ctrl_blk, la); - - return 0; -} - -static int src_set_pitch(struct src *src, unsigned int pitch) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_pitch(src->rsc.ctrl_blk, pitch); - - return 0; -} - -static int src_set_clear_zbufs(struct src *src) -{ - struct hw *hw; - - hw = src->rsc.hw; - hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); - - return 0; -} - -static int src_commit_write(struct src *src) -{ - struct hw *hw; - int i; - unsigned int dirty = 0; - - hw = src->rsc.hw; - src->rsc.ops->master(&src->rsc); - if (src->rsc.msr > 1) { - /* Save dirty flags for conjugate resource programming */ - dirty = hw->src_get_dirty(src->rsc.ctrl_blk) & conj_mask; - } - hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), - src->rsc.ctrl_blk); - - /* Program conjugate parameter mixer resources */ - if (MEMWR == src->mode) - return 0; - - for (i = 1; i < src->rsc.msr; i++) { - src->rsc.ops->next_conj(&src->rsc); - hw->src_set_dirty(src->rsc.ctrl_blk, dirty); - hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), - src->rsc.ctrl_blk); - } - src->rsc.ops->master(&src->rsc); - - return 0; -} - -static int src_get_ca(struct src *src) -{ - struct hw *hw; - - hw = src->rsc.hw; - return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc), - src->rsc.ctrl_blk); -} - -static int src_init(struct src *src) -{ - src_default_config[src->mode](src); - - return 0; -} - -static struct src *src_next_interleave(struct src *src) -{ - return src->intlv; -} - -static int src_default_config_memrd(struct src *src) -{ - struct hw *hw = src->rsc.hw; - unsigned int rsr, msr; - - hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); - hw->src_set_bm(src->rsc.ctrl_blk, 1); - for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1) - rsr++; - - hw->src_set_rsr(src->rsc.ctrl_blk, rsr); - hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16); - hw->src_set_wr(src->rsc.ctrl_blk, 0); - hw->src_set_pm(src->rsc.ctrl_blk, 0); - hw->src_set_rom(src->rsc.ctrl_blk, 0); - hw->src_set_vo(src->rsc.ctrl_blk, 0); - hw->src_set_st(src->rsc.ctrl_blk, 0); - hw->src_set_ilsz(src->rsc.ctrl_blk, src->multi - 1); - hw->src_set_cisz(src->rsc.ctrl_blk, 0x80); - hw->src_set_sa(src->rsc.ctrl_blk, 0x0); - hw->src_set_la(src->rsc.ctrl_blk, 0x1000); - hw->src_set_ca(src->rsc.ctrl_blk, 0x80); - hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); - hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); - - src->rsc.ops->master(&src->rsc); - hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), - src->rsc.ctrl_blk); - - for (msr = 1; msr < src->rsc.msr; msr++) { - src->rsc.ops->next_conj(&src->rsc); - hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); - hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), - src->rsc.ctrl_blk); - } - src->rsc.ops->master(&src->rsc); - - return 0; -} - -static int src_default_config_memwr(struct src *src) -{ - struct hw *hw = src->rsc.hw; - - hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); - hw->src_set_bm(src->rsc.ctrl_blk, 1); - hw->src_set_rsr(src->rsc.ctrl_blk, 0); - hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16); - hw->src_set_wr(src->rsc.ctrl_blk, 1); - hw->src_set_pm(src->rsc.ctrl_blk, 0); - hw->src_set_rom(src->rsc.ctrl_blk, 0); - hw->src_set_vo(src->rsc.ctrl_blk, 0); - hw->src_set_st(src->rsc.ctrl_blk, 0); - hw->src_set_ilsz(src->rsc.ctrl_blk, 0); - hw->src_set_cisz(src->rsc.ctrl_blk, 0x80); - hw->src_set_sa(src->rsc.ctrl_blk, 0x0); - hw->src_set_la(src->rsc.ctrl_blk, 0x1000); - hw->src_set_ca(src->rsc.ctrl_blk, 0x80); - hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); - hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); - - src->rsc.ops->master(&src->rsc); - hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), - src->rsc.ctrl_blk); - - return 0; -} - -static int src_default_config_arcrw(struct src *src) -{ - struct hw *hw = src->rsc.hw; - unsigned int rsr, msr; - unsigned int dirty; - - hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF); - hw->src_set_bm(src->rsc.ctrl_blk, 0); - for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1) - rsr++; - - hw->src_set_rsr(src->rsc.ctrl_blk, rsr); - hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_F32); - hw->src_set_wr(src->rsc.ctrl_blk, 0); - hw->src_set_pm(src->rsc.ctrl_blk, 0); - hw->src_set_rom(src->rsc.ctrl_blk, 0); - hw->src_set_vo(src->rsc.ctrl_blk, 0); - hw->src_set_st(src->rsc.ctrl_blk, 0); - hw->src_set_ilsz(src->rsc.ctrl_blk, 0); - hw->src_set_cisz(src->rsc.ctrl_blk, 0x80); - hw->src_set_sa(src->rsc.ctrl_blk, 0x0); - /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/ - hw->src_set_la(src->rsc.ctrl_blk, 0x1000); - /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/ - hw->src_set_ca(src->rsc.ctrl_blk, 0x80); - hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000); - hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1); - - dirty = hw->src_get_dirty(src->rsc.ctrl_blk); - src->rsc.ops->master(&src->rsc); - for (msr = 0; msr < src->rsc.msr; msr++) { - hw->src_set_dirty(src->rsc.ctrl_blk, dirty); - hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc), - src->rsc.ctrl_blk); - src->rsc.ops->next_conj(&src->rsc); - } - src->rsc.ops->master(&src->rsc); - - return 0; -} - -static struct src_rsc_ops src_rsc_ops = { - .set_state = src_set_state, - .set_bm = src_set_bm, - .set_sf = src_set_sf, - .set_pm = src_set_pm, - .set_rom = src_set_rom, - .set_vo = src_set_vo, - .set_st = src_set_st, - .set_bp = src_set_bp, - .set_cisz = src_set_cisz, - .set_ca = src_set_ca, - .set_sa = src_set_sa, - .set_la = src_set_la, - .set_pitch = src_set_pitch, - .set_clr_zbufs = src_set_clear_zbufs, - .commit_write = src_commit_write, - .get_ca = src_get_ca, - .init = src_init, - .next_interleave = src_next_interleave, -}; - -static int -src_rsc_init(struct src *src, u32 idx, - const struct src_desc *desc, struct src_mgr *mgr) -{ - int err; - int i, n; - struct src *p; - - n = (MEMRD == desc->mode) ? desc->multi : 1; - for (i = 0, p = src; i < n; i++, p++) { - err = rsc_init(&p->rsc, idx + i, SRC, desc->msr, mgr->mgr.hw); - if (err) - goto error1; - - /* Initialize src specific rsc operations */ - p->ops = &src_rsc_ops; - p->multi = (0 == i) ? desc->multi : 1; - p->mode = desc->mode; - src_default_config[desc->mode](p); - mgr->src_enable(mgr, p); - p->intlv = p + 1; - } - (--p)->intlv = NULL; /* Set @intlv of the last SRC to NULL */ - - mgr->commit_write(mgr); - - return 0; - -error1: - for (i--, p--; i >= 0; i--, p--) { - mgr->src_disable(mgr, p); - rsc_uninit(&p->rsc); - } - mgr->commit_write(mgr); - return err; -} - -static int src_rsc_uninit(struct src *src, struct src_mgr *mgr) -{ - int i, n; - struct src *p; - - n = (MEMRD == src->mode) ? src->multi : 1; - for (i = 0, p = src; i < n; i++, p++) { - mgr->src_disable(mgr, p); - rsc_uninit(&p->rsc); - p->multi = 0; - p->ops = NULL; - p->mode = NUM_SRCMODES; - p->intlv = NULL; - } - mgr->commit_write(mgr); - - return 0; -} - -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; - struct src *src; - unsigned long flags; - - *rsrc = NULL; - - /* Check whether there are sufficient src resources to meet request. */ - spin_lock_irqsave(&mgr->mgr_lock, flags); - if (MEMRD == desc->mode) - err = mgr_get_resource(&mgr->mgr, desc->multi, &idx); - else - err = mgr_get_resource(&mgr->mgr, 1, &idx); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - if (err) { - printk(KERN_ERR "ctxfi: Can't meet SRC resource request!\n"); - return err; - } - - /* Allocate mem for master src resource */ - if (MEMRD == desc->mode) - src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL); - else - src = kzalloc(sizeof(*src), GFP_KERNEL); - - if (!src) { - err = -ENOMEM; - goto error1; - } - - err = src_rsc_init(src, idx, desc, mgr); - if (err) - goto error2; - - *rsrc = src; - - return 0; - -error2: - kfree(src); -error1: - spin_lock_irqsave(&mgr->mgr_lock, flags); - if (MEMRD == desc->mode) - mgr_put_resource(&mgr->mgr, desc->multi, idx); - else - mgr_put_resource(&mgr->mgr, 1, idx); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - return err; -} - -static int put_src_rsc(struct src_mgr *mgr, struct src *src) -{ - unsigned long flags; - - spin_lock_irqsave(&mgr->mgr_lock, flags); - src->rsc.ops->master(&src->rsc); - if (MEMRD == src->mode) - mgr_put_resource(&mgr->mgr, src->multi, - src->rsc.ops->index(&src->rsc)); - else - mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc)); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - src_rsc_uninit(src, mgr); - kfree(src); - - return 0; -} - -static int src_enable_s(struct src_mgr *mgr, struct src *src) -{ - struct hw *hw = mgr->mgr.hw; - int i; - - src->rsc.ops->master(&src->rsc); - for (i = 0; i < src->rsc.msr; i++) { - hw->src_mgr_enbs_src(mgr->mgr.ctrl_blk, - src->rsc.ops->index(&src->rsc)); - src->rsc.ops->next_conj(&src->rsc); - } - src->rsc.ops->master(&src->rsc); - - return 0; -} - -static int src_enable(struct src_mgr *mgr, struct src *src) -{ - struct hw *hw = mgr->mgr.hw; - int i; - - src->rsc.ops->master(&src->rsc); - for (i = 0; i < src->rsc.msr; i++) { - hw->src_mgr_enb_src(mgr->mgr.ctrl_blk, - src->rsc.ops->index(&src->rsc)); - src->rsc.ops->next_conj(&src->rsc); - } - src->rsc.ops->master(&src->rsc); - - return 0; -} - -static int src_disable(struct src_mgr *mgr, struct src *src) -{ - struct hw *hw = mgr->mgr.hw; - int i; - - src->rsc.ops->master(&src->rsc); - for (i = 0; i < src->rsc.msr; i++) { - hw->src_mgr_dsb_src(mgr->mgr.ctrl_blk, - src->rsc.ops->index(&src->rsc)); - src->rsc.ops->next_conj(&src->rsc); - } - src->rsc.ops->master(&src->rsc); - - return 0; -} - -static int src_mgr_commit_write(struct src_mgr *mgr) -{ - struct hw *hw = mgr->mgr.hw; - - hw->src_mgr_commit_write(hw, mgr->mgr.ctrl_blk); - - return 0; -} - -int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr) -{ - int err, i; - struct src_mgr *src_mgr; - - *rsrc_mgr = NULL; - src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL); - if (!src_mgr) - return -ENOMEM; - - err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw); - if (err) - goto error1; - - spin_lock_init(&src_mgr->mgr_lock); - conj_mask = ((struct hw *)hw)->src_dirty_conj_mask(); - - src_mgr->get_src = get_src_rsc; - src_mgr->put_src = put_src_rsc; - src_mgr->src_enable_s = src_enable_s; - src_mgr->src_enable = src_enable; - src_mgr->src_disable = src_disable; - src_mgr->commit_write = src_mgr_commit_write; - - /* Disable all SRC resources. */ - for (i = 0; i < 256; i++) - ((struct hw *)hw)->src_mgr_dsb_src(src_mgr->mgr.ctrl_blk, i); - - ((struct hw *)hw)->src_mgr_commit_write(hw, src_mgr->mgr.ctrl_blk); - - *rsrc_mgr = src_mgr; - - return 0; - -error1: - kfree(src_mgr); - return err; -} - -int src_mgr_destroy(struct src_mgr *src_mgr) -{ - rsc_mgr_uninit(&src_mgr->mgr); - kfree(src_mgr); - - return 0; -} - -/* SRCIMP resource manager operations */ - -static int srcimp_master(struct rsc *rsc) -{ - rsc->conj = 0; - return rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0]; -} - -static int srcimp_next_conj(struct rsc *rsc) -{ - rsc->conj++; - return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj]; -} - -static int srcimp_index(const struct rsc *rsc) -{ - return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj]; -} - -static struct rsc_ops srcimp_basic_rsc_ops = { - .master = srcimp_master, - .next_conj = srcimp_next_conj, - .index = srcimp_index, - .output_slot = NULL, -}; - -static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input) -{ - struct imapper *entry; - int i; - - srcimp->rsc.ops->master(&srcimp->rsc); - src->rsc.ops->master(&src->rsc); - input->ops->master(input); - - /* Program master and conjugate resources */ - for (i = 0; i < srcimp->rsc.msr; i++) { - entry = &srcimp->imappers[i]; - entry->slot = input->ops->output_slot(input); - entry->user = src->rsc.ops->index(&src->rsc); - entry->addr = srcimp->rsc.ops->index(&srcimp->rsc); - srcimp->mgr->imap_add(srcimp->mgr, entry); - srcimp->mapped |= (0x1 << i); - - srcimp->rsc.ops->next_conj(&srcimp->rsc); - input->ops->next_conj(input); - } - - srcimp->rsc.ops->master(&srcimp->rsc); - input->ops->master(input); - - return 0; -} - -static int srcimp_unmap(struct srcimp *srcimp) -{ - int i; - - /* Program master and conjugate resources */ - for (i = 0; i < srcimp->rsc.msr; i++) { - if (srcimp->mapped & (0x1 << i)) { - srcimp->mgr->imap_delete(srcimp->mgr, - &srcimp->imappers[i]); - srcimp->mapped &= ~(0x1 << i); - } - } - - return 0; -} - -static struct srcimp_rsc_ops srcimp_ops = { - .map = srcimp_map, - .unmap = srcimp_unmap -}; - -static int srcimp_rsc_init(struct srcimp *srcimp, - const struct srcimp_desc *desc, - struct srcimp_mgr *mgr) -{ - int err; - - err = rsc_init(&srcimp->rsc, srcimp->idx[0], - SRCIMP, desc->msr, mgr->mgr.hw); - if (err) - return err; - - /* Reserve memory for imapper nodes */ - srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr, - GFP_KERNEL); - if (!srcimp->imappers) { - err = -ENOMEM; - goto error1; - } - - /* Set srcimp specific operations */ - srcimp->rsc.ops = &srcimp_basic_rsc_ops; - srcimp->ops = &srcimp_ops; - srcimp->mgr = mgr; - - srcimp->rsc.ops->master(&srcimp->rsc); - - return 0; - -error1: - rsc_uninit(&srcimp->rsc); - return err; -} - -static int srcimp_rsc_uninit(struct srcimp *srcimp) -{ - if (NULL != srcimp->imappers) { - kfree(srcimp->imappers); - srcimp->imappers = NULL; - } - srcimp->ops = NULL; - srcimp->mgr = NULL; - rsc_uninit(&srcimp->rsc); - - return 0; -} - -static int get_srcimp_rsc(struct srcimp_mgr *mgr, - const struct srcimp_desc *desc, - struct srcimp **rsrcimp) -{ - int err, i; - unsigned int idx; - struct srcimp *srcimp; - unsigned long flags; - - *rsrcimp = NULL; - - /* Allocate mem for SRCIMP resource */ - srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL); - if (!srcimp) - return -ENOMEM; - - /* Check whether there are sufficient SRCIMP resources. */ - err = 0; - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i = 0; i < desc->msr; i++) { - err = mgr_get_resource(&mgr->mgr, 1, &idx); - if (err) - break; - - srcimp->idx[i] = idx; - } - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - if (err) { - printk(KERN_ERR "ctxfi: Can't meet SRCIMP resource request!\n"); - goto error1; - } - - err = srcimp_rsc_init(srcimp, desc, mgr); - if (err) - goto error1; - - *rsrcimp = srcimp; - - return 0; - -error1: - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i--; i >= 0; i--) - mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - kfree(srcimp); - return err; -} - -static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&mgr->mgr_lock, flags); - for (i = 0; i < srcimp->rsc.msr; i++) - mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]); - - spin_unlock_irqrestore(&mgr->mgr_lock, flags); - srcimp_rsc_uninit(srcimp); - kfree(srcimp); - - return 0; -} - -static int srcimp_map_op(void *data, struct imapper *entry) -{ - struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr; - struct hw *hw = mgr->hw; - - hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot); - hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user); - hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next); - hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr); - hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk); - - return 0; -} - -static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry) -{ - unsigned long flags; - int err; - - spin_lock_irqsave(&mgr->imap_lock, flags); - if ((0 == entry->addr) && (mgr->init_imap_added)) { - input_mapper_delete(&mgr->imappers, - mgr->init_imap, srcimp_map_op, mgr); - mgr->init_imap_added = 0; - } - err = input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr); - spin_unlock_irqrestore(&mgr->imap_lock, flags); - - return err; -} - -static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry) -{ - unsigned long flags; - int err; - - spin_lock_irqsave(&mgr->imap_lock, flags); - err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr); - if (list_empty(&mgr->imappers)) { - input_mapper_add(&mgr->imappers, mgr->init_imap, - srcimp_map_op, mgr); - mgr->init_imap_added = 1; - } - spin_unlock_irqrestore(&mgr->imap_lock, flags); - - return err; -} - -int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr) -{ - int err; - struct srcimp_mgr *srcimp_mgr; - struct imapper *entry; - - *rsrcimp_mgr = NULL; - srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL); - if (!srcimp_mgr) - return -ENOMEM; - - err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw); - if (err) - goto error1; - - spin_lock_init(&srcimp_mgr->mgr_lock); - spin_lock_init(&srcimp_mgr->imap_lock); - INIT_LIST_HEAD(&srcimp_mgr->imappers); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) { - err = -ENOMEM; - goto error2; - } - entry->slot = entry->addr = entry->next = entry->user = 0; - list_add(&entry->list, &srcimp_mgr->imappers); - srcimp_mgr->init_imap = entry; - srcimp_mgr->init_imap_added = 1; - - srcimp_mgr->get_srcimp = get_srcimp_rsc; - srcimp_mgr->put_srcimp = put_srcimp_rsc; - srcimp_mgr->imap_add = srcimp_imap_add; - srcimp_mgr->imap_delete = srcimp_imap_delete; - - *rsrcimp_mgr = srcimp_mgr; - - return 0; - -error2: - rsc_mgr_uninit(&srcimp_mgr->mgr); -error1: - kfree(srcimp_mgr); - return err; -} - -int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr) -{ - unsigned long flags; - - /* free src input mapper list */ - spin_lock_irqsave(&srcimp_mgr->imap_lock, flags); - free_input_mapper_list(&srcimp_mgr->imappers); - spin_unlock_irqrestore(&srcimp_mgr->imap_lock, flags); - - rsc_mgr_uninit(&srcimp_mgr->mgr); - kfree(srcimp_mgr); - - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.h deleted file mode 100644 index 259366aa..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * 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 ctsrc.h - * - * @Brief - * This file contains the definition of the Sample Rate Convertor - * resource management object. - * - * @Author Liu Chun - * @Date May 13 2008 - * - */ - -#ifndef CTSRC_H -#define CTSRC_H - -#include "ctresource.h" -#include "ctimap.h" -#include <linux/spinlock.h> -#include <linux/list.h> - -#define SRC_STATE_OFF 0x0 -#define SRC_STATE_INIT 0x4 -#define SRC_STATE_RUN 0x5 - -#define SRC_SF_U8 0x0 -#define SRC_SF_S16 0x1 -#define SRC_SF_S24 0x2 -#define SRC_SF_S32 0x3 -#define SRC_SF_F32 0x4 - -/* Define the descriptor of a src resource */ -enum SRCMODE { - MEMRD, /* Read data from host memory */ - MEMWR, /* Write data to host memory */ - ARCRW, /* Read from and write to audio ring channel */ - NUM_SRCMODES -}; - -struct src_rsc_ops; - -struct src { - struct rsc rsc; /* Basic resource info */ - struct src *intlv; /* Pointer to next interleaved SRC in a series */ - struct src_rsc_ops *ops; /* SRC specific operations */ - /* Number of contiguous srcs for interleaved usage */ - unsigned char multi; - unsigned char mode; /* Working mode of this SRC resource */ -}; - -struct src_rsc_ops { - int (*set_state)(struct src *src, unsigned int state); - int (*set_bm)(struct src *src, unsigned int bm); - int (*set_sf)(struct src *src, unsigned int sf); - int (*set_pm)(struct src *src, unsigned int pm); - int (*set_rom)(struct src *src, unsigned int rom); - int (*set_vo)(struct src *src, unsigned int vo); - int (*set_st)(struct src *src, unsigned int st); - int (*set_bp)(struct src *src, unsigned int bp); - int (*set_cisz)(struct src *src, unsigned int cisz); - int (*set_ca)(struct src *src, unsigned int ca); - int (*set_sa)(struct src *src, unsigned int sa); - int (*set_la)(struct src *src, unsigned int la); - int (*set_pitch)(struct src *src, unsigned int pitch); - int (*set_clr_zbufs)(struct src *src); - int (*commit_write)(struct src *src); - int (*get_ca)(struct src *src); - int (*init)(struct src *src); - struct src* (*next_interleave)(struct src *src); -}; - -/* Define src resource request description info */ -struct src_desc { - /* Number of contiguous master srcs for interleaved usage */ - unsigned char multi; - unsigned char msr; - unsigned char mode; /* Working mode of the requested srcs */ -}; - -/* Define src manager object */ -struct src_mgr { - struct rsc_mgr mgr; /* Basic resource manager info */ - spinlock_t mgr_lock; - - /* request src resource */ - int (*get_src)(struct src_mgr *mgr, - const struct src_desc *desc, struct src **rsrc); - /* return src resource */ - int (*put_src)(struct src_mgr *mgr, struct src *src); - int (*src_enable_s)(struct src_mgr *mgr, struct src *src); - int (*src_enable)(struct src_mgr *mgr, struct src *src); - int (*src_disable)(struct src_mgr *mgr, struct src *src); - int (*commit_write)(struct src_mgr *mgr); -}; - -/* Define the descriptor of a SRC Input Mapper resource */ -struct srcimp_mgr; -struct srcimp_rsc_ops; - -struct srcimp { - struct rsc rsc; - unsigned char idx[8]; - struct imapper *imappers; - unsigned int mapped; /* A bit-map indicating which conj rsc is mapped */ - struct srcimp_mgr *mgr; - struct srcimp_rsc_ops *ops; -}; - -struct srcimp_rsc_ops { - int (*map)(struct srcimp *srcimp, struct src *user, struct rsc *input); - int (*unmap)(struct srcimp *srcimp); -}; - -/* Define SRCIMP resource request description info */ -struct srcimp_desc { - unsigned int msr; -}; - -struct srcimp_mgr { - struct rsc_mgr mgr; /* Basic resource manager info */ - spinlock_t mgr_lock; - spinlock_t imap_lock; - struct list_head imappers; - struct imapper *init_imap; - unsigned int init_imap_added; - - /* request srcimp resource */ - int (*get_srcimp)(struct srcimp_mgr *mgr, - const struct srcimp_desc *desc, - struct srcimp **rsrcimp); - /* return srcimp resource */ - int (*put_srcimp)(struct srcimp_mgr *mgr, struct srcimp *srcimp); - int (*imap_add)(struct srcimp_mgr *mgr, struct imapper *entry); - int (*imap_delete)(struct srcimp_mgr *mgr, struct imapper *entry); -}; - -/* Constructor and destructor of SRC resource manager */ -int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr); -int src_mgr_destroy(struct src_mgr *src_mgr); -/* Constructor and destructor of SRCIMP resource manager */ -int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrc_mgr); -int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr); - -#endif /* CTSRC_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.c b/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.c deleted file mode 100644 index 03fb9090..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * 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 <linux/slab.h> -#include <linux/math64.h> -#include <linux/moduleparam.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include "ctatc.h" -#include "cthardware.h" -#include "cttimer.h" - -static bool use_system_timer; -MODULE_PARM_DESC(use_system_timer, "Force to use system-timer"); -module_param(use_system_timer, bool, S_IRUGO); - -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 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 */ -}; - - -/* - * 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 MIN_TICKS 1 -#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; - } -} - -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. - * 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, int can_update) -{ - struct ct_timer_instance *ti; - 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) { - 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); - } - if (ti->need_update && !can_update) - min_intr = 0; /* pending to the next irq */ - if (ti->frag_count < min_intr) - min_intr = ti->frag_count; - } - - if (min_intr < MIN_TICKS) - min_intr = MIN_TICKS; - ct_xfitimer_irq_rearm(atimer, min_intr); - 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->running && 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, 1); - 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->running = 0; - ti->need_update = 0; -} - - -/* start/stop the timer */ -static void ct_xfitimer_update(struct ct_timer *atimer) -{ - unsigned long flags; - - 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; - } - - ct_xfitimer_irq_stop(atimer); - ct_xfitimer_reprogram(atimer, 0); - spin_unlock_irqrestore(&atimer->lock, flags); -} - -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); - if (list_empty(&ti->running_list)) - atimer->wc = ct_xfitimer_get_wc(atimer); - ti->running = 1; - ti->need_update = 0; - 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->running = 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 - */ - -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) { - 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 { - snd_printd(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/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.h b/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.h deleted file mode 100644 index 97934822..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Timer handling - */ - -#ifndef __CTTIMER_H -#define __CTTIMER_H - -#include <linux/spinlock.h> -#include <linux/timer.h> -#include <linux/list.h> - -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 */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.c deleted file mode 100644 index 6109490b..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.c +++ /dev/null @@ -1,247 +0,0 @@ -/** - * 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 ctvmem.c - * - * @Brief - * This file contains the implementation of virtual memory management object - * for card device. - * - * @Author Liu Chun - * @Date Apr 1 2008 - */ - -#include "ctvmem.h" -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/io.h> -#include <sound/pcm.h> - -#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. - * @size must be page aligned. - * */ -static struct ct_vm_block * -get_vm_block(struct ct_vm *vm, unsigned int size) -{ - struct ct_vm_block *block = NULL, *entry; - struct list_head *pos; - - size = CT_PAGE_ALIGN(size); - if (size > vm->size) { - printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual " - "memory space available!\n"); - return NULL; - } - - mutex_lock(&vm->lock); - list_for_each(pos, &vm->unused) { - entry = list_entry(pos, struct ct_vm_block, list); - if (entry->size >= size) - break; /* found a block that is big enough */ - } - if (pos == &vm->unused) - goto out; - - if (entry->size == size) { - /* Move the vm node from unused list to used list directly */ - list_move(&entry->list, &vm->used); - vm->size -= size; - block = entry; - goto out; - } - - block = kzalloc(sizeof(*block), GFP_KERNEL); - if (!block) - goto out; - - block->addr = entry->addr; - block->size = size; - list_add(&block->list, &vm->used); - entry->addr += size; - entry->size -= size; - vm->size -= size; - - out: - mutex_unlock(&vm->lock); - return block; -} - -static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block) -{ - struct ct_vm_block *entry, *pre_ent; - struct list_head *pos, *pre; - - block->size = CT_PAGE_ALIGN(block->size); - - mutex_lock(&vm->lock); - list_del(&block->list); - vm->size += block->size; - - list_for_each(pos, &vm->unused) { - entry = list_entry(pos, struct ct_vm_block, list); - if (entry->addr >= (block->addr + block->size)) - break; /* found a position */ - } - if (pos == &vm->unused) { - list_add_tail(&block->list, &vm->unused); - entry = block; - } else { - if ((block->addr + block->size) == entry->addr) { - entry->addr = block->addr; - entry->size += block->size; - kfree(block); - } else { - __list_add(&block->list, pos->prev, pos); - entry = block; - } - } - - pos = &entry->list; - pre = pos->prev; - while (pre != &vm->unused) { - entry = list_entry(pos, struct ct_vm_block, list); - pre_ent = list_entry(pre, struct ct_vm_block, list); - if ((pre_ent->addr + pre_ent->size) > entry->addr) - break; - - pre_ent->size += entry->size; - list_del(pos); - kfree(entry); - pos = pre; - pre = pos->prev; - } - mutex_unlock(&vm->lock); -} - -/* Map host addr (kmalloced/vmalloced) to device logical addr. */ -static struct ct_vm_block * -ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size) -{ - struct ct_vm_block *block; - unsigned int pte_start; - unsigned i, pages; - unsigned long *ptp; - - block = get_vm_block(vm, size); - if (block == NULL) { - printk(KERN_ERR "ctxfi: No virtual memory block that is big " - "enough to allocate!\n"); - return NULL; - } - - ptp = (unsigned long *)vm->ptp[0].area; - pte_start = (block->addr >> CT_PAGE_SHIFT); - pages = block->size >> CT_PAGE_SHIFT; - for (i = 0; i < pages; i++) { - unsigned long addr; - addr = snd_pcm_sgbuf_get_addr(substream, i << CT_PAGE_SHIFT); - ptp[pte_start + i] = addr; - } - - block->size = size; - return block; -} - -static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block) -{ - /* do unmapping */ - put_vm_block(vm, block); -} - -/* * - * return the host physical addr of the @index-th device - * page table page on success, or ~0UL on failure. - * The first returned ~0UL indicates the termination. - * */ -static dma_addr_t -ct_get_ptp_phys(struct ct_vm *vm, int index) -{ - dma_addr_t addr; - - addr = (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr; - - return addr; -} - -int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci) -{ - struct ct_vm *vm; - struct ct_vm_block *block; - int i, err = 0; - - *rvm = NULL; - - vm = kzalloc(sizeof(*vm), GFP_KERNEL); - if (!vm) - return -ENOMEM; - - mutex_init(&vm->lock); - - /* Allocate page table pages */ - for (i = 0; i < CT_PTP_NUM; i++) { - err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(pci), - PAGE_SIZE, &vm->ptp[i]); - if (err < 0) - break; - } - if (err < 0) { - /* no page table pages are allocated */ - ct_vm_destroy(vm); - return -ENOMEM; - } - vm->size = CT_ADDRS_PER_PAGE * i; - vm->map = ct_vm_map; - vm->unmap = ct_vm_unmap; - vm->get_ptp_phys = ct_get_ptp_phys; - INIT_LIST_HEAD(&vm->unused); - INIT_LIST_HEAD(&vm->used); - block = kzalloc(sizeof(*block), GFP_KERNEL); - if (NULL != block) { - block->addr = 0; - block->size = vm->size; - list_add(&block->list, &vm->unused); - } - - *rvm = vm; - return 0; -} - -/* The caller must ensure no mapping pages are being used - * by hardware before calling this function */ -void ct_vm_destroy(struct ct_vm *vm) -{ - int i; - struct list_head *pos; - struct ct_vm_block *entry; - - /* free used and unused list nodes */ - while (!list_empty(&vm->used)) { - pos = vm->used.next; - list_del(pos); - entry = list_entry(pos, struct ct_vm_block, list); - kfree(entry); - } - while (!list_empty(&vm->unused)) { - pos = vm->unused.next; - list_del(pos); - entry = list_entry(pos, struct ct_vm_block, list); - kfree(entry); - } - - /* free allocated page table pages */ - for (i = 0; i < CT_PTP_NUM; i++) - snd_dma_free_pages(&vm->ptp[i]); - - vm->size = 0; - - kfree(vm); -} diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.h deleted file mode 100644 index e6da60eb..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * 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 ctvmem.h - * - * @Brief - * This file contains the definition of virtual memory management object - * for card device. - * - * @Author Liu Chun - * @Date Mar 28 2008 - */ - -#ifndef CTVMEM_H -#define CTVMEM_H - -#define CT_PTP_NUM 4 /* num of device page table pages */ - -#include <linux/mutex.h> -#include <linux/list.h> -#include <linux/pci.h> -#include <sound/memalloc.h> - -/* 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 */ - struct list_head list; -}; - -struct snd_pcm_substream; - -/* Virtual memory management object for card device */ -struct ct_vm { - struct snd_dma_buffer ptp[CT_PTP_NUM]; /* Device page table pages */ - unsigned int size; /* Available addr space in bytes */ - struct list_head unused; /* List of unused blocks */ - struct list_head used; /* List of used blocks */ - struct mutex lock; - - /* Map host addr (kmalloced/vmalloced) to device logical addr. */ - struct ct_vm_block *(*map)(struct ct_vm *, struct snd_pcm_substream *, - int size); - /* Unmap device logical addr area. */ - void (*unmap)(struct ct_vm *, struct ct_vm_block *block); - dma_addr_t (*get_ptp_phys)(struct ct_vm *vm, int index); -}; - -int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci); -void ct_vm_destroy(struct ct_vm *vm); - -#endif /* CTVMEM_H */ diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/xfi.c b/ANDROID_3.4.5/sound/pci/ctxfi/xfi.c deleted file mode 100644 index 15d95d2b..00000000 --- a/ANDROID_3.4.5/sound/pci/ctxfi/xfi.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * xfi linux driver. - * - * 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. - */ - -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/moduleparam.h> -#include <linux/pci_ids.h> -#include <linux/module.h> -#include <sound/core.h> -#include <sound/initval.h> -#include "ctatc.h" -#include "cthardware.h" - -MODULE_AUTHOR("Creative Technology Ltd"); -MODULE_DESCRIPTION("X-Fi driver version 1.03"); -MODULE_LICENSE("GPL v2"); -MODULE_SUPPORTED_DEVICE("{{Creative Labs, Sound Blaster X-Fi}"); - -static unsigned int reference_rate = 48000; -static unsigned int multiple = 2; -MODULE_PARM_DESC(reference_rate, "Reference rate (default=48000)"); -module_param(reference_rate, uint, S_IRUGO); -MODULE_PARM_DESC(multiple, "Rate multiplier (default=2)"); -module_param(multiple, uint, S_IRUGO); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; -static unsigned int subsystem[SNDRV_CARDS]; - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver"); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver"); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver"); -module_param_array(subsystem, int, NULL, 0444); -MODULE_PARM_DESC(subsystem, "Override subsystem ID for Creative X-Fi driver"); - -static DEFINE_PCI_DEVICE_TABLE(ct_pci_dev_ids) = { - /* only X-Fi is supported, so... */ - { 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); - -static int __devinit -ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct ct_atc *atc; - int err; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - - if (!enable[dev]) { - dev++; - return -ENOENT; - } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err) - return err; - if ((reference_rate != 48000) && (reference_rate != 44100)) { - printk(KERN_ERR "ctxfi: Invalid reference_rate value %u!!!\n", - reference_rate); - printk(KERN_ERR "ctxfi: The valid values for reference_rate " - "are 48000 and 44100, Value 48000 is assumed.\n"); - reference_rate = 48000; - } - if ((multiple != 1) && (multiple != 2) && (multiple != 4)) { - printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n", - multiple); - printk(KERN_ERR "ctxfi: The valid values for multiple are " - "1, 2 and 4, Value 2 is assumed.\n"); - multiple = 2; - } - err = ct_atc_create(card, pci, reference_rate, multiple, - pci_id->driver_data, subsystem[dev], &atc); - if (err < 0) - goto error; - - card->private_data = atc; - - /* Create alsa devices supported by this card */ - err = ct_atc_create_alsa_devs(atc); - if (err < 0) - goto error; - - strcpy(card->driver, "SB-XFi"); - strcpy(card->shortname, "Creative 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) - goto error; - - pci_set_drvdata(pci, card); - dev++; - - return 0; - -error: - snd_card_free(card); - return err; -} - -static void __devexit ct_card_remove(struct pci_dev *pci) -{ - snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); -} - -#ifdef CONFIG_PM -static int ct_card_suspend(struct pci_dev *pci, pm_message_t state) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct ct_atc *atc = card->private_data; - - return atc->suspend(atc, state); -} - -static int ct_card_resume(struct pci_dev *pci) -{ - struct snd_card *card = pci_get_drvdata(pci); - struct ct_atc *atc = card->private_data; - - return atc->resume(atc); -} -#endif - -static struct pci_driver ct_driver = { - .name = KBUILD_MODNAME, - .id_table = ct_pci_dev_ids, - .probe = ct_card_probe, - .remove = __devexit_p(ct_card_remove), -#ifdef CONFIG_PM - .suspend = ct_card_suspend, - .resume = ct_card_resume, -#endif -}; - -static int __init ct_card_init(void) -{ - return pci_register_driver(&ct_driver); -} - -static void __exit ct_card_exit(void) -{ - pci_unregister_driver(&ct_driver); -} - -module_init(ct_card_init) -module_exit(ct_card_exit) |