From 8a96784240a1da37bd2e91860a62df4c06e3570a Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Tue, 14 Jun 2011 18:10:03 +0200 Subject: [PATCH 01/17] xbmc: add patch to show our RSS News feeds too Signed-off-by: Stephan Raue --- ...10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 packages/mediacenter/xbmc/patches/xbmc-10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch new file mode 100644 index 0000000000..5b32c0cce7 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch @@ -0,0 +1,11 @@ +diff -Naur xbmc-10.1-Dharma/userdata/RssFeeds.xml xbmc-10.1-Dharma.patch/userdata/RssFeeds.xml +--- xbmc-10.1-Dharma/userdata/RssFeeds.xml 2011-03-08 02:49:24.000000000 +0100 ++++ xbmc-10.1-Dharma.patch/userdata/RssFeeds.xml 2011-06-14 17:07:08.450880123 +0200 +@@ -3,6 +3,7 @@ + + + ++ http://openelec.tv/news?format=feed&type=rss + http://feeds.feedburner.com/xbmc + + From 648e68ce48839eeb772aa376b5def9b4c2753282 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Tue, 14 Jun 2011 23:23:04 +0200 Subject: [PATCH 02/17] projects/Intel/linux: add Broadcom Tigon3 LAN driver Signed-off-by: Stephan Raue --- projects/Intel/linux/linux.i386.conf | 26 +++++++++++++++++++++++--- projects/Intel/linux/linux.x86_64.conf | 26 +++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/projects/Intel/linux/linux.i386.conf b/projects/Intel/linux/linux.i386.conf index 1ef90d4362..7b7e59d5a2 100644 --- a/projects/Intel/linux/linux.i386.conf +++ b/projects/Intel/linux/linux.i386.conf @@ -99,7 +99,6 @@ CONFIG_IRQ_FORCED_THREADING=y # RCU Subsystem # CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set # CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 @@ -939,7 +938,28 @@ CONFIG_NETDEVICES=y # CONFIG_NET_SB1000 is not set # CONFIG_ARCNET is not set CONFIG_MII=y -# CONFIG_PHYLIB is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM63XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set @@ -995,7 +1015,7 @@ CONFIG_R8169=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set +CONFIG_TIGON3=y # CONFIG_BNX2 is not set # CONFIG_CNIC is not set # CONFIG_QLA3XXX is not set diff --git a/projects/Intel/linux/linux.x86_64.conf b/projects/Intel/linux/linux.x86_64.conf index 5583d74fb4..d461a1d86d 100644 --- a/projects/Intel/linux/linux.x86_64.conf +++ b/projects/Intel/linux/linux.x86_64.conf @@ -99,7 +99,6 @@ CONFIG_IRQ_FORCED_THREADING=y # RCU Subsystem # CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set # CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 @@ -889,7 +888,28 @@ CONFIG_NETDEVICES=y # CONFIG_NET_SB1000 is not set # CONFIG_ARCNET is not set CONFIG_MII=y -# CONFIG_PHYLIB is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM63XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set @@ -945,7 +965,7 @@ CONFIG_R8169=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set +CONFIG_TIGON3=y # CONFIG_BNX2 is not set # CONFIG_CNIC is not set # CONFIG_QLA3XXX is not set From 1f21b86d85b206bb07ba569e6060d1905e69d432 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Tue, 14 Jun 2011 23:23:39 +0200 Subject: [PATCH 03/17] projects/Generic/linux: update kernel config Signed-off-by: Stephan Raue --- projects/Generic/linux/linux.i386.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/Generic/linux/linux.i386.conf b/projects/Generic/linux/linux.i386.conf index 81f6c4113a..43a4e7e939 100644 --- a/projects/Generic/linux/linux.i386.conf +++ b/projects/Generic/linux/linux.i386.conf @@ -99,7 +99,6 @@ CONFIG_IRQ_FORCED_THREADING=y # RCU Subsystem # CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set # CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 From 3ea90cf07f6ef796ab3811cf83e8cb120dfa9eb3 Mon Sep 17 00:00:00 2001 From: Gujs Date: Tue, 14 Jun 2011 23:29:57 +0200 Subject: [PATCH 04/17] addons: add first version of oscam to service addons --- packages/addons/service/softcam/oscam/addon | 29 +++++++ packages/addons/service/softcam/oscam/build | 27 +++++++ .../service/softcam/oscam/changelog.txt | 2 + .../service/softcam/oscam/config/oscam.conf | 31 ++++++++ .../service/softcam/oscam/icon/icon.png | Bin 0 -> 15282 bytes packages/addons/service/softcam/oscam/meta | 39 ++++++++++ .../softcam/oscam/source/bin/oscam.service | 72 ++++++++++++++++++ .../service/softcam/oscam/source/default.py | 23 ++++++ tools/mkpkg/mkpkg_oscam | 44 +++++++++++ 9 files changed, 267 insertions(+) create mode 100755 packages/addons/service/softcam/oscam/addon create mode 100755 packages/addons/service/softcam/oscam/build create mode 100644 packages/addons/service/softcam/oscam/changelog.txt create mode 100644 packages/addons/service/softcam/oscam/config/oscam.conf create mode 100644 packages/addons/service/softcam/oscam/icon/icon.png create mode 100644 packages/addons/service/softcam/oscam/meta create mode 100755 packages/addons/service/softcam/oscam/source/bin/oscam.service create mode 100644 packages/addons/service/softcam/oscam/source/default.py create mode 100755 tools/mkpkg/mkpkg_oscam diff --git a/packages/addons/service/softcam/oscam/addon b/packages/addons/service/softcam/oscam/addon new file mode 100755 index 0000000000..0863220d80 --- /dev/null +++ b/packages/addons/service/softcam/oscam/addon @@ -0,0 +1,29 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. config/options $1 + +mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin + cp -P $PKG_BUILD/oscam $ADDON_BUILD/$PKG_ADDON_ID/bin + cp -PR $PKG_DIR/config/oscam.conf $ADDON_BUILD/$PKG_ADDON_ID/oscam-default.conf + + diff --git a/packages/addons/service/softcam/oscam/build b/packages/addons/service/softcam/oscam/build new file mode 100755 index 0000000000..70bbd406a0 --- /dev/null +++ b/packages/addons/service/softcam/oscam/build @@ -0,0 +1,27 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. config/options $1 + +cd $PKG_BUILD +cmake -DWEBIF=1 +make diff --git a/packages/addons/service/softcam/oscam/changelog.txt b/packages/addons/service/softcam/oscam/changelog.txt new file mode 100644 index 0000000000..5c9a1ea79d --- /dev/null +++ b/packages/addons/service/softcam/oscam/changelog.txt @@ -0,0 +1,2 @@ +0.99.1 +- initial version oscam-5377 diff --git a/packages/addons/service/softcam/oscam/config/oscam.conf b/packages/addons/service/softcam/oscam/config/oscam.conf new file mode 100644 index 0000000000..f5a0ebc151 --- /dev/null +++ b/packages/addons/service/softcam/oscam/config/oscam.conf @@ -0,0 +1,31 @@ +# oscam.conf generated automatically by Streamboard OSCAM 1.00-unstable_svn build #0 +# Read more: http://streamboard.gmc.to/svn/oscam/trunk/Distribution/doc/txt/oscam.conf.txt + +[global] +usrfile = /storage/.xbmc/userdata/addon_data/service.softcam.oscam/log/oscamuser.log +logfile = /storage/.xbmc/userdata/addon_data/service.softcam.oscam/log/oscam.log +cwlogdir = /storage/.xbmc/userdata/addon_data/service.softcam.oscam/log/cw +nice = -1 +saveinithistory = 1 + +[monitor] +port = 988 +aulow = 120 +hideclient_to = 15 +monlevel = 1 +appendchaninfo = 0 + +[webif] +httpport = 8888 +httpuser = oscam +httppwd = oscam +httpallowed = 0.0.0.0-255.255.255.255 + +[anticasc] +enabled = 1 +numusers = 1 +samples = 5 +penalty = 1 +aclogfile = /storage/.xbmc/userdata/addon_data/service.softcam.oscam/log/aclog.log +denysamples = 4 + diff --git a/packages/addons/service/softcam/oscam/icon/icon.png b/packages/addons/service/softcam/oscam/icon/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b936a07d690f5732d56e25b38a6a46b0742b6e2b GIT binary patch literal 15282 zcmeIZXH-*N*EYIQ)Sz@h10oWNCI~_V=|v+&qM!*Kq{a}6H0hliA}WR=O~e2S1SJrV zuJjrZ5Tpg9geIUAgA`F|-@f1Tj`RI~ew-g?jAxG#vXi|s*IIM0HLq)4bMxemkv`XP z;o|@Ra2edt!GiB(@TCJe1peKr?zRBmZUviI_+lLb#JnDOI=S4(i}?n5;l=QQE=~Xt zI5vl-b>5o80*7%Dmrfe{oKU!_pm11BzErVP5zT&ChEuGG_c19l4@u-YdHv{JAl8eA z)buCV3;;L?E}&ft!&_=NPxng>_dFf(mjd0rzzzXGLp#vR0q2JI6?4QBTs$)|8uuZjQ1 zh7R5b_rS%=*TvIA>|dJ>j-GzLn&RT%b+P|7?(5?8f317?{I3&0cgX#FMGkpMUhaRI z|NBYJz}H+Q+`>#Qk`6qoyVsB-^1R&eTa|L@%Y9l-zh$A3Hdk9_=Jcm3C0|B(m& zqsISTUH^60f8>GxsPTVS*Z;rVb^QObC%gwpnF2s=Wc}$e3glIXeNYA_5C~*^=JqrI zhyeyV*GvM(ChLPzZ1jV^?F_%~@QJtbC>&pxOuTWwdxLmP!~T+g6pobn^$7prAgEW% z?@lW@OCCm-)UqxAk66~HoAMvnIfG8$vOr2I9X%#u_wwphe&`x}JV~ln^P{VE+F!Ef z@Lg8I60<(6X4u2QXUeMN;PXI9q5tsquz72BBh@CZS7nX_j|Hxx5vFH|{HU5V5<_Q-sUL77GW<<8vp*n63JE~n=Lk>$Lu zM~cvVx)r(zF5nIwXmaN2-h;r>_AkfJQ5ret@1Vw}#NH4`jywG24i~RQD~4T6Fyw$1hLh=3_y5i%op#-Y4w+ z)w8<&-Mw5koVc3R?{jcLK*lLtb%-I;D{?W%WUKDDh7D{Zr>9Glv$713k0(}z;f3zn zEVMrpUP!D8Ai?lNenvZE7f77{Uik2s!a?Cf{1vs)x)FbF08(z!Stl_5(OxRWRa9cX z5sCo5TB3zm84B@pmmcV)ROyYMa)Y51;$V2mg=f4qS1fuYUVm*)o+pdIH!(zPW*h8dVEY`~X zteEPScj$HP?R@)oUFHaoD=788Xvv-xiF%y4L{112z}AjtWM391LOGA7*aMI%A>FgT-?A)T|H0K zWCOpjugh(#<~^a-;+^#q1a8N#mgj7O+O1njcTbrzyP>aT^AR0Hw#f3DQ{r)R&vgk` z08%VZeq8p!bG+M7nIP zbA@|t?`3B{;f`xnk$g87CT|dG;C_dJpHVx)PQP^p)JVF$5MZcM_&UyST$PyQuwWs? z7Rg_CD2DmD{nb9SO4G$sBdvkND6*dIRP)k9xC$A-nBY`_|_URQ}IT;-(36x9G zmB9uJ<}r%t$uf&@Rf5^oLay^N@i_X8Wruvr1Y}NS|?!_(#(jKCACLjWCa zl=RpeX5!YUvVeN~PK2E^ES{g-=5p1Yt2xD6I8V4W`a^iPqlJ2l03}7$B#&6>T#-Yn zWADJ8miOJ0cW*NoXn%acfnU=^@=bQQ^lK3yF~DzdGgxR5)1=pFD<{Do!h$p#N`zQ; z<#t*bLOh5octkTq;|@v~wo`9=H3}nvZyd=bMjqq2flkd6TI2-k^s!W#n~Qvjyrvmj zDimOvk3Xj?MDy0W4bhWD_Xfo&CLhlm464kI)kM0a<#~%>Us~M@>aq9?N#PIDKZ2km zZz_m-FLJ^x5NGA{j!HtKk3~f{{E^1o_)=`gP@`-$e-4sNjh|DA%|+@2@~J*WS<{ZX z^hmg$1#Zw7MV74)ZaC4Z-09P-_}vs){uXM^%GPBR6tF1Nl{Ifc%jB4$9@}=r@uN7^ z1fMKPSqKcj(za-$dOYK+6BsetJk9LLtUAxy5|RL3RniK@SzFde7N7CaWa*0bf&QG= z7d+gGB70v@1@^+@f1>VPmCfnoS`&0ea+p@w0p$N|S2QYRXk%AjhNr#lW= z6W`TbViR-JfDg2P4r6;2$8nQZQ-Hllxn+R|#AHqp`=ei1$$i{inhR~Ef_?U~cKttV z^!Whr?jSh{XF;c+)Jl-bur!1wEb`?BrAYt2JNKg87rAk$ z%c;~dS5h$UzTtqlgi2mlKDV*k4R>T;us6S~p&&Zu2^(&S{33!ccJ8rvfobQ&Y!39; zHPZLv??au8D3=*a9t*l(O{52fi#};29P7K)3fPR=Afubx$~wihL_{rQ*8^2F66r#7 zp@>hYG_7L-upb5O|HE!vmLR(9F3Q;^Hd)R$tKfb-F zsn5%}TbWm2SEdJgHn`Cxw{ziXSmG1qz75IQIFoM25oQTH#jLQS#)V$n+ct*B+%$bk z-2s0KE{CdRUu2IOo89auzrFLAdiLeAr??mGsN09UO4yOjex@afUt9%w!!}#b3CDGP z)-z~hvqz{AawIh^Tx+!xb$0Q_*D*Jd6)QKfPchJWxtFT1hNzi-^gD_J7JJf;wf1oi z=`*#XnaN{ApU)q=X~T7NWYJ#m^>*XI9*~&tuw`q}XUirU^z|<;LGxESF8)*5{rkA( zpB(`_i+bbL+M|#s09(^?pX$z9>&RsIPBq(Sm}!N_WR2lVC8JwKlNBz;)v;f`eChE2 zVPeG!zJCD_Y4BJAA-0y)5Ry%P!4|34X?Hbu&`5o2bFlCI&lAexB-_cVzfv$maigHT z6z;QiQ+n9r;Q&vaq0K9$*(9J-y$gPKzz~40mU`NjW z{*34ZA-9Kj$Amp=|5AN=RSDlkSGgiKly~ezxc>?zoTQk1Ybd<`>$?OaVkKeUxu|Kz z>-YED2M;mFffRx0@W!3{B_p{hk05-UJS0>uaqf zZ<-*$`ACAYwOT!uh5tT2wa*O%&YhWptkDzy^q)=0cVUMZz&M&)9aNz*#?LV8dB#Sn z+Y=itUb_p*o|)?M%H%T(L9x8t9?iXH)w9MoRt9fth7Av!&j)F#s($dCYABQ0ZhX%J zbfGzqsRA0ne^f`^q z&(RmM0teDv5CnrB;H1BG`0m%4fBNln&KI3=h1HH?_R}LA*1Z{z@nUj0>9HXzTOt2RUVV; zgCRe>nF$Lq_2IXz3u#9p``>-z31;jp+NJM}jWqmi*tV(moYDdUzdn0J!RlJlgf@#R zt!|>fJ1b^bsQ)ZGo)xqpbVlhuq@Q!KDDfyj&9N%?Kg0{Ap^RgC^a>XVgvOt1xqdb_ z4?e!M%H=*9{o;b?2m^~Qq}r;N9_6(%Yz61j$V`(L;r9IfvhPj|TT}3DdC}fD#w|_& zR{bhGkYTOgDns7hVH{d4f*%LIZTonhoyVMJ6ANsa9C}<{Z4+jyK7Xj`M~7(P@^M}c zrKhUN=m)}rhI7q6det724}N@Dd^pr`ZptQA@Tnt=9ar?6Vzn%3SV;A_=z0teOg!k8 z4ao|tf?sr#O?WR5^}se&5XdvQmy$z1t&0>s^*Zh2$B$>#{TtpNT;W=m9LcFQC5C=?KPt_P&Q&J>ICoq@MgNjP@JM?ZU9a62ks=X#|3t2n_ z6Lz7@OEtzd?AY-Uwr?iVqEz&Xt=SxTE;#qD zm3xOa^_M39GbT^{V5_)>T38eQ^I;eYQjp@KC9=H93|e!?$jnyQBuArhP+jEW{Vyi; z(fQ|g4MXj;F6sLbbZ@dG$GWZCO(8=^Be;3a7xkUpm6iK}^4(+?c(C>s7ND}z)!%m(G<`wth;Fh$c$#l zFXC`D-xVnnH+S08WFj(c`!azh;8YMLn-#Ku=KO^V)|4#r3qF*Wo={w>651NDs6Ef2 zH4-}4#)mH|Smr7TG7K0ar(0YUzUGBOJi`j(;cxgrT7Rx6v*g1V2BZ7Z)Rz^7*ien6~F`YLp7C{of~B9*EMvY;IO0qR?N4{01K@ zeG7Z%->|#ht?V(OBEmiH5ZtG!jp)Ldn#R55r9)vndP0S%YyhXNL4T}6N?V-C>mrpW zs9m^yN*+ew9A}^Q!Nj}xqX8a2MQqbD{l^f!Ap07it1cFOER*TOE|a&ILdkebiHu** zPAYloMZVNKj>zN12y|e`+s9UmP5{-+2g}Zi!d#EEbg+4f4B^7^qU`x6r3@$`wQF7S zrtvbVve)V`5Rw(rtHvUi)9Ky<9i=9EE;OCN;cA&~UK^J@^uX>X&j#O}U#kiV3N!#5 zQdDIXRcG)9LRhq&jD-1Bf6p6;GhzPaI-|5QR_Qj?5avL3AAQ%XZmw)N`8dBAI!7+m z>%^b&pIZ)}FYCTkd$7L)22f_!r`nz3h{7%_MJ~GJ?1YM2MKU(ufGp`Ek!n)ocCF~N z$?@fK+qWD*o`4kxtqr>0<=v4PJmzvjRA;O0WI}-YmZ|x{LPoQdd)}2XwPYt%i6M){ zB0q*xy(q4T>v|eqRa28zaaqp*ftX{4z}jCjE512T`1IWt4Y{w6IR)60o}twV*M3xQywF(yTAHWFC&pR2OZ9G}S5^KpYstZj~5mqw=7z)X!+*6|J`s-|_z< z95Z}p)m;EAsOTYv72_BvxAt5pkixL)uJT4<^a=-!w9f+mD}lcL{#9pP4U$|bOVrmX zAzoNG?dyR5kCGSff7C3;w9bs|&lJ8?_Vk!Svm(~Cq$JM^u=$HN1ugnEPIWkFjZiPf z+;?3eJDebF-7|i)m#kaSYdNBec7|SeVAL=7st5cS{c^=M4S(+M+A$#tGlZoHh()D1 z*ZDA2N%An2*c|`ApEf3(@g!ug%3|Gi$Jv01p&=9N>CAwMe#JOmtlM0Dx!%br4tfew z@2wI)?6y3|jOdpkrs`T2@9vAf(0ms(8nH;$=bP&hj?*|EKMVp~MDrhT#QR<54ZEO2 z{YFgOQv?Ro7VA$i6YmSN=w~|A17-~_9BR7Gqh%qWTYE{g;fL3v2AvtSnCX_Gc1v=S zKr3}X?18_p+wYVZcc^h6S1Kg=or1kei3}h*qJ&^ji6RR08tV2%*qPys~k~#1b66FMF`{X!;d@MtFSG1GJNL@ zEn@`nq&rgc?qI>NXX%cq1;gQb0U_mbWK#$$(`Q;D>ubH%n;tcstT<8EfJzy_9(ggR zcpY*kmxSa?D6i{K0SQ_H4i@(!9^ZE-L%&9&mPPf1oM#+y9D0z#2{9x35tV6AOABV*SMQv zZ1iD1ErMC&H{P#*Zjuo`a!}VDO&|sFKwwwXFK4|`rME#p4C#?Npou4N5h~Jyk}jpi zOP9Fy@og>w8~#>6WcI->VaIObLhA2<=M5DBEM~Dyg7!X9d$-9?l~1 z$WiT6in`9T=1F|)-2a$kCB1bZ$2UxEhWXymqQ>3_)bC7!fnf*ai+;AzcDqU6!O6xY z5gmzjess&hA;XOP)$(=}COP>LTN6$_;Bw4Mr+&}$bSR*LOED{Z+oclE_QylLBvWIB zT3F1i582iZ-ExEGGOn{nhJ^n;39R)R$I^zq+YowP@Z90_xF|gg=ME4#}!rjF|2Wqaxc$n z2=MDIt*qFxnnOHkvfT?q#`EtltnlZe!-d4y&_hF|pOp=9KB#UJDh1 z86C9#K^?I=@u6JW?G}Xo`^B5=n*G1a(Kh3wEt{L02Y)&u$cryb3^DOBx9wU@sA zke{r<7bbND>C5MkfLDa<$qn;^)e>CQIFEg`qzPjNGH)om$JuGe)seVOGBG9F16qmhn*Llgtxg-%6q(F?Fm7Fo9NZ^4@^ zP_}e^mw)yXuvVTuQl$F1vyJ}}z=K6rV@jLBpdzvCM|aP!)r7!BIK?}OUAf=# zwC?>LJ+{_A-Ec#sirlg=SuR#OUR6bo_$^03P(_>ka{Rrw@uJVc(#H$g4;aEUh~8MI z%uSpq2ED!VWy7xIpc@nt{4bs#-Qw9_;}KdUCh}H7a)Xu`vOcYcAvm2T=dFy9x+=FJ zknBPbsuT!pnG^QjMMp%xGogFp_?Pyaw*!(b09Fb5in^ruguYq-HO_OaE@)#>YkMj? zJtzt37?)P|lX))ucTM}lg%69V*cqP)3VWcrfZ_T;RcuZWZsMRR43F_PYWnly#S3{X zNCzKlI8*9;@LzQJwwN5S;tva%(aqD#$_H~^9wsA{D?iNbs$Gx^UfVWkM6Zh8G+CG3 z+%z@s=dRFbe8V+P7`uZ>>`}Mn3cnp5QcGT_JULyZjtj=tWPDrGCGHAC?cDBjvX2p5 zA_d|8tN#5#$-&+XjUZ}RiQw*yL4=Z6Nz1WyCuYkTJ|cOmHZd}0$nxMavF>CHs3 ztFR#(Q^O=l=*hXzi}w=c?SJPHQia>S>-OK~GW~~5LGatzZw$*;aHS2?g>X-EmeA|F z4PoTV#JUY;khXBDw@46?j%I=ms&XIC3R_SWEq!;h3`8b>%ghX|7FD~{E4ZPMlFHi6 zk?_@jB^?j}8(0lHDQ4)GA7<9xpEPn_o-D(kdBX`4_%*yt{a7YS@4WOj+o`_z?~FxZ z3jYaMEJjF6V}QW{>v9}&v=Q_(%`?!j7-Yo+ZU4x;(kqOsz#52PS^$UK)GIYp%eorO z+5lE|*t)iVW`3EBvisO(jB?%U%FUIP6^6St>ZTB(6&d-XSpdZW1g_~J3Uo5)P>1DE z^G>g;S`gLq8(r!7-$SN$8o--(rqN3RHzE9{;u(tJmzrm=U5QpQ{4IuZ8&@<;%7emi z_svNodrRJcyuyZ#Ksz%8mx*;{`Sew`dQ1+@RPv@gv+v*1FK%4O2>8LQ-^qX3KuwX3 z#h9j&H_Cg}YH8a9?L7n#$fA{^sfr&V*BHNRq^;x9sCKDQF|XvsH>OUo2b4s^^YqA- zY>#BRZ3AbHz}QibFYCc|*>xn~xzN|}S?F?2X`jZ%1i|z7I8XSu!;=cL#>U302aP|s zN)Dr@>lrcnBDlJqV>`^7lq5-A2p_7hy8VV2F->qiac%agTn72yqweQZHi3|$0Xp5PS;s&XyocBglCw$I&|8&&m8p{MIKhp zQh3XwJ~0R8rhbby0YWr34V21k-Sb5-xIKDY$q3Ph;7JRX#c_VUs;oJX7R zw+ni5ohhCfx~U8w-TP7-P-4bVJqE$h%QTF~tkf^je|BWcD=3r)_?KYK+`f|&az~-# zst2DFgp|jmWg-^GrkEg5ZH?F+Y$}AL@Q>X<3oU+pav^JUA!7QUow!mubS>*a7Qr$p z|6ud>LB)E#O!dTi-@)$$(cdT~*T-olj@87@YyYiyw&|A)vkDpvQ zOnR1dD6!sn6qg{%W8XnvJXBa@h4W(=Yyg+uFyqQ-Zhp#Ri4ir zr0eiqhaf0I61o&d(MNN{1~jH`l1+>?-?$ypSRJvs71ZG;2br9cOhLOO{SC-r}I zNVePWdVach(~Kb`Wtue)fk_GCbl}N&7wZQZTT1sw*D_hVHzkOr)II3__cz(xtpdQh z?QQF5zTmxOx%c22X8!BRDZl65PKwgWl1BlG$%x>;NbF~IBQ+mEAGHVr2~ooeUR_-@ ztU~7I{ff(059NMmZXCN#yJvC7dhnFrOp#wN0x_WYlj%kyA$38nrHX<&Bya?>4i+;H z#x4~*yxVUzZ~O~F;wY4s7w;I)r#lU-6x-C+iW?Q#bVE0|Ro#jd@TT)YWl@P2aXq<_ zjX_(Uhnl9se)vQtCZePDMQ2V=iyKM2E{ry=( zL%y{|F{>A@!rL17Q1~zQQ7z@fX=*X8(o$|}YxKtt+cQAu4E+qPoIP13UOqqNj(gFu za=&FpK;7I~S_%Qw7c&Ex8~{q12W|&}6k!+eKjS>>zLI@<|MU>FHg-44nKjg+qSBOs zcND3LHptlz;b9kB_fPZK-vR(O`0Ki8TjrUIe@3}F4mBl&Z_ZIq%@i6F???>w^dvjv zaX)JP{@sPPwRNx+4E)|W*v-xwSAU9}A*-?2uA;*RP;~+F&`?lFb|#7u?TIZi^K3Q; z&qofXBIc&DJ^=t<^1sglY)#c|&pbXw5or47Q9d8gl&f;L_&mjS(~#sh-=c3j6CQnP zaV~LN^K<35wv5VVVG_kZO>N_!sVuxs^=5 zb7+0u@Vh;GG9I^02vo1ymCy$rx!{YqbVh$ab>ZW@1TiA@uh8+B=|CO3grOw5xbK?Ybhty1! zE3q-iiLf+pMtAw+pUeBxJT)^DFFhNC0Ql<}of}^2Dug{-5Ayym_bJzCLqewCuZ2$+ zTxlG1gC3d!{)@=1&QpDw+Y{P=}mNfULA8DJU&HtNA#W|y-&#M?XlE7@YE@AfV zNcROs5!WIHctu4oW)5^&-GufIjH*e@J6hNO@M~04RsFN}YZaO+8J~y6-pEy?LK z3HbCa{~B?=5p`|M_an45D4ZaUKS5Bd&}3I0qtf3Uw}E zx8zXM9*+hu`7FU^*hD540vpSClNDU1seKeUchIN>(}_k_F%T4TmEWL_cj$r;A?B(# zL{hN*hV^QZxz&SS4*D3B5N3M%nw?w4hApC5<&A*qyIvSYa&f})Q5^Vi#RC)K#pm4d zn#9j%LAC}iLoWZYRX61<|FQ3k_xUcf@Ga2_|4D-C)BUx>=Un%g5eM7nLVupH)9{)G z2qfMpzUIfyw4I=A-r2fJ1_Pf-sE_#boHgOy5zrb4*3$;F_r6?+>(~2U1|N{LzSemF z)`j-ZnD5fxXl)gIn0Y6XYB{jY?c!cBzzSWw@>0ni6!S*vx0!``m%1*;V;Advn1}gM zn>%5`monEtB7c_YkD5xt>S9ESpDNPLbOp5>70oVq3$z?j_t&CUV#XBxGAWwGCMYfr z42FbpgRPUo<(3^V+}9V3Z>!GFojdrwx#?>P9+RK~rOf>OXRmcH3rX{T|}!psrj)6-PpDTeE_!bezkfit?v$;o~;aj_rDM6f9GHWUVPgDtDXb2O*O z!(M)DJ>OFM09piw@$(dR7&~OR4D8#Q_3*SE)YgY@no3>D&mn=|zouSV&QCg#eJ^aQ z5KOSgr;f9oV%4XhI%B-!k!p^A9~Tza)J%qgg}Mu=chFcpB>nMp4PrTe)|&|6ZbkJN zka_hG1iCcNG)Xc=q3Z*0)UC5xM?{Z|yb=+d?k{`HE3L1av|w)ICkQyx%4O!rc3#a# z291pqR)dS6f)L)Lp?^Gg>6GUUf3)lVd?Nb*feSC*c-F2~d4_MiL_t^@6n5PGI4R=g zu62zIL`BnR4OC>ZBHL9{%U~WJ?cL7kZEfE6pD|o#7{xX_jA~m|WT}&*afA_`a77o zWCtyLx!~j^-o^I1rWh#>O_u57X!f(TS&KQbpOCQE|95M-^@ib~@5aI>Q&ZN&2V*x~ zq;BMfhCV2zflFF_YO6Tl@YRg`=xY&EC;A%Kb{kZlAn7?S^7dc*k!RvH4|X>QPEK0C zN)v(>5nvKX<2;{kpRrhfu_Sa^U+XUhbwi{B3rbcO7)CwyfzzcnwK?$o6ln_NJk%?L z0=Z^t@|rfFky!%aBi%?N5U2BtIj+O+&dN|Y11`RC36?h*An*M3VgC6M0M@%#?GFBa zLUrB_ot?Xo>AOC#F|peBNqK6w_1wPK)KfWU3i3P@hpVV$sCTZ*7%D6lZHx(bmdTjp zRq&!ZNQd?OY;H<%zf@Vtd3s4}VKg^lZ)9pfwoayd+@toB>h>gy$@lYybU|F=K%POD zs^)rUF1X2W$9+6`>jYqK8${Uv?GDO(|oleLR1j@k*gr1-C!!r}#YIAcU~=7XCLg zGj_)LlEG|Yaa|2{*^}w-W|>Czrp5UbPqFMm``bH2LwbT1v(M$vpH&x~tnyoq=5aSi zxw>_giGlp1KA>0K4J_)VfK?t?9$eog!|T+eannNTk8OsETT$s)#*A}37A>y}aUeas zKcHwBcnE6w=A~7>Wt;PaU=klU&;>`}GtQIfOm&un#}DBAWBVoYbqGg)p3A9@e*=Wg zh+)=3`W;qgrN5%EC85ZBW|a*nQ;eIH%;|w$eE4H4n0Yvm5SMv|E2xdv9%v%o=;sVR zd<&$$s>;d}*=+@kG3Z=rvnaJ^gfg>TnGNne}pky;q zoITfZv=TFNZ&JOe|Kl67O2me5M#br@)49}^WX>Q$w2;S}TfZ}H~pNN3_Xa!UtVLZ*%v#2o?cn?SW2zT~zmr>`sx0{yy71a#jGp}Y#}Fx+H@mTys0LMc(2S_z zn&;JvL1zX;UOmGlia}*=K(0!=$Ki=qi{vX>6|qZP+w%L zGdZroi)s~pcBjSi+|rR_rpD@vNIgcnd`Tcn6$fF{vv6C^oKq}g1SjMrS-C|Ol+r^= zQd-zgq5!g=6=XhB9}>MieGM_MDc=Rv6%9fNq8>YV6qPbgz*@Tn#jZkHsxwottjukt z`%XHF4;cUGqi?#M)niXQaVpbO?JIDYhOhUklfG*{3IMOuy$?-yyyN2v)De23GDt@w z_)sZ#=t8I)$A#`|HgX{ZA}@d)%Yzrta7TEoDt*J;TY{KY2wAG(_<6qfg->y@FbQej zB=9KNTqV>vN;8u7PzT}=)haTq=x{qR=I~L!VE}*;FE5dk9!`Q1L>bA6KVJjNHhCQ+13K@1P#>ZA@EM{MnUX}IyiZ{!;7mBg91Jj(b4F|h7tT4 z1V(H_UWcB5U03;tTg*(x0_#LaG#t250H?qt^*Pd98{lH1pVQ-BK}}CQpY2gTTS;&C zCg;1@jLev>*gF?h(sjWCr-5lILj@&|)3~o4#KUAu2o%r-At`e^%jZ=4lO%o+ic}NI zWKQQG$6%loWgBadWMVq60bCW4LMAM&@x|+tHWZD75iKu9C7+6C4I6R+y?<5W2Nc~h zz}db!K;5pQe`+<+fJ!7|jRF+;=8eMA?%O--3>dg{gcwY9{#bfgh6iO9Pcnvw6_Q^6o6 zQmH7{x5{^ydnCj`7N<^_lSI$9U4lc~`CeC?5;tj+=oLDNb`&w<0qX@6EOaghKC7~j zazw$zG*!~2?L8K(x};j&c}E9D2`GVtq4{}%4mRW$wJL+h!i}J>U%#~%AlW%yUU4Zz z31CRPToGyx;G{ogT)~a*J3Nepmdkg>_QMUZdLJqyqqq&)RFoKO>!zmdE&}=!|6GT5 zm5CHtUgszWQ@5B_2LVji+v{`-b!BB`=+_jC6lME7WHJ^h!abLci5ZhyIe-2yS%DUJ z%v?Y>Nr!AaClGm-`;i-?=o;h*>`|)&{EKjOsU2?;JM3wW^A^{OITbyK(CT&L^~d^r z)lA2zuCiMLDZEZ`9UD?SkbH*f)wl52{Z}0-*C0XX&_6ISB9|GL(1Jtf;`G2rgwyWc zkCqk=uB+R>eOWMC90{{ z758EB%tmDLNhwO{B`8_{nbmvkT0ZeYo{JS1 zKw)rF$L?C0n3H~ei8d8@_h}-`U&iO<*sR6Ji+M2wj$h3$Pq;-`_op|w*LPFpV`#^_ zWBJfOlqLu0E)?O5$1Af-Dzf^ek-x?CUW#?V@LG8UJKa#h<-PfW12pz@5Q!mH(h1&;=b zKXwNTb^jGxjn!OuC$o(3oqUTNu`ihW>?G literal 0 HcmV?d00001 diff --git a/packages/addons/service/softcam/oscam/meta b/packages/addons/service/softcam/oscam/meta new file mode 100644 index 0000000000..8c64ef0c96 --- /dev/null +++ b/packages/addons/service/softcam/oscam/meta @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="oscam" +PKG_VERSION="5377" +PKG_REV="1" +PKG_ARCH="any" +PKG_LICENSE="GPL" +PKG_SITE="http://streamboard.gmc.to/wiki/index.php/OSCam/en" +#PKG_URL="$OPENELEC_SRC/${PKG_NAME}-${PKG_VERSION}.tar.bz2" +PKG_URL="http://gujs.openelec.tv/${PKG_NAME}-${PKG_VERSION}.tar.bz2" +PKG_DEPENDS="libiconv avahi openssl" +PKG_BUILD_DEPENDS="toolchain libiconv avahi openssl" +PKG_PRIORITY="optional" +PKG_SECTION="service/softcam" +PKG_SHORTDESC="oscam: OSCam is Open Source Conditional Access Modul." +PKG_LONGDESC="OSCam is Open Source Conditional Access Modul." + +PKG_IS_ADDON="yes" +PKG_ADDON_TYPE="xbmc.service" + +PKG_AUTORECONF="no" diff --git a/packages/addons/service/softcam/oscam/source/bin/oscam.service b/packages/addons/service/softcam/oscam/source/bin/oscam.service new file mode 100755 index 0000000000..609aa0b893 --- /dev/null +++ b/packages/addons/service/softcam/oscam/source/bin/oscam.service @@ -0,0 +1,72 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +#Check if process is already running +if [ ! $(pidof oscam) ]; then + + ADDON_DIR="$HOME/.xbmc/addons/service.softcam.oscam" + ADDON_HOME="$HOME/.xbmc/userdata/addon_data/service.softcam.oscam" + ADDON_LOG_DIR="$ADDON_HOME/log" + + ADDON_CONF_DIR="$ADDON_HOME/config" + ADDON_CONF="$ADDON_CONF_DIR/oscam.conf" + ADDON_CONF_AC="$ADDON_CONF_DIR/oscam.ac" + ADDON_CONF_CERT="$ADDON_CONF_DIR/oscam.cert" + ADDON_CONF_DVBAPI="$ADDON_CONF_DIR/oscam.dvbapi" + ADDON_CONF_GUESS="$ADDON_CONF_DIR/oscam.guess" + ADDON_CONF_IRD="$ADDON_CONF_DIR/oscam.ird" + ADDON_CONF_PROVID="$ADDON_CONF_DIR/oscam.provid" + ADDON_CONF_SERVER="$ADDON_CONF_DIR/oscam.server" + ADDON_CONF_SERVICES="$ADDON_CONF_DIR/oscam.services" + ADDON_CONF_SRVID="$ADDON_CONF_DIR/oscam.srvid" + ADDON_CONF_TIERS="$ADDON_CONF_DIR/oscam.tiers" + ADDON_CONF_USER="$ADDON_CONF_DIR/oscam.user" + + OSCAM_ARG="-c $ADDON_CONF_DIR" + + mkdir -p $ADDON_HOME + mkdir -p $ADDON_CONF_DIR + mkdir -p $ADDON_LOG_DIR + + if [ ! -f "$ADDON_CONF" ]; then + cp $ADDON_DIR/oscam-default.conf $ADDON_CONF + fi + + touch $ADDON_CONF_AC + touch $ADDON_CONF_CERT + touch $ADDON_CONF_DVBAPI + touch $ADDON_CONF_GUESS + touch $ADDON_CONF_IRD + touch $ADDON_CONF_PROVID + touch $ADDON_CONF_SERVER + touch $ADDON_CONF_SERVICES + touch $ADDON_CONF_SRVID + touch $ADDON_CONF_TIERS + touch $ADDON_CONF_USER + +#Restart process if it terminates. + (while true; do + oscam $OSCAM_ARG > /dev/null 2>&1 + sleep 1 + done)& +fi + diff --git a/packages/addons/service/softcam/oscam/source/default.py b/packages/addons/service/softcam/oscam/source/default.py new file mode 100644 index 0000000000..15b9b8159e --- /dev/null +++ b/packages/addons/service/softcam/oscam/source/default.py @@ -0,0 +1,23 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +import xbmc, time, os, subprocess + +os.system("oscam.service") diff --git a/tools/mkpkg/mkpkg_oscam b/tools/mkpkg/mkpkg_oscam new file mode 100755 index 0000000000..5851560e19 --- /dev/null +++ b/tools/mkpkg/mkpkg_oscam @@ -0,0 +1,44 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + + +echo "getting sources..." + svn checkout http://streamboard.gmc.to/svn/oscam/trunk oscam-latest + +echo "getting version..." + cd oscam-latest + SVN_REV=`LANG=C svn info 2>/dev/null | grep Revision: | sed -e 's/.*\: //'` + echo $SVN_REV + cd .. + +echo "copying sources..." + rm -rf oscam-$SVN_REV + cp -R oscam-latest oscam-$SVN_REV + +echo "cleaning sources..." + find oscam-$SVN_REV -name .svn -exec rm -rf {} ";" + +echo "packing sources..." + tar cvjf oscam-$SVN_REV.tar.bz2 oscam-$SVN_REV + +echo "remove temporary sourcedir..." + rm -rf oscam-$SVN_REV From a8c9ac235bb72a8cdb7ea81778c14798b2dd61a1 Mon Sep 17 00:00:00 2001 From: Gujs Date: Tue, 14 Jun 2011 23:40:51 +0200 Subject: [PATCH 05/17] oscam addon: add me to copyright --- packages/addons/service/softcam/oscam/addon | 1 + packages/addons/service/softcam/oscam/build | 1 + packages/addons/service/softcam/oscam/meta | 1 + packages/addons/service/softcam/oscam/source/bin/oscam.service | 1 + packages/addons/service/softcam/oscam/source/default.py | 1 + 5 files changed, 5 insertions(+) diff --git a/packages/addons/service/softcam/oscam/addon b/packages/addons/service/softcam/oscam/addon index 0863220d80..23e6843c7b 100755 --- a/packages/addons/service/softcam/oscam/addon +++ b/packages/addons/service/softcam/oscam/addon @@ -3,6 +3,7 @@ ################################################################################ # This file is part of OpenELEC - http://www.openelec.tv # Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2011-2011 Gregor Fuis (gujs@openelec.tv) # # This Program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/packages/addons/service/softcam/oscam/build b/packages/addons/service/softcam/oscam/build index 70bbd406a0..f7b25c375c 100755 --- a/packages/addons/service/softcam/oscam/build +++ b/packages/addons/service/softcam/oscam/build @@ -3,6 +3,7 @@ ################################################################################ # This file is part of OpenELEC - http://www.openelec.tv # Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2011-2011 Gregor Fuis (gujs@openelec.tv) # # This Program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/packages/addons/service/softcam/oscam/meta b/packages/addons/service/softcam/oscam/meta index 8c64ef0c96..d21bde4621 100644 --- a/packages/addons/service/softcam/oscam/meta +++ b/packages/addons/service/softcam/oscam/meta @@ -1,6 +1,7 @@ ################################################################################ # This file is part of OpenELEC - http://www.openelec.tv # Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2011-2011 Gregor Fuis (gujs@openelec.tv) # # This Program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/packages/addons/service/softcam/oscam/source/bin/oscam.service b/packages/addons/service/softcam/oscam/source/bin/oscam.service index 609aa0b893..a3aac8992e 100755 --- a/packages/addons/service/softcam/oscam/source/bin/oscam.service +++ b/packages/addons/service/softcam/oscam/source/bin/oscam.service @@ -3,6 +3,7 @@ ################################################################################ # This file is part of OpenELEC - http://www.openelec.tv # Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2011-2011 Gregor Fuis (gujs@openelec.tv) # # This Program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/packages/addons/service/softcam/oscam/source/default.py b/packages/addons/service/softcam/oscam/source/default.py index 15b9b8159e..5ce0c51314 100644 --- a/packages/addons/service/softcam/oscam/source/default.py +++ b/packages/addons/service/softcam/oscam/source/default.py @@ -1,6 +1,7 @@ ################################################################################ # This file is part of OpenELEC - http://www.openelec.tv # Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2011-2011 Gregor Fuis (gujs@openelec.tv) # # This Program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by From 0a5b7c686808f1dc60b29da9ef6251dd82367007 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Wed, 15 Jun 2011 00:08:51 +0200 Subject: [PATCH 06/17] xf86-video-nvidia: update to xf86-video-nvidia-275.09.07 Signed-off-by: Stephan Raue --- packages/x11/driver/xf86-video-nvidia/meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x11/driver/xf86-video-nvidia/meta b/packages/x11/driver/xf86-video-nvidia/meta index 65c8a53dce..aed65025bf 100644 --- a/packages/x11/driver/xf86-video-nvidia/meta +++ b/packages/x11/driver/xf86-video-nvidia/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xf86-video-nvidia" -PKG_VERSION="275.09.04" +PKG_VERSION="275.09.07" PKG_REV="1" PKG_ARCH="i386 x86_64" PKG_LICENSE="nonfree" From bbffc89bf4a49ac8554312df57babeddfa088ad9 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Wed, 15 Jun 2011 12:45:02 +0200 Subject: [PATCH 07/17] linux: add patch to add Realtek RTL2832U DVB-USB support Signed-off-by: Stephan Raue --- .../058-add_rtl2832u_dvb-usb_driver.txt | 15 + ...-058-add_rtl2832u_dvb-usb_driver-0.1.patch | 66731 ++++++++++++++++ projects/ATV/linux/linux.i386.conf | 2 +- projects/Fusion/linux/linux.i386.conf | 2 +- projects/Generic/linux/linux.i386.conf | 1 + projects/ION/linux/linux.i386.conf | 2 +- projects/ION/linux/linux.x86_64.conf | 2 +- projects/Intel/linux/linux.i386.conf | 1 + projects/Intel/linux/linux.x86_64.conf | 1 + 9 files changed, 66753 insertions(+), 4 deletions(-) create mode 100644 packages/linux/patches/058-add_rtl2832u_dvb-usb_driver.txt create mode 100644 packages/linux/patches/linux-2.6.39.1-058-add_rtl2832u_dvb-usb_driver-0.1.patch diff --git a/packages/linux/patches/058-add_rtl2832u_dvb-usb_driver.txt b/packages/linux/patches/058-add_rtl2832u_dvb-usb_driver.txt new file mode 100644 index 0000000000..cd74409c5d --- /dev/null +++ b/packages/linux/patches/058-add_rtl2832u_dvb-usb_driver.txt @@ -0,0 +1,15 @@ +driver (rtl2832u_v2.0.1.tar.gz) incl. patches taken from: +- http://www.mail-archive.com/linux-media@vger.kernel.org/msg25032.html + - http://goo.gl/CnJJu + - http://goo.gl/NF9eB + +other links: +- http://ubuntuforums.org/showthread.php?t=1678094&page=4 + +see also: +- http://openelec.tv/forum/27-hardware-support/7149-tv-tuner-notonlytv-dvb-t-usb-deluxe-lv5tdeluxe +- http://wiki.zeratul.org/doku.php?id=linux:v4l:realtek:start (source of incl. driver?) +- http://ubuntuforums.org/showpost.php?s=a4812315c36edc2587115bbc15c7ee79&p=10807315&postcount=39 +- http://ubuntuforums.org/showpost.php?s=a4812315c36edc2587115bbc15c7ee79&p=10935546&postcount=40 +- https://build.opensuse.org/package/files?package=dvb-usb-rtl2832u&project=home%3Ajvroosmalen%3Abranches%3Ahome%3Apolyconvex + diff --git a/packages/linux/patches/linux-2.6.39.1-058-add_rtl2832u_dvb-usb_driver-0.1.patch b/packages/linux/patches/linux-2.6.39.1-058-add_rtl2832u_dvb-usb_driver-0.1.patch new file mode 100644 index 0000000000..ffb97f2ae9 --- /dev/null +++ b/packages/linux/patches/linux-2.6.39.1-058-add_rtl2832u_dvb-usb_driver-0.1.patch @@ -0,0 +1,66731 @@ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2832.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2832.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2832.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2832.c 2010-10-12 19:35:16.000000000 +0200 +@@ -0,0 +1,2872 @@ ++/** ++ ++@file ++ ++@brief RTL2832 demod module definition ++ ++One can manipulate RTL2832 demod through RTL2832 module. ++RTL2832 module is derived from DVB-T demod module. ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 demod module builder ++ ++Use BuildRtl2832Module() to build RTL2832 module, set all module function pointers with the corresponding ++functions, and initialize module private variables. ++ ++ ++@param [in] ppDemod Pointer to RTL2832 demod module pointer ++@param [in] pDvbtDemodModuleMemory Pointer to an allocated DVB-T demod module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr RTL2832 I2C device address ++@param [in] CrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] TsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] AppMode RTL2832 application mode for setting ++@param [in] UpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] IsFunc1Enabled RTL2832 Function 1 enabling status for setting ++ ++ ++@note ++ -# One should call BuildRtl2832Module() to build RTL2832 module before using it. ++ ++*/ ++void ++BuildRtl2832Module( ++ DVBT_DEMOD_MODULE **ppDemod, ++ DVBT_DEMOD_MODULE *pDvbtDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int AppMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set demod module pointer, ++ *ppDemod = pDvbtDemodModuleMemory; ++ ++ // Get demod module. ++ pDemod = *ppDemod; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pDemod->pBaseInterface = pBaseInterfaceModuleMemory; ++ pDemod->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Set demod type. ++ pDemod->DemodType = DVBT_DEMOD_TYPE_RTL2832; ++ ++ // Set demod I2C device address. ++ pDemod->DeviceAddr = DeviceAddr; ++ ++ // Set demod crystal frequency in Hz. ++ pDemod->CrystalFreqHz = CrystalFreqHz; ++ ++ // Set demod TS interface mode. ++ pDemod->TsInterfaceMode = TsInterfaceMode; ++ ++ ++ // Initialize demod parameter setting status ++ pDemod->IsBandwidthModeSet = NO; ++ pDemod->IsIfFreqHzSet = NO; ++ pDemod->IsSpectrumModeSet = NO; ++ ++ ++ // Initialize demod register table. ++ rtl2832_InitRegTable(pDemod); ++ ++ ++ // Build I2C birdge module. ++ rtl2832_BuildI2cBridgeModule(pDemod); ++ ++ ++ // Set demod module I2C function pointers with default functions. ++ pDemod->SetRegPage = dvbt_demod_default_SetRegPage; ++ pDemod->SetRegBytes = dvbt_demod_default_SetRegBytes; ++ pDemod->GetRegBytes = dvbt_demod_default_GetRegBytes; ++ pDemod->SetRegMaskBits = dvbt_demod_default_SetRegMaskBits; ++ pDemod->GetRegMaskBits = dvbt_demod_default_GetRegMaskBits; ++ pDemod->SetRegBits = dvbt_demod_default_SetRegBits; ++ pDemod->GetRegBits = dvbt_demod_default_GetRegBits; ++ pDemod->SetRegBitsWithPage = dvbt_demod_default_SetRegBitsWithPage; ++ pDemod->GetRegBitsWithPage = dvbt_demod_default_GetRegBitsWithPage; ++ ++ ++ // Set demod module manipulating function pointers with default functions. ++ pDemod->GetDemodType = dvbt_demod_default_GetDemodType; ++ pDemod->GetDeviceAddr = dvbt_demod_default_GetDeviceAddr; ++ pDemod->GetCrystalFreqHz = dvbt_demod_default_GetCrystalFreqHz; ++ ++ pDemod->GetBandwidthMode = dvbt_demod_default_GetBandwidthMode; ++ pDemod->GetIfFreqHz = dvbt_demod_default_GetIfFreqHz; ++ pDemod->GetSpectrumMode = dvbt_demod_default_GetSpectrumMode; ++ ++ ++ // Set demod module manipulating function pointers with particular functions. ++ pDemod->IsConnectedToI2c = rtl2832_IsConnectedToI2c; ++ pDemod->SoftwareReset = rtl2832_SoftwareReset; ++ pDemod->Initialize = rtl2832_Initialize; ++ pDemod->SetBandwidthMode = rtl2832_SetBandwidthMode; ++ pDemod->SetIfFreqHz = rtl2832_SetIfFreqHz; ++ pDemod->SetSpectrumMode = rtl2832_SetSpectrumMode; ++ ++ pDemod->IsTpsLocked = rtl2832_IsTpsLocked; ++ pDemod->IsSignalLocked = rtl2832_IsSignalLocked; ++ ++ pDemod->GetSignalStrength = rtl2832_GetSignalStrength; ++ pDemod->GetSignalQuality = rtl2832_GetSignalQuality; ++ ++ pDemod->GetBer = rtl2832_GetBer; ++ pDemod->GetSnrDb = rtl2832_GetSnrDb; ++ ++ pDemod->GetRfAgc = rtl2832_GetRfAgc; ++ pDemod->GetIfAgc = rtl2832_GetIfAgc; ++ pDemod->GetDiAgc = rtl2832_GetDiAgc; ++ ++ pDemod->GetTrOffsetPpm = rtl2832_GetTrOffsetPpm; ++ pDemod->GetCrOffsetHz = rtl2832_GetCrOffsetHz; ++ ++ pDemod->GetConstellation = rtl2832_GetConstellation; ++ pDemod->GetHierarchy = rtl2832_GetHierarchy; ++ pDemod->GetCodeRateLp = rtl2832_GetCodeRateLp; ++ pDemod->GetCodeRateHp = rtl2832_GetCodeRateHp; ++ pDemod->GetGuardInterval = rtl2832_GetGuardInterval; ++ pDemod->GetFftMode = rtl2832_GetFftMode; ++ ++ pDemod->UpdateFunction = rtl2832_UpdateFunction; ++ pDemod->ResetFunction = rtl2832_ResetFunction; ++ ++ ++ // Initialize demod extra module variables. ++ pExtra->AppMode = AppMode; ++ ++ ++ // Initialize demod Function 1 variables. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL; ++ ++ pExtra->IsFunc1Enabled = IsFunc1Enabled; ++ ++ pExtra->Func1WaitTimeMax = DivideWithCeiling(RTL2832_FUNC1_WAIT_TIME_MS, UpdateFuncRefPeriodMs); ++ pExtra->Func1GettingTimeMax = DivideWithCeiling(RTL2832_FUNC1_GETTING_TIME_MS, UpdateFuncRefPeriodMs); ++ pExtra->Func1GettingNumEachTime = DivideWithCeiling(RTL2832_FUNC1_GETTING_NUM_MIN, pExtra->Func1GettingTimeMax + 1); ++ ++ pExtra->Func1QamBak = 0xff; ++ pExtra->Func1HierBak = 0xff; ++ pExtra->Func1LpCrBak = 0xff; ++ pExtra->Func1HpCrBak = 0xff; ++ pExtra->Func1GiBak = 0xff; ++ pExtra->Func1FftBak = 0xff; ++ ++ ++ // Set demod extra module function pointers. ++ pExtra->GetAppMode = rtl2832_GetAppMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C ++ ++*/ ++void ++rtl2832_IsConnectedToI2c( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char Nothing; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send read command. ++ // Note: The number of reading bytes must be greater than 0. ++ if(pBaseInterface->I2cRead(pBaseInterface, pDemod->DeviceAddr, &Nothing, LEN_1_BYTE) == FUNCTION_ERROR) ++ goto error_status_i2c_read; ++ ++ ++ // Set I2cConnectionStatus with YES. ++ *pAnswer = YES; ++ ++ ++ return; ++ ++ ++error_status_i2c_read: ++ ++ // Set I2cConnectionStatus with NO. ++ *pAnswer = NO; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SOFTWARE_RESET ++ ++*/ ++int ++rtl2832_SoftwareReset( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set SOFT_RST with 1. Then, set SOFT_RST with 0. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SOFT_RST, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SOFT_RST, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_Initialize( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue; ++ } ++ INIT_TABLE_ENTRY; ++ ++ // TS interface initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[TS_INTERFACE_MODE_NUM]; ++ } ++ TS_INTERFACE_INIT_TABLE_ENTRY; ++ ++ // Application initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[RTL2832_APPLICATION_MODE_NUM]; ++ } ++ APP_INIT_TABLE_ENTRY; ++ ++ ++ ++ static const INIT_TABLE_ENTRY InitTable[RTL2832_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue ++ {DVBT_AD_EN_REG, 0x1 }, ++ {DVBT_AD_EN_REG1, 0x1 }, ++ {DVBT_RSD_BER_FAIL_VAL, 0x2800 }, ++ {DVBT_MGD_THD0, 0x10 }, ++ {DVBT_MGD_THD1, 0x20 }, ++ {DVBT_MGD_THD2, 0x20 }, ++ {DVBT_MGD_THD3, 0x40 }, ++ {DVBT_MGD_THD4, 0x22 }, ++ {DVBT_MGD_THD5, 0x32 }, ++ {DVBT_MGD_THD6, 0x37 }, ++ {DVBT_MGD_THD7, 0x39 }, ++ {DVBT_EN_BK_TRK, 0x0 }, ++ {DVBT_EN_CACQ_NOTCH, 0x0 }, ++ {DVBT_AD_AV_REF, 0x2a }, ++ {DVBT_REG_PI, 0x6 }, ++ {DVBT_PIP_ON, 0x0 }, ++ {DVBT_CDIV_PH0, 0x8 }, ++ {DVBT_CDIV_PH1, 0x8 }, ++ {DVBT_SCALE1_B92, 0x4 }, ++ {DVBT_SCALE1_B93, 0xb0 }, ++ {DVBT_SCALE1_BA7, 0x78 }, ++ {DVBT_SCALE1_BA9, 0x28 }, ++ {DVBT_SCALE1_BAA, 0x59 }, ++ {DVBT_SCALE1_BAB, 0x83 }, ++ {DVBT_SCALE1_BAC, 0xd4 }, ++ {DVBT_SCALE1_BB0, 0x65 }, ++ {DVBT_SCALE1_BB1, 0x43 }, ++ {DVBT_KB_P1, 0x1 }, ++ {DVBT_KB_P2, 0x4 }, ++ {DVBT_KB_P3, 0x7 }, ++ {DVBT_K1_CR_STEP12, 0xa }, ++ {DVBT_REG_GPE, 0x1 }, ++ }; ++ ++ static const TS_INTERFACE_INIT_TABLE_ENTRY TsInterfaceInitTable[RTL2832_TS_INTERFACE_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Parallel, Serial} ++ {DVBT_SERIAL, {0x0, 0x1}}, ++ {DVBT_CDIV_PH0, {0x9, 0x1}}, ++ {DVBT_CDIV_PH1, {0x9, 0x2}}, ++ {DVBT_MPEG_IO_OPT_2_2, {0x0, 0x0}}, ++ {DVBT_MPEG_IO_OPT_1_0, {0x0, 0x1}}, ++ }; ++ ++ static const APP_INIT_TABLE_ENTRY AppInitTable[RTL2832_APP_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Dongle, STB} ++ {DVBT_TRK_KS_P2, {0x4, 0x4}}, ++ {DVBT_TRK_KS_I2, {0x7, 0x7}}, ++ {DVBT_TR_THD_SET2, {0x6, 0x6}}, ++ {DVBT_TRK_KC_I2, {0x5, 0x6}}, ++ {DVBT_CR_THD_SET2, {0x1, 0x1}}, ++ }; ++ ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ int i; ++ ++ int TsInterfaceMode; ++ int AppMode; ++ ++ ++ ++ // Get base interface and demod extra module. ++ pBaseInterface = pDemod->pBaseInterface; ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ // Get TS interface mode. ++ TsInterfaceMode = pDemod->TsInterfaceMode; ++ ++ // Get application mode. ++ pExtra->GetAppMode(pDemod, &AppMode); ++ ++ ++ // Initialize demod registers according to the initializing table. ++ for(i = 0; i < RTL2832_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->SetRegBitsWithPage(pDemod, InitTable[i].RegBitName, InitTable[i].WritingValue) ++ != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Initialize demod registers according to the TS interface initializing table. ++ for(i = 0; i < RTL2832_TS_INTERFACE_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->SetRegBitsWithPage(pDemod, TsInterfaceInitTable[i].RegBitName, ++ TsInterfaceInitTable[i].WritingValue[TsInterfaceMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Initialize demod registers according to the application initializing table. ++ for(i = 0; i < RTL2832_APP_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->SetRegBitsWithPage(pDemod, AppInitTable[i].RegBitName, ++ AppInitTable[i].WritingValue[AppMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_BANDWIDTH_MODE ++ ++*/ ++int ++rtl2832_SetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int BandwidthMode ++ ) ++{ ++ static const unsigned char HlpfxTable[DVBT_BANDWIDTH_MODE_NUM][RTL2832_H_LPF_X_LEN] = ++ { ++ // H_LPF_X writing value for 6 MHz bandwidth ++ { ++ 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f, ++ 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2, ++ 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67, ++ 0x19, 0xe0, ++ }, ++ ++ // H_LPF_X writing value for 7 MHz bandwidth ++ { ++ 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf, ++ 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30, ++ 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22, ++ 0x19, 0x10, ++ }, ++ ++ // H_LPF_X writing value for 8 MHz bandwidth ++ { ++ 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf, ++ 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7, ++ 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8, ++ 0x19, 0xe0, ++ }, ++ }; ++ ++ ++ unsigned long CrystalFreqHz; ++ ++ long ConstWithBandwidthMode; ++ ++ MPI MpiCrystalFreqHz; ++ MPI MpiConst, MpiVar0, MpiVar1, MpiNone; ++ ++ unsigned long RsampRatio; ++ ++ long CfreqOffRatioInt; ++ unsigned long CfreqOffRatioBinary; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Set H_LPF_X registers with HlpfxTable according to BandwidthMode. ++ if(pDemod->SetRegPage(pDemod, RTL2832_H_LPF_X_PAGE) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBytes(pDemod, RTL2832_H_LPF_X_ADDR, HlpfxTable[BandwidthMode], RTL2832_H_LPF_X_LEN) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Determine constant value with bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: ConstWithBandwidthMode = 48000000; break; ++ case DVBT_BANDWIDTH_7MHZ: ConstWithBandwidthMode = 56000000; break; ++ case DVBT_BANDWIDTH_8MHZ: ConstWithBandwidthMode = 64000000; break; ++ } ++ ++ ++ // Calculate RSAMP_RATIO value. ++ // Note: RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22) / ConstWithBandwidthMode) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiVar1, ConstWithBandwidthMode); ++ MpiSetValue(&MpiConst, 7); ++ ++ MpiMul(&MpiVar0, MpiCrystalFreqHz, MpiConst); ++ MpiLeftShift(&MpiVar0, MpiVar0, 22); ++ MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, (long *)&RsampRatio); ++ ++ ++ // Set RSAMP_RATIO with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_RSAMP_RATIO, RsampRatio) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Calculate CFREQ_OFF_RATIO value. ++ // Note: CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20) / (CrystalFreqHz * 7)) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiVar0, ConstWithBandwidthMode); ++ MpiSetValue(&MpiConst, 7); ++ ++ MpiLeftShift(&MpiVar0, MpiVar0, 20); ++ MpiMul(&MpiVar1, MpiCrystalFreqHz, MpiConst); ++ MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, &CfreqOffRatioInt); ++ CfreqOffRatioInt = - CfreqOffRatioInt; ++ ++ CfreqOffRatioBinary = SignedIntToBin(CfreqOffRatioInt, RTL2832_CFREQ_OFF_RATIO_BIT_NUM); ++ ++ ++ // Set CFREQ_OFF_RATIO with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CFREQ_OFF_RATIO, CfreqOffRatioBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ ++ // Set demod bandwidth mode parameter. ++ pDemod->BandwidthMode = BandwidthMode; ++ pDemod->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_IF_FREQ_HZ ++ ++*/ ++int ++rtl2832_SetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ) ++{ ++ unsigned long CrystalFreqHz; ++ ++ unsigned long EnBbin; ++ ++ MPI MpiCrystalFreqHz, MpiVar, MpiNone; ++ ++ long PsetIffreqInt; ++ unsigned long PsetIffreqBinary; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Determine and set EN_BBIN value. ++ EnBbin = (IfFreqHz == IF_FREQ_0HZ) ? 0x1 : 0x0; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_EN_BBIN, EnBbin) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Calculate PSET_IFFREQ value. ++ // Note: PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22) / CrystalFreqHz) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ ++ MpiSetValue(&MpiVar, (IfFreqHz % CrystalFreqHz)); ++ MpiLeftShift(&MpiVar, MpiVar, RTL2832_PSET_IFFREQ_BIT_NUM); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiCrystalFreqHz); ++ ++ MpiGetValue(MpiVar, &PsetIffreqInt); ++ PsetIffreqInt = - PsetIffreqInt; ++ ++ PsetIffreqBinary = SignedIntToBin(PsetIffreqInt, RTL2832_PSET_IFFREQ_BIT_NUM); ++ ++ ++ // Set PSET_IFFREQ with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_PSET_IFFREQ, PsetIffreqBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod IF frequnecy parameter. ++ pDemod->IfFreqHz = IfFreqHz; ++ pDemod->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_SPECTRUM_MODE ++ ++*/ ++int ++rtl2832_SetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ) ++{ ++ unsigned long SpecInv; ++ ++ ++ ++ // Determine SpecInv according to spectrum mode. ++ switch(SpectrumMode) ++ { ++ default: ++ case SPECTRUM_NORMAL: SpecInv = 0; break; ++ case SPECTRUM_INVERSE: SpecInv = 1; break; ++ } ++ ++ ++ // Set SPEC_INV with SpecInv. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SPEC_INV, SpecInv) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod spectrum mode parameter. ++ pDemod->SpectrumMode = SpectrumMode; ++ pDemod->IsSpectrumModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_IS_TPS_LOCKED ++ ++*/ ++int ++rtl2832_IsTpsLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long FsmStage; ++ ++ ++ ++ // Get FSM stage from FSM_STAGE. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine answer according to FSM stage. ++ if(FsmStage > 9) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++rtl2832_IsSignalLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long FsmStage; ++ ++ ++ ++ // Get FSM stage from FSM_STAGE. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine answer according to FSM stage. ++ if(FsmStage == 11) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++rtl2832_GetSignalStrength( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ) ++{ ++ unsigned long FsmStage; ++ unsigned long IfAgc; ++ ++ ++ ++ // Get FSM stage and IF AGC value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine signal strength according to FSM stage and IF AGC value. ++ if(FsmStage < 10) ++ *pSignalStrength = 0; ++ else ++ *pSignalStrength = 55 - IfAgc / 182; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++rtl2832_GetSignalQuality( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ) ++{ ++ unsigned long FsmStage, RsdBerEst; ++ ++ MPI MpiVar; ++ long Var; ++ ++ ++ ++ // Get FSM_STAGE and RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // If demod is not signal-locked, set signal quality with zero. ++ if(FsmStage < 10) ++ { ++ *pSignalQuality = 0; ++ goto success_status_non_signal_lock; ++ } ++ ++ // Determine signal quality according to RSD_BER_EST. ++ // Note: Map RSD_BER_EST value 8192 ~ 128 to 10 ~ 100 ++ // Original formula: SignalQuality = 205 - 15 * log2(RSD_BER_EST) ++ // Adjusted formula: SignalQuality = ((205 << 5) - 15 * (log2(RSD_BER_EST) << 5)) >> 5 ++ // If RSD_BER_EST > 8192, signal quality is 10. ++ // If RSD_BER_EST < 128, signal quality is 100. ++ if(RsdBerEst > 8192) ++ { ++ *pSignalQuality = 10; ++ } ++ else if(RsdBerEst < 128) ++ { ++ *pSignalQuality = 100; ++ } ++ else ++ { ++ MpiSetValue(&MpiVar, RsdBerEst); ++ MpiLog2(&MpiVar, MpiVar, RTL2832_SQ_FRAC_BIT_NUM); ++ MpiGetValue(MpiVar, &Var); ++ ++ *pSignalQuality = ((205 << RTL2832_SQ_FRAC_BIT_NUM) - 15 * Var) >> RTL2832_SQ_FRAC_BIT_NUM; ++ } ++ ++ ++success_status_non_signal_lock: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_BER ++ ++*/ ++int ++rtl2832_GetBer( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++ unsigned long RsdBerEst; ++ ++ ++ ++ // Get RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set BER numerator according to RSD_BER_EST. ++ *pBerNum = RsdBerEst; ++ ++ // Set BER denominator. ++ *pBerDen = RTL2832_BER_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SNR_DB ++ ++*/ ++int ++rtl2832_GetSnrDb( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ unsigned long FsmStage; ++ unsigned long CeEstEvm; ++ int Constellation, Hierarchy; ++ ++ static const long SnrDbNumConst[DVBT_CONSTELLATION_NUM][DVBT_HIERARCHY_NUM] = ++ { ++ {122880, 122880, 122880, 122880, }, ++ {146657, 146657, 156897, 171013, }, ++ {167857, 167857, 173127, 181810, }, ++ }; ++ ++ long Var; ++ MPI MpiCeEstEvm, MpiVar; ++ ++ ++ ++ // Get FSM stage, CE_EST_EVM, constellation, and hierarchy. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_CE_EST_EVM, &CeEstEvm) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetConstellation(pDemod, &Constellation) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetHierarchy(pDemod, &Hierarchy) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ ++ // SNR dB formula ++ // Original formula: SNR_dB = 10 * log10(Norm * pow(2, 11) / CeEstEvm) ++ // Adjusted formula: SNR_dB = (SNR_DB_NUM_CONST - 10 * log2(CeEstEvm) * pow(2, SNR_FRAC_BIT_NUM)) / SNR_DB_DEN ++ // SNR_DB_NUM_CONST = 10 * log2(Norm * pow(2, 11)) * pow(2, SNR_FRAC_BIT_NUM) ++ // SNR_DB_DEN = log2(10) * pow(2, SNR_FRAC_BIT_NUM) ++ // Norm: ++ // None Alpha=1 Alpha=2 Alpha=4 ++ // 4-QAM 2 2 2 2 ++ // 16-QAM 10 10 20 52 ++ // 64-QAM 42 42 60 108 ++ ++ ++ // If FSM stage < 10, set CE_EST_EVM with max value. ++ if(FsmStage < 10) ++ CeEstEvm = RTL2832_CE_EST_EVM_MAX_VALUE; ++ ++ ++ // Calculate SNR dB numerator. ++ MpiSetValue(&MpiCeEstEvm, CeEstEvm); ++ ++ MpiLog2(&MpiVar, MpiCeEstEvm, RTL2832_SNR_FRAC_BIT_NUM); ++ ++ MpiGetValue(MpiVar, &Var); ++ ++ *pSnrDbNum = SnrDbNumConst[Constellation][Hierarchy] - 10 * Var; ++ ++ ++ // Set SNR dB denominator. ++ *pSnrDbDen = RTL2832_SNR_DB_DEN; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_RF_AGC ++ ++*/ ++int ++rtl2832_GetRfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ) ++{ ++ unsigned long Value; ++ ++ ++ ++ // Get RF_AGC_VAL to Value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RF_AGC_VAL, &Value) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Convert Value to signed integer and store the signed integer to RfAgc. ++ *pRfAgc = (int)BinToSignedInt(Value, RTL2832_RF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_IF_AGC ++ ++*/ ++int ++rtl2832_GetIfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ) ++{ ++ unsigned long Value; ++ ++ ++ ++ // Get IF_AGC_VAL to Value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_IF_AGC_VAL, &Value) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Convert Value to signed integer and store the signed integer to IfAgc. ++ *pIfAgc = (int)BinToSignedInt(Value, RTL2832_IF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_DI_AGC ++ ++*/ ++int ++rtl2832_GetDiAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDiAgc ++ ) ++{ ++ unsigned long Value; ++ ++ ++ ++ // Get DAGC_VAL to DiAgc. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_DAGC_VAL, &Value) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ *pDiAgc = (unsigned char)Value; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++rtl2832_GetTrOffsetPpm( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ) ++{ ++ unsigned long SfreqOffBinary; ++ long SfreqOffInt; ++ ++ MPI MpiSfreqOffInt; ++ MPI MpiConst, MpiVar; ++ ++ ++ // Get SfreqOff binary value from SFREQ_OFF register bits. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_SFREQ_OFF, &SfreqOffBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Convert SfreqOff binary value to signed integer. ++ SfreqOffInt = BinToSignedInt(SfreqOffBinary, RTL2832_SFREQ_OFF_BIT_NUM); ++ ++ ++ // Get TR offset in ppm. ++ // Note: Original formula: TrOffsetPpm = (SfreqOffInt * 1000000) / pow(2, 24) ++ // Adjusted formula: TrOffsetPpm = (SfreqOffInt * 1000000) >> 24 ++ MpiSetValue(&MpiSfreqOffInt, SfreqOffInt); ++ MpiSetValue(&MpiConst, 1000000); ++ ++ MpiMul(&MpiVar, MpiSfreqOffInt, MpiConst); ++ MpiRightShift(&MpiVar, MpiVar, 24); ++ ++ MpiGetValue(MpiVar, pTrOffsetPpm); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++rtl2832_GetCrOffsetHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ) ++{ ++ int BandwidthMode; ++ int FftMode; ++ ++ unsigned long CfreqOffBinary; ++ long CfreqOffInt; ++ ++ long ConstWithBandwidthMode, ConstWithFftMode; ++ ++ MPI MpiCfreqOffInt; ++ MPI MpiConstWithBandwidthMode, MpiConstWithFftMode; ++ MPI MpiConst, MpiVar0, MpiVar1, MpiNone; ++ ++ ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_bandwidth_mode; ++ ++ ++ // Get demod FFT mode. ++ if(pDemod->GetFftMode(pDemod, &FftMode) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Get CfreqOff binary value from CFREQ_OFF register bits. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_CFREQ_OFF, &CfreqOffBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Convert CfreqOff binary value to signed integer. ++ CfreqOffInt = BinToSignedInt(CfreqOffBinary, RTL2832_CFREQ_OFF_BIT_NUM); ++ ++ ++ // Determine constant value with bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: ConstWithBandwidthMode = 48000000; break; ++ case DVBT_BANDWIDTH_7MHZ: ConstWithBandwidthMode = 56000000; break; ++ case DVBT_BANDWIDTH_8MHZ: ConstWithBandwidthMode = 64000000; break; ++ } ++ ++ ++ // Determine constant value with FFT mode. ++ switch(FftMode) ++ { ++ default: ++ case DVBT_FFT_MODE_2K: ConstWithFftMode = 2048; break; ++ case DVBT_FFT_MODE_8K: ConstWithFftMode = 8192; break; ++ } ++ ++ ++ // Get Cr offset in Hz. ++ // Note: Original formula: CrOffsetHz = (CfreqOffInt * ConstWithBandwidthMode) / (ConstWithFftMode * 7 * 128) ++ // Adjusted formula: CrOffsetHz = (CfreqOffInt * ConstWithBandwidthMode) / ((ConstWithFftMode * 7) << 7) ++ MpiSetValue(&MpiCfreqOffInt, CfreqOffInt); ++ MpiSetValue(&MpiConstWithBandwidthMode, ConstWithBandwidthMode); ++ MpiSetValue(&MpiConstWithFftMode, ConstWithFftMode); ++ MpiSetValue(&MpiConst, 7); ++ ++ MpiMul(&MpiVar0, MpiCfreqOffInt, MpiConstWithBandwidthMode); ++ MpiMul(&MpiVar1, MpiConstWithFftMode, MpiConst); ++ MpiLeftShift(&MpiVar1, MpiVar1, 7); ++ MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, pCrOffsetHz); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CONSTELLATION ++ ++*/ ++int ++rtl2832_GetConstellation( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConstellation ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS constellation information from RX_CONSTEL. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_CONSTEL, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pConstellation = DVBT_CONSTELLATION_QPSK; break; ++ case 1: *pConstellation = DVBT_CONSTELLATION_16QAM; break; ++ case 2: *pConstellation = DVBT_CONSTELLATION_64QAM; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_HIERARCHY ++ ++*/ ++int ++rtl2832_GetHierarchy( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pHierarchy ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS hierarchy infromation from RX_HIER. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_HIER, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pHierarchy = DVBT_HIERARCHY_NONE; break; ++ case 1: *pHierarchy = DVBT_HIERARCHY_ALPHA_1; break; ++ case 2: *pHierarchy = DVBT_HIERARCHY_ALPHA_2; break; ++ case 3: *pHierarchy = DVBT_HIERARCHY_ALPHA_4; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CODE_RATE_LP ++ ++*/ ++int ++rtl2832_GetCodeRateLp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateLp ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS low-priority code rate infromation from RX_C_RATE_LP. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_C_RATE_LP, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pCodeRateLp = DVBT_CODE_RATE_1_OVER_2; break; ++ case 1: *pCodeRateLp = DVBT_CODE_RATE_2_OVER_3; break; ++ case 2: *pCodeRateLp = DVBT_CODE_RATE_3_OVER_4; break; ++ case 3: *pCodeRateLp = DVBT_CODE_RATE_5_OVER_6; break; ++ case 4: *pCodeRateLp = DVBT_CODE_RATE_7_OVER_8; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CODE_RATE_HP ++ ++*/ ++int ++rtl2832_GetCodeRateHp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateHp ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS high-priority code rate infromation from RX_C_RATE_HP. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_C_RATE_HP, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pCodeRateHp = DVBT_CODE_RATE_1_OVER_2; break; ++ case 1: *pCodeRateHp = DVBT_CODE_RATE_2_OVER_3; break; ++ case 2: *pCodeRateHp = DVBT_CODE_RATE_3_OVER_4; break; ++ case 3: *pCodeRateHp = DVBT_CODE_RATE_5_OVER_6; break; ++ case 4: *pCodeRateHp = DVBT_CODE_RATE_7_OVER_8; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_GUARD_INTERVAL ++ ++*/ ++int ++rtl2832_GetGuardInterval( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pGuardInterval ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS guard interval infromation from GI_IDX. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_GI_IDX, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_32; break; ++ case 1: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_16; break; ++ case 2: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_8; break; ++ case 3: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_4; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_FFT_MODE ++ ++*/ ++int ++rtl2832_GetFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pFftMode ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS FFT mode infromation from FFT_MODE_IDX. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FFT_MODE_IDX, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pFftMode = DVBT_FFT_MODE_2K; break; ++ case 1: *pFftMode = DVBT_FFT_MODE_8K; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_UpdateFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Execute Function 1 according to Function 1 enabling status ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2832_func1_Update(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_RESET_FUNCTION ++ ++*/ ++int ++rtl2832_ResetFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Reset Function 1 settings according to Function 1 enabling status. ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ++ ++*/ ++int ++rtl2832_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C reading command. ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_reading_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_reading_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ++ ++*/ ++int ++rtl2832_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_writing_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_writing_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize RTL2832 register table. ++ ++Use rtl2832_InitRegTable() to initialize RTL2832 register table. ++ ++ ++@param [in] pDemod RTL2832 demod module pointer ++ ++ ++@note ++ -# The rtl2832_InitRegTable() function will be called by BuildRtl2832Module(). ++ ++*/ ++void ++rtl2832_InitRegTable( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const DVBT_PRIMARY_REG_ENTRY PrimaryRegTable[RTL2832_REG_TABLE_LEN] = ++ { ++ // Software reset register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_SOFT_RST, 0x1, 0x1, 2, 2}, ++ ++ // Tuner I2C forwording register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_IIC_REPEAT, 0x1, 0x1, 3, 3}, ++ ++ // Registers for initialization ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_TR_WAIT_MIN_8K, 0x1, 0x88, 11, 2}, ++ {DVBT_RSD_BER_FAIL_VAL, 0x1, 0x8f, 15, 0}, ++ {DVBT_EN_BK_TRK, 0x1, 0xa6, 7, 7}, ++ {DVBT_AD_EN_REG, 0x0, 0x8, 7, 7}, ++ {DVBT_AD_EN_REG1, 0x0, 0x8, 6, 6}, ++ {DVBT_EN_BBIN, 0x1, 0xb1, 0, 0}, ++ {DVBT_MGD_THD0, 0x1, 0x95, 7, 0}, ++ {DVBT_MGD_THD1, 0x1, 0x96, 7, 0}, ++ {DVBT_MGD_THD2, 0x1, 0x97, 7, 0}, ++ {DVBT_MGD_THD3, 0x1, 0x98, 7, 0}, ++ {DVBT_MGD_THD4, 0x1, 0x99, 7, 0}, ++ {DVBT_MGD_THD5, 0x1, 0x9a, 7, 0}, ++ {DVBT_MGD_THD6, 0x1, 0x9b, 7, 0}, ++ {DVBT_MGD_THD7, 0x1, 0x9c, 7, 0}, ++ {DVBT_EN_CACQ_NOTCH, 0x1, 0x61, 4, 4}, ++ {DVBT_AD_AV_REF, 0x0, 0x9, 6, 0}, ++ {DVBT_REG_PI, 0x0, 0xa, 2, 0}, ++ {DVBT_PIP_ON, 0x0, 0x21, 3, 3}, ++ {DVBT_SCALE1_B92, 0x2, 0x92, 7, 0}, ++ {DVBT_SCALE1_B93, 0x2, 0x93, 7, 0}, ++ {DVBT_SCALE1_BA7, 0x2, 0xa7, 7, 0}, ++ {DVBT_SCALE1_BA9, 0x2, 0xa9, 7, 0}, ++ {DVBT_SCALE1_BAA, 0x2, 0xaa, 7, 0}, ++ {DVBT_SCALE1_BAB, 0x2, 0xab, 7, 0}, ++ {DVBT_SCALE1_BAC, 0x2, 0xac, 7, 0}, ++ {DVBT_SCALE1_BB0, 0x2, 0xb0, 7, 0}, ++ {DVBT_SCALE1_BB1, 0x2, 0xb1, 7, 0}, ++ {DVBT_KB_P1, 0x1, 0x64, 3, 1}, ++ {DVBT_KB_P2, 0x1, 0x64, 6, 4}, ++ {DVBT_KB_P3, 0x1, 0x65, 2, 0}, ++ {DVBT_OPT_ADC_IQ, 0x0, 0x6, 5, 4}, ++ {DVBT_AD_AVI, 0x0, 0x9, 1, 0}, ++ {DVBT_AD_AVQ, 0x0, 0x9, 3, 2}, ++ {DVBT_K1_CR_STEP12, 0x2, 0xad, 9, 4}, ++ ++ // Registers for initialization according to mode ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_TRK_KS_P2, 0x1, 0x6f, 2, 0}, ++ {DVBT_TRK_KS_I2, 0x1, 0x70, 5, 3}, ++ {DVBT_TR_THD_SET2, 0x1, 0x72, 3, 0}, ++ {DVBT_TRK_KC_P2, 0x1, 0x73, 5, 3}, ++ {DVBT_TRK_KC_I2, 0x1, 0x75, 2, 0}, ++ {DVBT_CR_THD_SET2, 0x1, 0x76, 7, 6}, ++ ++ // Registers for IF setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_PSET_IFFREQ, 0x1, 0x19, 21, 0}, ++ {DVBT_SPEC_INV, 0x1, 0x15, 0, 0}, ++ ++ // Registers for bandwidth programming ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RSAMP_RATIO, 0x1, 0x9f, 27, 2}, ++ {DVBT_CFREQ_OFF_RATIO, 0x1, 0x9d, 23, 4}, ++ ++ // FSM stage register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_FSM_STAGE, 0x3, 0x51, 6, 3}, ++ ++ // TPS content registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RX_CONSTEL, 0x3, 0x3c, 3, 2}, ++ {DVBT_RX_HIER, 0x3, 0x3c, 6, 4}, ++ {DVBT_RX_C_RATE_LP, 0x3, 0x3d, 2, 0}, ++ {DVBT_RX_C_RATE_HP, 0x3, 0x3d, 5, 3}, ++ {DVBT_GI_IDX, 0x3, 0x51, 1, 0}, ++ {DVBT_FFT_MODE_IDX, 0x3, 0x51, 2, 2}, ++ ++ // Performance measurement registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RSD_BER_EST, 0x3, 0x4e, 15, 0}, ++ {DVBT_CE_EST_EVM, 0x4, 0xc, 15, 0}, ++ ++ // AGC registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RF_AGC_VAL, 0x3, 0x5b, 13, 0}, ++ {DVBT_IF_AGC_VAL, 0x3, 0x59, 13, 0}, ++ {DVBT_DAGC_VAL, 0x3, 0x5, 7, 0}, ++ ++ // TR offset and CR offset registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_SFREQ_OFF, 0x3, 0x18, 13, 0}, ++ {DVBT_CFREQ_OFF, 0x3, 0x5f, 17, 0}, ++ ++ // AGC relative registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_POLAR_RF_AGC, 0x0, 0xe, 1, 1}, ++ {DVBT_POLAR_IF_AGC, 0x0, 0xe, 0, 0}, ++ {DVBT_AAGC_HOLD, 0x1, 0x4, 5, 5}, ++ {DVBT_EN_RF_AGC, 0x1, 0x4, 6, 6}, ++ {DVBT_EN_IF_AGC, 0x1, 0x4, 7, 7}, ++ {DVBT_IF_AGC_MIN, 0x1, 0x8, 7, 0}, ++ {DVBT_IF_AGC_MAX, 0x1, 0x9, 7, 0}, ++ {DVBT_RF_AGC_MIN, 0x1, 0xa, 7, 0}, ++ {DVBT_RF_AGC_MAX, 0x1, 0xb, 7, 0}, ++ {DVBT_IF_AGC_MAN, 0x1, 0xc, 6, 6}, ++ {DVBT_IF_AGC_MAN_VAL, 0x1, 0xc, 13, 0}, ++ {DVBT_RF_AGC_MAN, 0x1, 0xe, 6, 6}, ++ {DVBT_RF_AGC_MAN_VAL, 0x1, 0xe, 13, 0}, ++ {DVBT_DAGC_TRG_VAL, 0x1, 0x12, 7, 0}, ++ {DVBT_AGC_TARG_VAL_0, 0x1, 0x2, 0, 0}, ++ {DVBT_AGC_TARG_VAL_8_1, 0x1, 0x3, 7, 0}, ++ {DVBT_AAGC_LOOP_GAIN, 0x1, 0xc7, 5, 1}, ++ {DVBT_LOOP_GAIN2_3_0, 0x1, 0x4, 4, 1}, ++ {DVBT_LOOP_GAIN2_4, 0x1, 0x5, 7, 7}, ++ {DVBT_LOOP_GAIN3, 0x1, 0xc8, 4, 0}, ++ {DVBT_VTOP1, 0x1, 0x6, 5, 0}, ++ {DVBT_VTOP2, 0x1, 0xc9, 5, 0}, ++ {DVBT_VTOP3, 0x1, 0xca, 5, 0}, ++ {DVBT_KRF1, 0x1, 0xcb, 7, 0}, ++ {DVBT_KRF2, 0x1, 0x7, 7, 0}, ++ {DVBT_KRF3, 0x1, 0xcd, 7, 0}, ++ {DVBT_KRF4, 0x1, 0xce, 7, 0}, ++ {DVBT_EN_GI_PGA, 0x1, 0xe5, 0, 0}, ++ {DVBT_THD_LOCK_UP, 0x1, 0xd9, 8, 0}, ++ {DVBT_THD_LOCK_DW, 0x1, 0xdb, 8, 0}, ++ {DVBT_THD_UP1, 0x1, 0xdd, 7, 0}, ++ {DVBT_THD_DW1, 0x1, 0xde, 7, 0}, ++ {DVBT_INTER_CNT_LEN, 0x1, 0xd8, 3, 0}, ++ {DVBT_GI_PGA_STATE, 0x1, 0xe6, 3, 3}, ++ {DVBT_EN_AGC_PGA, 0x1, 0xd7, 0, 0}, ++ ++ // TS interface registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_CKOUTPAR, 0x1, 0x7b, 5, 5}, ++ {DVBT_CKOUT_PWR, 0x1, 0x7b, 6, 6}, ++ {DVBT_SYNC_DUR, 0x1, 0x7b, 7, 7}, ++ {DVBT_ERR_DUR, 0x1, 0x7c, 0, 0}, ++ {DVBT_SYNC_LVL, 0x1, 0x7c, 1, 1}, ++ {DVBT_ERR_LVL, 0x1, 0x7c, 2, 2}, ++ {DVBT_VAL_LVL, 0x1, 0x7c, 3, 3}, ++ {DVBT_SERIAL, 0x1, 0x7c, 4, 4}, ++ {DVBT_SER_LSB, 0x1, 0x7c, 5, 5}, ++ {DVBT_CDIV_PH0, 0x1, 0x7d, 3, 0}, ++ {DVBT_CDIV_PH1, 0x1, 0x7d, 7, 4}, ++ {DVBT_MPEG_IO_OPT_2_2, 0x0, 0x6, 7, 7}, ++ {DVBT_MPEG_IO_OPT_1_0, 0x0, 0x7, 7, 6}, ++ {DVBT_CKOUTPAR_PIP, 0x0, 0xb7, 4, 4}, ++ {DVBT_CKOUT_PWR_PIP, 0x0, 0xb7, 3, 3}, ++ {DVBT_SYNC_LVL_PIP, 0x0, 0xb7, 2, 2}, ++ {DVBT_ERR_LVL_PIP, 0x0, 0xb7, 1, 1}, ++ {DVBT_VAL_LVL_PIP, 0x0, 0xb7, 0, 0}, ++ {DVBT_CKOUTPAR_PID, 0x0, 0xb9, 4, 4}, ++ {DVBT_CKOUT_PWR_PID, 0x0, 0xb9, 3, 3}, ++ {DVBT_SYNC_LVL_PID, 0x0, 0xb9, 2, 2}, ++ {DVBT_ERR_LVL_PID, 0x0, 0xb9, 1, 1}, ++ {DVBT_VAL_LVL_PID, 0x0, 0xb9, 0, 0}, ++ ++ // FSM state-holding register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_SM_PASS, 0x1, 0x93, 11, 0}, ++ ++ // AD7 registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_AD7_SETTING, 0x0, 0x11, 15, 0}, ++ {DVBT_RSSI_R, 0x3, 0x1, 6, 0}, ++ ++ // ACI detection registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_ACI_DET_IND, 0x3, 0x12, 0, 0}, ++ ++ // Clock output registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_REG_MON, 0x0, 0xd, 1, 0}, ++ {DVBT_REG_MONSEL, 0x0, 0xd, 2, 2}, ++ {DVBT_REG_GPE, 0x0, 0xd, 7, 7}, ++ {DVBT_REG_GPO, 0x0, 0x10, 0, 0}, ++ {DVBT_REG_4MSEL, 0x0, 0x13, 0, 0}, ++ }; ++ ++ ++ int i; ++ int RegBitName; ++ ++ ++ ++ // Initialize register table according to primary register table. ++ // Note: 1. Register table rows are sorted by register bit name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < DVBT_REG_TABLE_LEN_MAX; i++) ++ pDemod->RegTable[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2832_REG_TABLE_LEN; i++) ++ { ++ RegBitName = PrimaryRegTable[i].RegBitName; ++ ++ pDemod->RegTable[RegBitName].IsAvailable = YES; ++ pDemod->RegTable[RegBitName].PageNo = PrimaryRegTable[i].PageNo; ++ pDemod->RegTable[RegBitName].RegStartAddr = PrimaryRegTable[i].RegStartAddr; ++ pDemod->RegTable[RegBitName].Msb = PrimaryRegTable[i].Msb; ++ pDemod->RegTable[RegBitName].Lsb = PrimaryRegTable[i].Lsb; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set I2C bridge module demod arguments. ++ ++RTL2832 builder will use rtl2832_BuildI2cBridgeModule() to set I2C bridge module demod arguments. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2832Module() ++ ++*/ ++void ++rtl2832_BuildI2cBridgeModule( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ ++ // Get I2C bridge module. ++ pI2cBridge = pDemod->pI2cBridge; ++ ++ // Set I2C bridge module demod arguments. ++ pI2cBridge->pPrivateData = (void *)pDemod; ++ pI2cBridge->ForwardI2cReadingCmd = rtl2832_ForwardI2cReadingCmd; ++ pI2cBridge->ForwardI2cWritingCmd = rtl2832_ForwardI2cWritingCmd; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/* ++ ++@see RTL2832_FP_GET_APP_MODE ++ ++*/ ++void ++rtl2832_GetAppMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Get demod type from demod module. ++ *pAppMode = pExtra->AppMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset Function 1 variables and registers. ++ ++One can use rtl2832_func1_Reset() to reset Function 1 variables and registers. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset Function 1 variables and registers successfully. ++@retval FUNCTION_ERROR Reset Function 1 variables and registers unsuccessfully. ++ ++ ++@note ++ -# Need to execute Function 1 reset function when change tuner RF frequency or demod parameters. ++ -# Function 1 update flow also employs Function 1 reset function. ++ ++*/ ++int ++rtl2832_func1_Reset( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ // Reset demod Function 1 variables. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL; ++ pExtra->Func1WaitTime = 0; ++ pExtra->Func1GettingTime = 0; ++ pExtra->Func1RsdBerEstSumNormal = 0; ++ pExtra->Func1RsdBerEstSumConfig1 = 0; ++ pExtra->Func1RsdBerEstSumConfig2 = 0; ++ pExtra->Func1RsdBerEstSumConfig3 = 0; ++ ++ ++ // Reset demod Function 1 registers. ++ if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update demod registers with Function 1. ++ ++One can use rtl2832_func1_Update() to update demod registers with Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod registers with Function 1 successfully. ++@retval FUNCTION_ERROR Update demod registers with Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_Update( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ int Answer; ++ int MinWeightedBerConfigMode; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Run FSM. ++ switch(pExtra->Func1State) ++ { ++ case RTL2832_FUNC1_STATE_NORMAL: ++ ++ // Ask if criterion is matched. ++ if(rtl2832_func1_IsCriterionMatched(pDemod, &Answer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Answer == YES) ++ { ++ // Accumulate RSD_BER_EST for normal case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumNormal) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_NORMAL_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_NORMAL_GET_BER: ++ ++ // Accumulate RSD_BER_EST for normal case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumNormal) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_NORMAL_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Set common registers for configuration 1, 2, and 3 case. ++ if(rtl2832_func1_SetCommonReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set registers with FFT mode for configuration 1, 2, and 3 case. ++ if(rtl2832_func1_SetRegWithFftMode(pDemod, pExtra->Func1FftBak) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set registers for configuration 1 case. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_1) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_1_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_1_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_1_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_1_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Accumulate RSD_BER_EST for configuration 1 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig1) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_1_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_1_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_1_GET_BER: ++ ++ // Accumulate RSD_BER_EST for configuration 1 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig1) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_1_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Set registers for configuration 2 case. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_2_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_2_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_2_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_2_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Accumulate RSD_BER_EST for configuration 2 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_2_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_2_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_2_GET_BER: ++ ++ // Accumulate RSD_BER_EST for configuration 2 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_2_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Set registers for configuration 3 case. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_3) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_3_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_3_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_3_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Accumulate RSD_BER_EST for configuration 3 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig3) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_3_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_3_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_3_GET_BER: ++ ++ // Accumulate RSD_BER_EST for configuration 3 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig3) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Determine minimum-weighted-BER configuration mode. ++ rtl2832_func1_GetMinWeightedBerConfigMode(pDemod, &MinWeightedBerConfigMode); ++ ++ // Set registers with minimum-weighted-BER configuration mode. ++ switch(MinWeightedBerConfigMode) ++ { ++ case RTL2832_FUNC1_CONFIG_NORMAL: ++ ++ // Reset registers for normal configuration. ++ if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_CONFIG_1: ++ case RTL2832_FUNC1_CONFIG_2: ++ case RTL2832_FUNC1_CONFIG_3: ++ ++ // Set registers for minimum-weighted-BER configuration. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, MinWeightedBerConfigMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ default: ++ ++ // Get error configuration mode, reset registers. ++ if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_DETERMINED_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_DETERMINED_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_DETERMINED_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Go to RTL2832_FUNC1_STATE_DETERMINED state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_DETERMINED; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_DETERMINED: ++ ++ // Ask if criterion is matched. ++ if(rtl2832_func1_IsCriterionMatched(pDemod, &Answer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Answer == NO) ++ { ++ // Reset FSM. ++ // Note: rtl2832_func1_Reset() will set FSM state with RTL2832_FUNC1_STATE_NORMAL. ++ if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ break; ++ ++ ++ default: ++ ++ // Get error state, reset FSM. ++ // Note: rtl2832_func1_Reset() will set FSM state with RTL2832_FUNC1_STATE_NORMAL. ++ if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Ask if criterion is matched for Function 1. ++ ++One can use rtl2832_func1_IsCriterionMatched() to ask if criterion is matched for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Ask if criterion is matched for Function 1 successfully. ++@retval FUNCTION_ERROR Ask if criterion is matched for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_IsCriterionMatched( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ unsigned long FsmStage; ++ ++ int Qam; ++ int Hier; ++ int LpCr; ++ int HpCr; ++ int Gi; ++ int Fft; ++ ++ unsigned long Reg0, Reg1; ++ ++ int BandwidthMode; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Get FSM_STAGE. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Get QAM. ++ if(pDemod->GetConstellation(pDemod, &Qam) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get hierarchy. ++ if(pDemod->GetHierarchy(pDemod, &Hier) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get low-priority code rate. ++ if(pDemod->GetCodeRateLp(pDemod, &LpCr) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get high-priority code rate. ++ if(pDemod->GetCodeRateHp(pDemod, &HpCr) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get guard interval. ++ if(pDemod->GetGuardInterval(pDemod, &Gi) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get FFT mode. ++ if(pDemod->GetFftMode(pDemod, &Fft) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Get REG_0 and REG_1. ++ if(pDemod->SetRegPage(pDemod, 0x3) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->GetRegMaskBits(pDemod, 0x22, 0, 0, &Reg0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->GetRegMaskBits(pDemod, 0x1a, 15, 3, &Reg1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Get bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Determine criterion answer. ++ *pAnswer = ++ (FsmStage == 11) && ++ ++ (Qam == pExtra->Func1QamBak) && ++ (Hier == pExtra->Func1HierBak) && ++ (LpCr == pExtra->Func1LpCrBak) && ++ (HpCr == pExtra->Func1HpCrBak) && ++ (Gi == pExtra->Func1GiBak) && ++ (Fft == pExtra->Func1FftBak) && ++ ++ (Reg0 == 0x1) && ++ ++ ((BandwidthMode == DVBT_BANDWIDTH_8MHZ) && ++ ( ((Fft == DVBT_FFT_MODE_2K) && (Reg1 > 1424) && (Reg1 < 1440)) || ++ ((Fft == DVBT_FFT_MODE_8K) && (Reg1 > 5696) && (Reg1 < 5760)) ) ); ++ ++ ++ // Backup TPS information. ++ pExtra->Func1QamBak = Qam; ++ pExtra->Func1HierBak = Hier; ++ pExtra->Func1LpCrBak = LpCr; ++ pExtra->Func1HpCrBak = HpCr; ++ pExtra->Func1GiBak = Gi; ++ pExtra->Func1FftBak = Fft; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Accumulate RSD_BER_EST value for Function 1. ++ ++One can use rtl2832_func1_AccumulateRsdBerEst() to accumulate RSD_BER_EST for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] pAccumulativeValue Accumulative RSD_BER_EST value ++ ++ ++@retval FUNCTION_SUCCESS Accumulate RSD_BER_EST for Function 1 successfully. ++@retval FUNCTION_ERROR Accumulate RSD_BER_EST for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_AccumulateRsdBerEst( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pAccumulativeValue ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ int i; ++ unsigned long RsdBerEst; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Get RSD_BER_EST with assigned times. ++ for(i = 0; i < pExtra->Func1GettingNumEachTime; i++) ++ { ++ // Get RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Accumulate RSD_BER_EST to accumulative value. ++ *pAccumulativeValue += RsdBerEst; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset registers for Function 1. ++ ++One can use rtl2832_func1_ResetReg() to reset registers for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset registers for Function 1 successfully. ++@retval FUNCTION_ERROR Reset registers for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_ResetReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Reset Function 1 registers. ++ if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x65, 2, 0, 0x7) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x68, 5, 4, 0x3) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 2, 0, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 5, 3, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 2, 0, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 5, 3, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd0, 3, 2, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd1, 14, 0, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd3, 14, 0, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd5, 14, 0, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x1, 0, 0, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb4, 7, 6, 0x3) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd2, 1, 1, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb5, 7, 7, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set common registers for Function 1. ++ ++One can use rtl2832_func1_SetCommonReg() to set common registers for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Set common registers for Function 1 successfully. ++@retval FUNCTION_ERROR Set common registers for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_SetCommonReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set common registers for Function 1. ++ if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x65, 2, 0, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x68, 5, 4, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd2, 1, 1, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb5, 7, 7, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set registers with FFT mode for Function 1. ++ ++One can use rtl2832_func1_SetRegWithConfigMode() to set registers with FFT mode for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] FftMode FFT mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set registers with FFT mode for Function 1 successfully. ++@retval FUNCTION_ERROR Set registers with FFT mode for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_SetRegWithFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int FftMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned long Reg0[DVBT_FFT_MODE_NUM]; ++ unsigned long Reg1[DVBT_FFT_MODE_NUM]; ++ } ++ FFT_REF_ENTRY; ++ ++ ++ ++ static const FFT_REF_ENTRY FftRefTable = ++ { ++ // 2K mode, 8K mode ++ {0x0, 0x1 }, ++ {0x3, 0x0 }, ++ }; ++ ++ ++ ++ // Set registers with FFT mode for Function 1. ++ if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x1, 0, 0, FftRefTable.Reg0[FftMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb4, 7, 6, FftRefTable.Reg1[FftMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set registers with configuration mode for Function 1. ++ ++One can use rtl2832_func1_SetRegWithConfigMode() to set registers with configuration mode for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] ConfigMode Configuration mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set registers with configuration mode for Function 1 successfully. ++@retval FUNCTION_ERROR Set registers with configuration mode for Function 1 unsuccessfully. ++ ++ ++@note ++ -# This function can not set RTL2832_FUNC1_CONFIG_NORMAL configuration mode. ++ ++*/ ++int ++rtl2832_func1_SetRegWithConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int ConfigMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned long Reg0[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg1[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg2[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg3[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg4[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ ++ unsigned long Reg5Ref[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg6Ref[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg7Ref[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ } ++ CONFIG_REF_ENTRY; ++ ++ ++ ++ static const CONFIG_REF_ENTRY ConfigRefTable = ++ { ++ // Config 1, Config 2, Config 3 ++ {0x5, 0x4, 0x5 }, ++ {0x5, 0x4, 0x7 }, ++ {0x5, 0x4, 0x7 }, ++ {0x7, 0x6, 0x5 }, ++ {0x3, 0x3, 0x2 }, ++ ++ {4437, 4437, 4325 }, ++ {6000, 5500, 6500 }, ++ {6552, 5800, 5850 }, ++ }; ++ ++ int BandwidthMode; ++ ++ static const unsigned long Const[DVBT_BANDWIDTH_MODE_NUM] = ++ { ++ // 6Mhz, 7Mhz, 8Mhz ++ 48, 56, 64, ++ }; ++ ++ unsigned long Reg5, Reg6, Reg7; ++ ++ ++ ++ // Get bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Calculate REG_5, REG_6, and REG_7 with bandwidth mode and configuration mode. ++ Reg5 = (ConfigRefTable.Reg5Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]); ++ Reg6 = (ConfigRefTable.Reg6Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]); ++ Reg7 = (ConfigRefTable.Reg7Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]); ++ ++ ++ // Set registers with bandwidth mode and configuration mode. ++ if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 2, 0, ConfigRefTable.Reg0[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 5, 3, ConfigRefTable.Reg1[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 2, 0, ConfigRefTable.Reg2[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 5, 3, ConfigRefTable.Reg3[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd0, 3, 2, ConfigRefTable.Reg4[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd1, 14, 0, Reg5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd3, 14, 0, Reg6) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd5, 14, 0, Reg7) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get minimum-weighted-BER configuration mode for Function 1. ++ ++One can use rtl2832_func1_GetMinWeightedBerConfigMode() to get minimum-weighted-BER configuration mode for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pConfigMode Pointer to an allocated memory for storing configuration mode answer ++ ++ ++@retval FUNCTION_SUCCESS Get minimum-weighted-BER configuration mode for Function 1 successfully. ++@retval FUNCTION_ERROR Get minimum-weighted-BER configuration mode for Function 1 unsuccessfully. ++ ++*/ ++void ++rtl2832_func1_GetMinWeightedBerConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConfigMode ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ unsigned long WeightedBerNormal; ++ unsigned long WeightedBerConfig1; ++ unsigned long WeightedBerConfig2; ++ unsigned long WeightedBerConfig3; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Calculate weighted BER for all configuration mode ++ WeightedBerNormal = pExtra->Func1RsdBerEstSumNormal * 2; ++ WeightedBerConfig1 = pExtra->Func1RsdBerEstSumConfig1; ++ WeightedBerConfig2 = pExtra->Func1RsdBerEstSumConfig2; ++ WeightedBerConfig3 = pExtra->Func1RsdBerEstSumConfig3; ++ ++ ++ // Determine minimum-weighted-BER configuration mode. ++ if(WeightedBerNormal <= WeightedBerConfig1 && ++ WeightedBerNormal <= WeightedBerConfig2 && ++ WeightedBerNormal <= WeightedBerConfig3) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_NORMAL; ++ } ++ else if(WeightedBerConfig1 <= WeightedBerNormal && ++ WeightedBerConfig1 <= WeightedBerConfig2 && ++ WeightedBerConfig1 <= WeightedBerConfig3) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_1; ++ } ++ else if(WeightedBerConfig2 <= WeightedBerNormal && ++ WeightedBerConfig2 <= WeightedBerConfig1 && ++ WeightedBerConfig2 <= WeightedBerConfig3) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_2; ++ } ++ else if(WeightedBerConfig3 <= WeightedBerNormal && ++ WeightedBerConfig3 <= WeightedBerConfig1 && ++ WeightedBerConfig3 <= WeightedBerConfig2) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_3; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2832.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2832.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2832.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2832.h 2010-10-12 19:35:18.000000000 +0200 +@@ -0,0 +1,466 @@ ++#ifndef __DEMOD_RTL2832_H ++#define __DEMOD_RTL2832_H ++ ++/** ++ ++@file ++ ++@brief RTL2832 demod module declaration ++ ++One can manipulate RTL2832 demod through RTL2832 module. ++RTL2832 module is derived from DVB-T demod module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the DVB-T demod example in dvbt_demod_base.h except the listed lines. ++ ++ ++ ++#include "demod_rtl2832.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ ++ ... ++ ++ ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pDemod, ++ &DvbtDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x20, // I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // Application mode is STB. ++ 50, // Update function reference period is 50 millisecond ++ YES // Function 1 enabling status is YES. ++ ); ++ ++ ++ ++ // See the example for other DVB-T demod functions in dvbt_demod_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "dvbt_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Initializing ++#define RTL2832_INIT_TABLE_LEN 32 ++#define RTL2832_TS_INTERFACE_INIT_TABLE_LEN 5 ++#define RTL2832_APP_INIT_TABLE_LEN 5 ++ ++ ++// Bandwidth setting ++#define RTL2832_H_LPF_X_PAGE 1 ++#define RTL2832_H_LPF_X_ADDR 0x1c ++#define RTL2832_H_LPF_X_LEN 32 ++#define RTL2832_RATIO_PAGE 1 ++#define RTL2832_RATIO_ADDR 0x9d ++#define RTL2832_RATIO_LEN 6 ++ ++ ++// Bandwidth setting ++#define RTL2832_CFREQ_OFF_RATIO_BIT_NUM 20 ++ ++ ++// IF frequency setting ++#define RTL2832_PSET_IFFREQ_BIT_NUM 22 ++ ++ ++// Signal quality ++#define RTL2832_SQ_FRAC_BIT_NUM 5 ++ ++ ++// BER ++#define RTL2832_BER_DEN_VALUE 1000000 ++ ++ ++// SNR ++#define RTL2832_CE_EST_EVM_MAX_VALUE 65535 ++#define RTL2832_SNR_FRAC_BIT_NUM 10 ++#define RTL2832_SNR_DB_DEN 3402 ++ ++ ++// AGC ++#define RTL2832_RF_AGC_REG_BIT_NUM 14 ++#define RTL2832_IF_AGC_REG_BIT_NUM 14 ++ ++ ++// TR offset and CR offset ++#define RTL2832_SFREQ_OFF_BIT_NUM 14 ++#define RTL2832_CFREQ_OFF_BIT_NUM 18 ++ ++ ++// Register table length ++#define RTL2832_REG_TABLE_LEN 127 ++ ++ ++// Function 1 ++#define RTL2832_FUNC1_WAIT_TIME_MS 500 ++#define RTL2832_FUNC1_GETTING_TIME_MS 200 ++#define RTL2832_FUNC1_GETTING_NUM_MIN 20 ++ ++ ++ ++/// Demod application modes ++enum RTL2832_APPLICATION_MODE ++{ ++ RTL2832_APPLICATION_DONGLE, ++ RTL2832_APPLICATION_STB, ++}; ++#define RTL2832_APPLICATION_MODE_NUM 2 ++ ++ ++// Function 1 ++enum RTL2832_FUNC1_CONFIG_MODE ++{ ++ RTL2832_FUNC1_CONFIG_1, ++ RTL2832_FUNC1_CONFIG_2, ++ RTL2832_FUNC1_CONFIG_3, ++}; ++#define RTL2832_FUNC1_CONFIG_MODE_NUM 3 ++#define RTL2832_FUNC1_CONFIG_NORMAL -1 ++ ++ ++enum RTL2832_FUNC1_STATE ++{ ++ RTL2832_FUNC1_STATE_NORMAL, ++ RTL2832_FUNC1_STATE_NORMAL_GET_BER, ++ RTL2832_FUNC1_STATE_CONFIG_1_WAIT, ++ RTL2832_FUNC1_STATE_CONFIG_1_GET_BER, ++ RTL2832_FUNC1_STATE_CONFIG_2_WAIT, ++ RTL2832_FUNC1_STATE_CONFIG_2_GET_BER, ++ RTL2832_FUNC1_STATE_CONFIG_3_WAIT, ++ RTL2832_FUNC1_STATE_CONFIG_3_GET_BER, ++ RTL2832_FUNC1_STATE_DETERMINED_WAIT, ++ RTL2832_FUNC1_STATE_DETERMINED, ++}; ++ ++ ++ ++ ++ ++// Demod module builder ++void ++BuildRtl2832Module( ++ DVBT_DEMOD_MODULE **ppDemod, ++ DVBT_DEMOD_MODULE *pDvbtDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int AppMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled ++ ); ++ ++ ++ ++ ++ ++// Manipulating functions ++void ++rtl2832_IsConnectedToI2c( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++); ++ ++int ++rtl2832_SoftwareReset( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_Initialize( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_SetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_SetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++int ++rtl2832_SetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++int ++rtl2832_IsTpsLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2832_IsSignalLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2832_GetSignalStrength( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++rtl2832_GetSignalQuality( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++rtl2832_GetBer( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++rtl2832_GetSnrDb( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++rtl2832_GetRfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++int ++rtl2832_GetIfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++int ++rtl2832_GetDiAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDiAgc ++ ); ++ ++int ++rtl2832_GetTrOffsetPpm( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++int ++rtl2832_GetCrOffsetHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++int ++rtl2832_GetConstellation( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConstellation ++ ); ++ ++int ++rtl2832_GetHierarchy( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pHierarchy ++ ); ++ ++int ++rtl2832_GetCodeRateLp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateLp ++ ); ++ ++int ++rtl2832_GetCodeRateHp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateHp ++ ); ++ ++int ++rtl2832_GetGuardInterval( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pGuardInterval ++ ); ++ ++int ++rtl2832_GetFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pFftMode ++ ); ++ ++int ++rtl2832_UpdateFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_ResetFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C command forwarding functions ++int ++rtl2832_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++rtl2832_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++// Register table initializing ++void ++rtl2832_InitRegTable( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C birdge module builder ++void ++rtl2832_BuildI2cBridgeModule( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// RTL2832 extra functions ++void ++rtl2832_GetAppMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ); ++ ++ ++ ++ ++ ++// RTL2832 dependence ++int ++rtl2832_func1_Reset( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_Update( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_IsCriterionMatched( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2832_func1_AccumulateRsdBerEst( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pAccumulativeValue ++ ); ++ ++int ++rtl2832_func1_ResetReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_SetCommonReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_SetRegWithFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int FftMode ++ ); ++ ++int ++rtl2832_func1_SetRegWithConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int ConfigMode ++ ); ++ ++void ++rtl2832_func1_GetMinWeightedBerConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConfigMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2836.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2836.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2836.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2836.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,2049 @@ ++/** ++ ++@file ++ ++@brief RTL2836 demod module definition ++ ++One can manipulate RTL2836 demod through RTL2836 module. ++RTL2836 module is derived from DTMB demod module. ++ ++*/ ++ ++ ++#include "demod_rtl2836.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2836 demod module builder ++ ++Use BuildRtl2836Module() to build RTL2836 module, set all module function pointers with the corresponding ++functions, and initialize module private variables. ++ ++ ++@param [in] ppDemod Pointer to RTL2836 demod module pointer ++@param [in] pDtmbDemodModuleMemory Pointer to an allocated DTMB demod module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr RTL2836 I2C device address ++@param [in] CrystalFreqHz RTL2836 crystal frequency in Hz ++@param [in] TsInterfaceMode RTL2836 TS interface mode for setting ++@param [in] UpdateFuncRefPeriodMs RTL2836 update function reference period in millisecond ++@param [in] IsFunc1Enabled RTL2836 Function 1 enabling status for setting ++@param [in] IsFunc2Enabled RTL2836 Function 2 enabling status for setting ++ ++ ++@note ++ -# One should call BuildRtl2836Module() to build RTL2836 module before using it. ++ ++*/ ++void ++BuildRtl2836Module( ++ DTMB_DEMOD_MODULE **ppDemod, ++ DTMB_DEMOD_MODULE *pDtmbDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled, ++ int IsFunc2Enabled ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set demod module pointer, ++ *ppDemod = pDtmbDemodModuleMemory; ++ ++ // Get demod module. ++ pDemod = *ppDemod; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pDemod->pBaseInterface = pBaseInterfaceModuleMemory; ++ pDemod->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Set demod type. ++ pDemod->DemodType = DTMB_DEMOD_TYPE_RTL2836; ++ ++ // Set demod I2C device address. ++ pDemod->DeviceAddr = DeviceAddr; ++ ++ // Set demod crystal frequency in Hz. ++ pDemod->CrystalFreqHz = CrystalFreqHz; ++ ++ // Set demod TS interface mode. ++ pDemod->TsInterfaceMode = TsInterfaceMode; ++ ++ ++ // Initialize demod parameter setting status ++ pDemod->IsIfFreqHzSet = NO; ++ pDemod->IsSpectrumModeSet = NO; ++ ++ ++ // Initialize demod register table. ++ rtl2836_InitRegTable(pDemod); ++ ++ ++ // Build I2C birdge module. ++ rtl2836_BuildI2cBridgeModule(pDemod); ++ ++ ++ // Set demod module I2C function pointers with 8-bit address default functions. ++ pDemod->RegAccess.Addr8Bit.SetRegPage = dtmb_demod_addr_8bit_default_SetRegPage; ++ pDemod->RegAccess.Addr8Bit.SetRegBytes = dtmb_demod_addr_8bit_default_SetRegBytes; ++ pDemod->RegAccess.Addr8Bit.GetRegBytes = dtmb_demod_addr_8bit_default_GetRegBytes; ++ pDemod->RegAccess.Addr8Bit.SetRegMaskBits = dtmb_demod_addr_8bit_default_SetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.GetRegMaskBits = dtmb_demod_addr_8bit_default_GetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBits = dtmb_demod_addr_8bit_default_SetRegBits; ++ pDemod->RegAccess.Addr8Bit.GetRegBits = dtmb_demod_addr_8bit_default_GetRegBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage = dtmb_demod_addr_8bit_default_SetRegBitsWithPage; ++ pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage = dtmb_demod_addr_8bit_default_GetRegBitsWithPage; ++ ++ ++ // Set demod module manipulating function pointers with default functions. ++ pDemod->GetDemodType = dtmb_demod_default_GetDemodType; ++ pDemod->GetDeviceAddr = dtmb_demod_default_GetDeviceAddr; ++ pDemod->GetCrystalFreqHz = dtmb_demod_default_GetCrystalFreqHz; ++ ++ pDemod->GetIfFreqHz = dtmb_demod_default_GetIfFreqHz; ++ pDemod->GetSpectrumMode = dtmb_demod_default_GetSpectrumMode; ++ ++ ++ // Set demod module manipulating function pointers with particular functions. ++ pDemod->IsConnectedToI2c = rtl2836_IsConnectedToI2c; ++ pDemod->SoftwareReset = rtl2836_SoftwareReset; ++ pDemod->Initialize = rtl2836_Initialize; ++ pDemod->SetIfFreqHz = rtl2836_SetIfFreqHz; ++ pDemod->SetSpectrumMode = rtl2836_SetSpectrumMode; ++ ++ pDemod->IsSignalLocked = rtl2836_IsSignalLocked; ++ ++ pDemod->GetSignalStrength = rtl2836_GetSignalStrength; ++ pDemod->GetSignalQuality = rtl2836_GetSignalQuality; ++ ++ pDemod->GetBer = rtl2836_GetBer; ++ pDemod->GetPer = rtl2836_GetPer; ++ pDemod->GetSnrDb = rtl2836_GetSnrDb; ++ ++ pDemod->GetRfAgc = rtl2836_GetRfAgc; ++ pDemod->GetIfAgc = rtl2836_GetIfAgc; ++ pDemod->GetDiAgc = rtl2836_GetDiAgc; ++ ++ pDemod->GetTrOffsetPpm = rtl2836_GetTrOffsetPpm; ++ pDemod->GetCrOffsetHz = rtl2836_GetCrOffsetHz; ++ ++ pDemod->GetCarrierMode = rtl2836_GetCarrierMode; ++ pDemod->GetPnMode = rtl2836_GetPnMode; ++ pDemod->GetQamMode = rtl2836_GetQamMode; ++ pDemod->GetCodeRateMode = rtl2836_GetCodeRateMode; ++ pDemod->GetTimeInterleaverMode = rtl2836_GetTimeInterleaverMode; ++ ++ pDemod->UpdateFunction = rtl2836_UpdateFunction; ++ pDemod->ResetFunction = rtl2836_ResetFunction; ++ ++ ++ // Initialize demod Function 1 variables. ++ pExtra->IsFunc1Enabled = IsFunc1Enabled; ++ pExtra->Func1CntThd = DivideWithCeiling(RTL2836_FUNC1_CHECK_TIME_MS, UpdateFuncRefPeriodMs); ++ pExtra->Func1Cnt = 0; ++ ++ // Initialize demod Function 2 variables. ++ pExtra->IsFunc2Enabled = IsFunc2Enabled; ++ pExtra->Func2SignalModePrevious = RTL2836_FUNC2_SIGNAL_NORMAL; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C ++ ++*/ ++void ++rtl2836_IsConnectedToI2c( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long ChipId; ++ ++ ++ ++ // Get CHIP_ID. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_CHIP_ID, &ChipId) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Check chip ID value. ++ if(ChipId != RTL2836_CHIP_ID_VALUE) ++ goto error_status_check_value; ++ ++ ++ // Set I2cConnectionStatus with YES. ++ *pAnswer = YES; ++ ++ ++ return; ++ ++ ++error_status_check_value: ++error_status_get_registers: ++ ++ // Set I2cConnectionStatus with NO. ++ *pAnswer = NO; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SOFTWARE_RESET ++ ++*/ ++int ++rtl2836_SoftwareReset( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set SOFT_RST with 0x0. Then, set SOFT_RST with 0x1. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_SOFT_RST_N, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_SOFT_RST_N, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_INITIALIZE ++ ++*/ ++int ++rtl2836_Initialize( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Initializing table entry only used in Initialize() ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ } ++ INIT_TABLE_ENTRY; ++ ++ // TS interface initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[TS_INTERFACE_MODE_NUM]; ++ } ++ TS_INTERFACE_INIT_TABLE_ENTRY; ++ ++ ++ ++ static const INIT_TABLE_ENTRY InitRegTable[RTL2836_INIT_REG_TABLE_LEN] = ++ { ++ // PageNo, RegStartAddr, Msb, Lsb, WritingValue ++ {0x0, 0x1, 0, 0, 0x1 }, ++ {0x0, 0x2, 4, 4, 0x0 }, ++ {0x0, 0x3, 2, 0, 0x0 }, ++ {0x0, 0xe, 5, 5, 0x1 }, ++ {0x0, 0x11, 3, 3, 0x0 }, ++ {0x0, 0x12, 1, 0, 0x1 }, ++ {0x0, 0x16, 2, 0, 0x3 }, ++ {0x0, 0x19, 7, 0, 0x19 }, ++ {0x0, 0x1b, 7, 0, 0xcc }, ++ {0x0, 0x1f, 7, 0, 0x5 }, ++ {0x0, 0x20, 2, 2, 0x1 }, ++ {0x0, 0x20, 3, 3, 0x0 }, ++ {0x1, 0x3, 7, 0, 0x38 }, ++ {0x1, 0x31, 1, 1, 0x0 }, ++ {0x1, 0x67, 7, 0, 0x30 }, ++ {0x1, 0x68, 7, 0, 0x10 }, ++ {0x1, 0x7f, 3, 2, 0x1 }, ++ {0x1, 0xda, 7, 7, 0x1 }, ++ {0x1, 0xdb, 7, 0, 0x5 }, ++ {0x2, 0x9, 7, 0, 0xa }, ++ {0x2, 0x10, 7, 0, 0x31 }, ++ {0x2, 0x11, 7, 0, 0x31 }, ++ {0x2, 0x1b, 7, 0, 0x1e }, ++ {0x2, 0x1e, 7, 0, 0x3a }, ++ {0x2, 0x1f, 5, 3, 0x3 }, ++ {0x2, 0x21, 7, 0, 0x3f }, ++ {0x2, 0x24, 6, 5, 0x0 }, ++ {0x2, 0x27, 7, 0, 0x17 }, ++ {0x2, 0x31, 7, 0, 0x35 }, ++ {0x2, 0x32, 7, 0, 0x3f }, ++ {0x2, 0x4f, 3, 2, 0x2 }, ++ {0x2, 0x5a, 7, 0, 0x5 }, ++ {0x2, 0x5b, 7, 0, 0x8 }, ++ {0x2, 0x5c, 7, 0, 0x8 }, ++ {0x2, 0x5e, 7, 5, 0x5 }, ++ {0x2, 0x70, 0, 0, 0x0 }, ++ {0x2, 0x77, 0, 0, 0x1 }, ++ {0x2, 0x7a, 7, 0, 0x2f }, ++ {0x2, 0x81, 3, 2, 0x2 }, ++ {0x2, 0x8d, 7, 0, 0x77 }, ++ {0x2, 0x8e, 7, 4, 0x8 }, ++ {0x2, 0x93, 7, 0, 0xff }, ++ {0x2, 0x94, 7, 0, 0x3 }, ++ {0x2, 0x9d, 7, 0, 0xff }, ++ {0x2, 0x9e, 7, 0, 0x3 }, ++ {0x2, 0xa8, 7, 0, 0xff }, ++ {0x2, 0xa9, 7, 0, 0x3 }, ++ {0x2, 0xa3, 2, 2, 0x1 }, ++ {0x3, 0x1, 7, 0, 0x0 }, ++ {0x3, 0x4, 7, 0, 0x20 }, ++ {0x3, 0x9, 7, 0, 0x10 }, ++ {0x3, 0x14, 7, 0, 0xe4 }, ++ {0x3, 0x15, 7, 0, 0x62 }, ++ {0x3, 0x16, 7, 0, 0x8c }, ++ {0x3, 0x17, 7, 0, 0x11 }, ++ {0x3, 0x1b, 7, 0, 0x40 }, ++ {0x3, 0x1c, 7, 0, 0x14 }, ++ {0x3, 0x23, 7, 0, 0x40 }, ++ {0x3, 0x24, 7, 0, 0xd6 }, ++ {0x3, 0x2b, 7, 0, 0x60 }, ++ {0x3, 0x2c, 7, 0, 0x16 }, ++ {0x3, 0x33, 7, 0, 0x40 }, ++ {0x3, 0x3b, 7, 0, 0x44 }, ++ {0x3, 0x43, 7, 0, 0x41 }, ++ {0x3, 0x4b, 7, 0, 0x40 }, ++ {0x3, 0x53, 7, 0, 0x4a }, ++ {0x3, 0x58, 7, 0, 0x1c }, ++ {0x3, 0x5b, 7, 0, 0x5a }, ++ {0x3, 0x5f, 7, 0, 0xe0 }, ++ {0x4, 0x2, 7, 0, 0x7 }, ++ {0x4, 0x3, 5, 0, 0x9 }, ++ {0x4, 0x4, 5, 0, 0xb }, ++ {0x4, 0x5, 5, 0, 0xd }, ++ {0x4, 0x7, 2, 1, 0x3 }, ++ {0x4, 0x7, 4, 3, 0x3 }, ++ {0x4, 0xe, 4, 0, 0x18 }, ++ {0x4, 0x10, 4, 0, 0x1c }, ++ {0x4, 0x12, 4, 0, 0x1c }, ++ {0x4, 0x2f, 7, 0, 0x0 }, ++ {0x4, 0x30, 7, 0, 0x20 }, ++ {0x4, 0x31, 7, 0, 0x40 }, ++ {0x4, 0x3e, 0, 0, 0x0 }, ++ {0x4, 0x3e, 1, 1, 0x1 }, ++ {0x4, 0x3e, 5, 2, 0x0 }, ++ {0x4, 0x3f, 5, 0, 0x10 }, ++ {0x4, 0x4a, 0, 0, 0x1 }, ++ }; ++ ++ static const TS_INTERFACE_INIT_TABLE_ENTRY TsInterfaceInitTable[RTL2836_TS_INTERFACE_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Parallel, Serial} ++ {DTMB_SERIAL, {0x0, 0x1}}, ++ {DTMB_CDIV_PH0, {0xf, 0x1}}, ++ {DTMB_CDIV_PH1, {0xf, 0x1}}, ++ }; ++ ++ int i; ++ ++ int TsInterfaceMode; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ ++ ++ // Get TS interface mode. ++ TsInterfaceMode = pDemod->TsInterfaceMode; ++ ++ // Initialize demod registers according to the initializing table. ++ for(i = 0; i < RTL2836_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register initializing entry. ++ PageNo = InitRegTable[i].PageNo; ++ RegStartAddr = InitRegTable[i].RegStartAddr; ++ Msb = InitRegTable[i].Msb; ++ Lsb = InitRegTable[i].Lsb; ++ WritingValue = InitRegTable[i].WritingValue; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ // Initialize demod registers according to the TS interface initializing table. ++ for(i = 0; i < RTL2836_TS_INTERFACE_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, TsInterfaceInitTable[i].RegBitName, ++ TsInterfaceInitTable[i].WritingValue[TsInterfaceMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_IF_FREQ_HZ ++ ++*/ ++int ++rtl2836_SetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ) ++{ ++ ++ unsigned long BbinEn, EnDcr; ++ ++ unsigned long IfFreqHzAdj; ++ ++ MPI MpiVar, MpiNone, MpiConst; ++ ++ long IffreqInt; ++ unsigned long IffreqBinary; ++ ++ ++ ++ // Determine and set BBIN_EN and EN_DCR value. ++ BbinEn = (IfFreqHz == IF_FREQ_0HZ) ? 0x1 : 0x0; ++ EnDcr = (IfFreqHz == IF_FREQ_0HZ) ? 0x1 : 0x0; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_BBIN_EN, BbinEn) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_EN_DCR, EnDcr) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Calculate IFFREQ value. ++ // Note: Case 1: IfFreqHz < 24000000, IfFreqHzAdj = IfFreqHz; ++ // Case 2: IfFreqHz >= 24000000, IfFreqHzAdj = 48000000 - IfFreqHz; ++ // IFFREQ = - round( IfFreqHzAdj * pow(2, 10) / 48000000 ) ++ // = - floor( (IfFreqHzAdj * pow(2, 10) + 24000000) / 48000000 ) ++ // RTL2836_ADC_FREQ_HZ = 48 MHz ++ // IFFREQ_BIT_NUM = 10 ++ IfFreqHzAdj = (IfFreqHz < (RTL2836_ADC_FREQ_HZ / 2)) ? IfFreqHz : (RTL2836_ADC_FREQ_HZ - IfFreqHz); ++ ++ MpiSetValue(&MpiVar, IfFreqHzAdj); ++ MpiLeftShift(&MpiVar, MpiVar, RTL2836_IFFREQ_BIT_NUM); ++ ++ MpiSetValue(&MpiConst, (RTL2836_ADC_FREQ_HZ / 2)); ++ MpiAdd(&MpiVar, MpiVar, MpiConst); ++ ++ MpiSetValue(&MpiConst, RTL2836_ADC_FREQ_HZ); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiConst); ++ ++ MpiGetValue(MpiVar, &IffreqInt); ++ IffreqInt = - IffreqInt; ++ ++ IffreqBinary = SignedIntToBin(IffreqInt, RTL2836_IFFREQ_BIT_NUM); ++ ++ ++ // Set IFFREQ with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_IFFREQ, IffreqBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod IF frequnecy parameter. ++ pDemod->IfFreqHz = IfFreqHz; ++ pDemod->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_SPECTRUM_MODE ++ ++*/ ++int ++rtl2836_SetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ) ++{ ++ unsigned long EnSpInv; ++ ++ ++ ++ // Determine SpecInv according to spectrum mode. ++ switch(SpectrumMode) ++ { ++ case SPECTRUM_NORMAL: EnSpInv = 0; break; ++ case SPECTRUM_INVERSE: EnSpInv = 1; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ // Set SPEC_INV with SpecInv. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_EN_SP_INV, EnSpInv) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod spectrum mode parameter. ++ pDemod->SpectrumMode = SpectrumMode; ++ pDemod->IsSpectrumModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++rtl2836_IsSignalLocked( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ long SnrDbNum; ++ long SnrDbDen; ++ long SnrDbInt; ++ ++ unsigned long PerNum; ++ unsigned long PerDen; ++ ++ ++ ++ // Get SNR integer part. ++ if(pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ SnrDbInt = SnrDbNum / SnrDbDen; ++ ++ ++ // Get PER. ++ if(pDemod->GetPer(pDemod, &PerNum, &PerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Determine answer according to SNR and PER. ++ // Note: The criterion is "(0 < SNR_in_Db < 40) && (PER < 1)" ++ if((SnrDbInt > 0) && (SnrDbInt < 40) && (PerNum < PerDen)) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++rtl2836_GetSignalStrength( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ) ++{ ++ int SignalLockStatus; ++ long IfAgc; ++ ++ ++ ++ // Get signal lock status. ++ if(pDemod->IsSignalLocked(pDemod, &SignalLockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Get IF AGC value. ++ if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // If demod is not signal-locked, set signal strength with zero. ++ if(SignalLockStatus != YES) ++ { ++ *pSignalStrength = 0; ++ goto success_status_signal_is_not_locked; ++ } ++ ++ // Determine signal strength according to signal lock status and IF AGC value. ++ // Note: Map IfAgc value 8191 ~ -8192 to 10 ~ 99 ++ // Formula: SignalStrength = 54 - IfAgc / 183 ++ *pSignalStrength = 54 - IfAgc / 183; ++ ++ ++success_status_signal_is_not_locked: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++rtl2836_GetSignalQuality( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ) ++{ ++ int SignalLockStatus; ++ long SnrDbNum, SnrDbDen; ++ ++ ++ ++ // Get signal lock status. ++ if(pDemod->IsSignalLocked(pDemod, &SignalLockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // If demod is not signal-locked, set signal quality with zero. ++ if(SignalLockStatus != YES) ++ { ++ *pSignalQuality = 0; ++ goto success_status_signal_is_not_locked; ++ } ++ ++ // Determine signal quality according to SnrDbNum. ++ // Note: Map SnrDbNum value 12 ~ 100 to 12 ~ 100 ++ // Formula: SignalQuality = SnrDbNum ++ // If SnrDbNum < 12, signal quality is 10. ++ // If SnrDbNum > 100, signal quality is 100. ++ if(SnrDbNum < 12) ++ { ++ *pSignalQuality = 10; ++ } ++ else if(SnrDbNum > 100) ++ { ++ *pSignalQuality = 100; ++ } ++ else ++ { ++ *pSignalQuality = SnrDbNum; ++ } ++ ++ ++success_status_signal_is_not_locked: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_BER ++ ++*/ ++int ++rtl2836_GetBer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++/* ++ unsigned long RsdBerEst; ++ ++ ++ ++ // Get RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DTMB_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set BER numerator according to RSD_BER_EST. ++ *pBerNum = RsdBerEst; ++ ++ // Set BER denominator. ++ *pBerDen = RTL2836_BER_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++*/ ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_PER ++ ++*/ ++int ++rtl2836_GetPer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ unsigned long RoPktErrRate; ++ ++ ++ ++ // Get RO_PKT_ERR_RATE. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_RO_PKT_ERR_RATE, &RoPktErrRate) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set PER numerator according to RO_PKT_ERR_RATE. ++ *pPerNum = RoPktErrRate; ++ ++ // Set PER denominator. ++ *pPerDen = RTL2836_PER_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SNR_DB ++ ++*/ ++int ++rtl2836_GetSnrDb( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ unsigned long EstSnr; ++ ++ ++ ++ // Get EST_SNR. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_EST_SNR, &EstSnr) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set SNR dB numerator according to EST_SNR. ++ *pSnrDbNum = BinToSignedInt(EstSnr, RTL2836_EST_SNR_BIT_NUM); ++ ++ // Set SNR dB denominator. ++ *pSnrDbDen = RTL2836_SNR_DB_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_RF_AGC ++ ++*/ ++int ++rtl2836_GetRfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ) ++{ ++ unsigned long RfAgcVal; ++ ++ ++ ++ // Get RF AGC binary value from RF_AGC_VAL. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_RF_AGC_VAL, &RfAgcVal) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert RF AGC binary value to signed integer. ++ *pRfAgc = (long)BinToSignedInt(RfAgcVal, RTL2836_RF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_IF_AGC ++ ++*/ ++int ++rtl2836_GetIfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ) ++{ ++ unsigned long IfAgcVal; ++ ++ ++ ++ // Get IF AGC binary value from IF_AGC_VAL. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_IF_AGC_VAL, &IfAgcVal) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert IF AGC binary value to signed integer. ++ *pIfAgc = (long)BinToSignedInt(IfAgcVal, RTL2836_IF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_DI_AGC ++ ++*/ ++int ++rtl2836_GetDiAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ) ++{ ++ unsigned long GainOutR; ++ ++ ++ ++ // Get GAIN_OUT_R to DiAgc. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_GAIN_OUT_R, &GainOutR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ *pDiAgc = GainOutR; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++rtl2836_GetTrOffsetPpm( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ) ++{ ++ unsigned long TrOutRBinary; ++ long TrOutRInt; ++ unsigned long SfoaqOutRBinary; ++ long SfoaqOutRInt; ++ ++ MPI MpiVar, MpiNone, MpiConst; ++ ++ ++ // Get TR_OUT_R and SFOAQ_OUT_R binary value. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_TR_OUT_R, &TrOutRBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_SFOAQ_OUT_R, &SfoaqOutRBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert TR_OUT_R and SFOAQ_OUT_R binary value to signed integer. ++ TrOutRInt = BinToSignedInt(TrOutRBinary, RTL2836_TR_OUT_R_BIT_NUM); ++ SfoaqOutRInt = BinToSignedInt(SfoaqOutRBinary, RTL2836_SFOAQ_OUT_R_BIT_NUM); ++ ++ ++ // Get TR offset in ppm. ++ // Note: Original formula: TrOffsetPpm = ((TrOutRInt + SfoaqOutRInt * 8) * 15.12 * pow(10, 6)) / (48 * pow(2, 23)) ++ // Adjusted formula: TrOffsetPpm = ((TrOutRInt + SfoaqOutRInt * 8) * 15120000) / 402653184 ++ MpiSetValue(&MpiVar, (TrOutRInt + SfoaqOutRInt * 8)); ++ ++ MpiSetValue(&MpiConst, 15120000); ++ MpiMul(&MpiVar, MpiVar, MpiConst); ++ ++ MpiSetValue(&MpiConst, 402653184); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiConst); ++ ++ MpiGetValue(MpiVar, pTrOffsetPpm); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++rtl2836_GetCrOffsetHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ) ++{ ++ unsigned long CfoEstRBinary; ++ long CfoEstRInt; ++ ++ MPI MpiVar, MpiConst; ++ ++ ++ // Get CFO_EST_R binary value. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_CFO_EST_R, &CfoEstRBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Convert CFO_EST_R binary value to signed integer. ++ CfoEstRInt = BinToSignedInt(CfoEstRBinary, RTL2836_CFO_EST_R_BIT_NUM); ++ ++ ++ // Get CR offset in Hz. ++ // Note: Original formula: CrOffsetHz = (CfoEstRInt * 15.12 * pow(10, 6)) / pow(2, 26) ++ // Adjusted formula: CrOffsetHz = (CfoEstRInt * 15120000) >> 26 ++ MpiSetValue(&MpiVar, CfoEstRInt); ++ ++ MpiSetValue(&MpiConst, 15120000); ++ MpiMul(&MpiVar, MpiVar, MpiConst); ++ ++ MpiRightShift(&MpiVar, MpiVar, 26); ++ ++ MpiGetValue(MpiVar, pCrOffsetHz); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CARRIER_MODE ++ ++*/ ++int ++rtl2836_GetCarrierMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCarrierMode ++ ) ++{ ++ unsigned long EstCarrier; ++ ++ ++ // Get carrier mode from EST_CARRIER. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_EST_CARRIER, &EstCarrier) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(EstCarrier) ++ { ++ case 0: *pCarrierMode = DTMB_CARRIER_SINGLE; break; ++ case 1: *pCarrierMode = DTMB_CARRIER_MULTI; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_PN_MODE ++ ++*/ ++int ++rtl2836_GetPnMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pPnMode ++ ) ++{ ++ unsigned long RxModeR; ++ ++ ++ // Get PN mode from RX_MODE_R. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_RX_MODE_R, &RxModeR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(RxModeR) ++ { ++ case 0: *pPnMode = DTMB_PN_420; break; ++ case 1: *pPnMode = DTMB_PN_595; break; ++ case 2: *pPnMode = DTMB_PN_945; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_QAM_MODE ++ ++*/ ++int ++rtl2836_GetQamMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ) ++{ ++ unsigned long UseTps; ++ ++ ++ // Get QAM mode from USE_TPS. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_USE_TPS, &UseTps) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(UseTps) ++ { ++ case 0: *pQamMode = DTMB_QAM_UNKNOWN; break; ++ ++ case 2: ++ case 3: *pQamMode = DTMB_QAM_4QAM_NR; break; ++ ++ case 4: ++ case 5: ++ case 6: ++ case 7: ++ case 8: ++ case 9: *pQamMode = DTMB_QAM_4QAM; break; ++ ++ case 10: ++ case 11: ++ case 12: ++ case 13: ++ case 14: ++ case 15: *pQamMode = DTMB_QAM_16QAM; break; ++ ++ case 16: ++ case 17: *pQamMode = DTMB_QAM_32QAM; break; ++ ++ case 18: ++ case 19: ++ case 20: ++ case 21: ++ case 22: ++ case 23: *pQamMode = DTMB_QAM_64QAM; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CODE_RATE_MODE ++ ++*/ ++int ++rtl2836_GetCodeRateMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCodeRateMode ++ ) ++{ ++ unsigned long UseTps; ++ ++ ++ // Get QAM mode from USE_TPS. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_USE_TPS, &UseTps) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(UseTps) ++ { ++ case 0: *pCodeRateMode = DTMB_CODE_RATE_UNKNOWN; break; ++ ++ case 4: ++ case 5: ++ case 10: ++ case 11: ++ case 18: ++ case 19: *pCodeRateMode = DTMB_CODE_RATE_0P4; break; ++ ++ case 6: ++ case 7: ++ case 12: ++ case 13: ++ case 20: ++ case 21: *pCodeRateMode = DTMB_CODE_RATE_0P6; break; ++ ++ case 2: ++ case 3: ++ case 8: ++ case 9: ++ case 14: ++ case 15: ++ case 16: ++ case 17: ++ case 22: ++ case 23: *pCodeRateMode = DTMB_CODE_RATE_0P8; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE ++ ++*/ ++int ++rtl2836_GetTimeInterleaverMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pTimeInterleaverMode ++ ) ++{ ++ unsigned long UseTps; ++ ++ ++ // Get QAM mode from USE_TPS. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_USE_TPS, &UseTps) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(UseTps) ++ { ++ case 0: *pTimeInterleaverMode = DTMB_TIME_INTERLEAVER_UNKNOWN; break; ++ ++ case 2: ++ case 4: ++ case 6: ++ case 8: ++ case 10: ++ case 12: ++ case 14: ++ case 16: ++ case 18: ++ case 20: ++ case 22: *pTimeInterleaverMode = DTMB_TIME_INTERLEAVER_240; break; ++ ++ case 3: ++ case 5: ++ case 7: ++ case 9: ++ case 11: ++ case 13: ++ case 15: ++ case 17: ++ case 19: ++ case 21: ++ case 23: *pTimeInterleaverMode = DTMB_TIME_INTERLEAVER_720; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2836_UpdateFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Execute Function 1 according to Function 1 enabling status ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2836_func1_Update(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ // Execute Function 2 according to Function 2 enabling status ++ if(pExtra->IsFunc2Enabled == YES) ++ { ++ if(rtl2836_func2_Update(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_RESET_FUNCTION ++ ++*/ ++int ++rtl2836_ResetFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Reset Function 1 settings according to Function 1 enabling status. ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2836_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ // Reset Function 2 settings according to Function 2 enabling status. ++ if(pExtra->IsFunc2Enabled == YES) ++ { ++ if(rtl2836_func2_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ++ ++*/ ++int ++rtl2836_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DTMB_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C reading command. ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_reading_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_reading_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ++ ++*/ ++int ++rtl2836_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DTMB_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_writing_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_writing_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize RTL2836 register table. ++ ++Use rtl2836_InitRegTable() to initialize RTL2836 register table. ++ ++ ++@param [in] pDemod RTL2836 demod module pointer ++ ++ ++@note ++ -# The rtl2836_InitRegTable() function will be called by BuildRtl2836Module(). ++ ++*/ ++void ++rtl2836_InitRegTable( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const DTMB_PRIMARY_REG_ENTRY_ADDR_8BIT PrimaryRegTable[RTL2836_REG_TABLE_LEN] = ++ { ++ // Software reset ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_SOFT_RST_N, 0x0, 0x4, 0, 0 }, ++ ++ // Tuner I2C forwording ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_I2CT_EN_CTRL, 0x0, 0x6, 0, 0 }, ++ ++ // Chip ID ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_CHIP_ID, 0x5, 0x10, 15, 0 }, ++ ++ // IF setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_EN_SP_INV, 0x1, 0x31, 1, 1 }, ++ {DTMB_EN_DCR, 0x1, 0x31, 0, 0 }, ++ {DTMB_BBIN_EN, 0x1, 0x6a, 0, 0 }, ++ {DTMB_IFFREQ, 0x1, 0x32, 9, 0 }, ++ ++ // AGC setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_TARGET_VAL, 0x1, 0x3, 7, 0 }, ++ ++ // IF setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_SERIAL, 0x4, 0x50, 7, 7 }, ++ {DTMB_CDIV_PH0, 0x4, 0x51, 4, 0 }, ++ {DTMB_CDIV_PH1, 0x4, 0x52, 4, 0 }, ++ ++ // Signal lock status ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_TPS_LOCK, 0x8, 0x2a, 6, 6 }, ++ {DTMB_PN_PEAK_EXIST, 0x6, 0x53, 0, 0 }, ++ ++ // FSM ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_FSM_STATE_R, 0x6, 0xc0, 4, 0 }, ++ ++ // Performance measurement ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_RO_PKT_ERR_RATE, 0x9, 0x2d, 15, 0 }, ++ {DTMB_EST_SNR, 0x8, 0x3e, 8, 0 }, ++ ++ // AGC ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_GAIN_OUT_R, 0x6, 0xb4, 12, 1 }, ++ {DTMB_RF_AGC_VAL, 0x6, 0x16, 13, 0 }, ++ {DTMB_IF_AGC_VAL, 0x6, 0x14, 13, 0 }, ++ ++ // TR and CR ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_TR_OUT_R, 0x7, 0x7c, 16, 0 }, ++ {DTMB_SFOAQ_OUT_R, 0x7, 0x21, 13, 0 }, ++ {DTMB_CFO_EST_R, 0x6, 0x94, 22, 0 }, ++ ++ // Signal information ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_EST_CARRIER, 0x8, 0x2a, 0, 0 }, ++ {DTMB_RX_MODE_R, 0x7, 0x17, 1, 0 }, ++ {DTMB_USE_TPS, 0x8, 0x2a, 5, 1 }, ++ }; ++ ++ ++ int i; ++ int RegBitName; ++ ++ ++ ++ // Initialize register table according to primary register table. ++ // Note: 1. Register table rows are sorted by register bit name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < DTMB_REG_TABLE_LEN_MAX; i++) ++ pDemod->RegTable.Addr8Bit[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2836_REG_TABLE_LEN; i++) ++ { ++ RegBitName = PrimaryRegTable[i].RegBitName; ++ ++ pDemod->RegTable.Addr8Bit[RegBitName].IsAvailable = YES; ++ pDemod->RegTable.Addr8Bit[RegBitName].PageNo = PrimaryRegTable[i].PageNo; ++ pDemod->RegTable.Addr8Bit[RegBitName].RegStartAddr = PrimaryRegTable[i].RegStartAddr; ++ pDemod->RegTable.Addr8Bit[RegBitName].Msb = PrimaryRegTable[i].Msb; ++ pDemod->RegTable.Addr8Bit[RegBitName].Lsb = PrimaryRegTable[i].Lsb; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set I2C bridge module demod arguments. ++ ++RTL2836 builder will use rtl2836_BuildI2cBridgeModule() to set I2C bridge module demod arguments. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2836Module() ++ ++*/ ++void ++rtl2836_BuildI2cBridgeModule( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ ++ // Get I2C bridge module. ++ pI2cBridge = pDemod->pI2cBridge; ++ ++ // Set I2C bridge module demod arguments. ++ pI2cBridge->pPrivateData = (void *)pDemod; ++ pI2cBridge->ForwardI2cReadingCmd = rtl2836_ForwardI2cReadingCmd; ++ pI2cBridge->ForwardI2cWritingCmd = rtl2836_ForwardI2cWritingCmd; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset Function 1 variables and registers. ++ ++One can use rtl2836_func1_Reset() to reset Function 1 variables and registers. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset Function 1 variables and registers successfully. ++@retval FUNCTION_ERROR Reset Function 1 variables and registers unsuccessfully. ++ ++ ++@note ++ -# Need to execute Function 1 reset function when change tuner RF frequency or demod parameters. ++ -# Function 1 update flow also employs Function 1 reset function. ++ ++*/ ++int ++rtl2836_func1_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ // Reset demod Function 1 variables. ++ pExtra->Func1Cnt = 0; ++ ++ ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update demod registers with Function 1. ++ ++One can use rtl2836_func1_Update() to update demod registers with Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod registers with Function 1 successfully. ++@retval FUNCTION_ERROR Update demod registers with Function 1 unsuccessfully. ++ ++ ++@note ++ -# Recommended update period is 50 ~ 200 ms for Function 1. ++ -# Need to execute Function 1 reset function when change tuner RF frequency or demod parameters. ++ -# Function 1 update flow also employs Function 1 reset function. ++ ++*/ ++int ++rtl2836_func1_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ unsigned long Reg0; ++ unsigned long Reg1; ++ unsigned long PnPeakExist; ++ unsigned long FsmStateR; ++ unsigned long TpsLock; ++ ++ long SnrDbNum; ++ long SnrDbDen; ++ long SnrDbInt; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Update Function 1 counter. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x9) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, 0x1e, 9, 0, &Reg0) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if((Reg0 & 0x3fb) == 0) ++ { ++ pExtra->Func1Cnt += 1; ++ } ++ else ++ { ++ pExtra->Func1Cnt = 0; ++ } ++ ++ ++ // Get PN_PEAK_EXIST and FSM_STATE_R value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x6) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, DTMB_PN_PEAK_EXIST, &PnPeakExist) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, DTMB_FSM_STATE_R, &FsmStateR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Get Reg1 and TPS_LOCK value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x8) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, 0x28, 3, 0, &Reg1) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, DTMB_TPS_LOCK, &TpsLock) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Get SNR integer part. ++ if(pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ SnrDbInt = SnrDbNum / SnrDbDen; ++ ++ ++ // Determine if reset demod by software reset. ++ // Note: Need to reset Function 2 when reset demod. ++ if((pExtra->Func1Cnt > pExtra->Func1CntThd) || ((PnPeakExist == 0) && (FsmStateR > 9)) || ++ ((Reg1 >= 6) && (TpsLock == 0)) || (SnrDbInt == -64)) ++ { ++ pExtra->Func1Cnt = 0; ++ ++ if(pExtra->IsFunc2Enabled == ON) ++ { ++ if(rtl2836_func2_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset Function 2 variables and registers. ++ ++One can use rtl2836_func2_Reset() to reset Function 1 variables and registers. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset Function 2 variables and registers successfully. ++@retval FUNCTION_ERROR Reset Function 2 variables and registers unsuccessfully. ++ ++ ++@note ++ -# Need to execute Function 2 reset function when change tuner RF frequency or demod parameters. ++ -# Function 2 update flow also employs Function 2 reset function. ++ ++*/ ++int ++rtl2836_func2_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ // Reset demod Function 2 variables and registers to signal normal mode. ++ pExtra->Func2SignalModePrevious = RTL2836_FUNC2_SIGNAL_NORMAL; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x15, 7, 0, 0xf) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1e, 6, 0, 0x3a) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1f, 5, 0, 0x19) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x23, 4, 0, 0x1e) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update demod registers with Function 2. ++ ++One can use rtl2836_func2_Update() to update demod registers with Function 2. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod registers with Function 2 successfully. ++@retval FUNCTION_ERROR Update demod registers with Function 2 unsuccessfully. ++ ++ ++@note ++ -# Recommended update period is 50 ~ 200 ms for Function 2. ++ -# Need to execute Function 2 reset function when change tuner RF frequency or demod parameters. ++ -# Function 2 update flow also employs Function 2 reset function. ++ ++*/ ++int ++rtl2836_func2_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ int i; ++ ++ unsigned long TpsLock; ++ unsigned long PnPeakExist; ++ ++ int PnMode; ++ int QamMode; ++ int CodeRateMode; ++ ++ int SignalLockStatus; ++ ++ int SignalMode; ++ ++ ++ ++ // Get base interface and demod extra module. ++ pBaseInterface = pDemod->pBaseInterface; ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Get TPS_LOCK value. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_TPS_LOCK, &TpsLock) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Get PN_PEAK_EXIST value. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_PN_PEAK_EXIST, &PnPeakExist) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Get PN mode. ++ if(pDemod->GetPnMode(pDemod, &PnMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get QAM mode. ++ if(pDemod->GetQamMode(pDemod, &QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get code rate mode. ++ if(pDemod->GetCodeRateMode(pDemod, &CodeRateMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // If TPS is not locked or PN peak doesn't exist, do nothing. ++ if((TpsLock != 0x1) || (PnPeakExist != 0x1)) ++ goto success_status_tps_is_not_locked; ++ ++ // Determine signal mode. ++ if((PnMode == DTMB_PN_945) && (QamMode == DTMB_QAM_64QAM) && (CodeRateMode == DTMB_CODE_RATE_0P6)) ++ { ++ SignalMode = RTL2836_FUNC2_SIGNAL_PARTICULAR; ++ } ++ else ++ { ++ SignalMode = RTL2836_FUNC2_SIGNAL_NORMAL; ++ } ++ ++ // If signal mode is the same as previous one, do nothing. ++ if(SignalMode == pExtra->Func2SignalModePrevious) ++ goto success_status_signal_mode_is_the_same; ++ ++ ++ // Set demod registers according to signal mode ++ switch(SignalMode) ++ { ++ default: ++ case RTL2836_FUNC2_SIGNAL_NORMAL: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x15, 7, 0, 0xf) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1e, 6, 0, 0x3a) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1f, 5, 0, 0x19) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x23, 4, 0, 0x1e) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ ++ ++ case RTL2836_FUNC2_SIGNAL_PARTICULAR: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x15, 7, 0, 0x4) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1e, 6, 0, 0xa) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1f, 5, 0, 0x3f) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x23, 4, 0, 0x1f) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Wait 1000 ms for signal lock check. ++ for(i = 0; i < 10; i++) ++ { ++ // Wait 100 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 100); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, &SignalLockStatus) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(SignalLockStatus == YES) ++ break; ++ } ++ ++ ++ // Update previous signal mode. ++ pExtra->Func2SignalModePrevious = SignalMode; ++ ++ ++success_status_signal_mode_is_the_same: ++success_status_tps_is_not_locked: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2836.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2836.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2836.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2836.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,376 @@ ++#ifndef __DEMOD_RTL2836_H ++#define __DEMOD_RTL2836_H ++ ++/** ++ ++@file ++ ++@brief RTL2836 demod module declaration ++ ++One can manipulate RTL2836 demod through RTL2836 module. ++RTL2836 module is derived from DTMB demod module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the DTMB demod example in dtmb_demod_base.h except the listed lines. ++ ++ ++ ++#include "demod_rtl2836.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ ++ ... ++ ++ ++ ++ // Build RTL2836 demod module. ++ BuildRtl2836Module( ++ &pDemod, ++ &DtmbDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x3e, // I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // Crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // TS interface mode is serial. ++ 50, // Update function reference period is 50 millisecond ++ YES, // Function 1 enabling status is on. ++ YES // Function 2 enabling status is on. ++ ); ++ ++ ++ ++ // See the example for other DTMB demod functions in dtmb_demod_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "dtmb_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Initializing ++#define RTL2836_INIT_REG_TABLE_LEN 86 ++#define RTL2836_TS_INTERFACE_INIT_TABLE_LEN 3 ++ ++ ++// Chip ID ++#define RTL2836_CHIP_ID_VALUE 0x4 ++ ++ ++// IF frequency setting ++#define RTL2836_ADC_FREQ_HZ 48000000 ++#define RTL2836_IFFREQ_BIT_NUM 10 ++ ++ ++// BER ++#define RTL2836_BER_DEN_VALUE 1000000 ++ ++ ++// PER ++#define RTL2836_PER_DEN_VALUE 32768 ++ ++ ++// SNR ++#define RTL2836_EST_SNR_BIT_NUM 9 ++#define RTL2836_SNR_DB_DEN_VALUE 4 ++ ++ ++// AGC ++#define RTL2836_RF_AGC_REG_BIT_NUM 14 ++#define RTL2836_IF_AGC_REG_BIT_NUM 14 ++ ++ ++// TR offset and CR offset ++#define RTL2836_TR_OUT_R_BIT_NUM 17 ++#define RTL2836_SFOAQ_OUT_R_BIT_NUM 14 ++#define RTL2836_CFO_EST_R_BIT_NUM 23 ++ ++ ++// Register table length ++#define RTL2836_REG_TABLE_LEN 25 ++ ++ ++// Function 1 ++#define RTL2836_FUNC1_CHECK_TIME_MS 500 ++ ++ ++// Function 2 ++enum RTL2836_FUNC2_SIGNAL_MODE ++{ ++ RTL2836_FUNC2_SIGNAL_NORMAL, ++ RTL2836_FUNC2_SIGNAL_PARTICULAR, ++}; ++ ++ ++ ++ ++ ++// Demod module builder ++void ++BuildRtl2836Module( ++ DTMB_DEMOD_MODULE **ppDemod, ++ DTMB_DEMOD_MODULE *pDtmbDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled, ++ int IsFunc2Enabled ++ ); ++ ++ ++ ++ ++ ++// Manipulating functions ++void ++rtl2836_IsConnectedToI2c( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++); ++ ++int ++rtl2836_SoftwareReset( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_Initialize( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_SetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++int ++rtl2836_SetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++int ++rtl2836_IsSignalLocked( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2836_GetSignalStrength( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++rtl2836_GetSignalQuality( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++rtl2836_GetBer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++rtl2836_GetPer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++rtl2836_GetSnrDb( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++rtl2836_GetRfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++int ++rtl2836_GetIfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++int ++rtl2836_GetDiAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++int ++rtl2836_GetTrOffsetPpm( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++int ++rtl2836_GetCrOffsetHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++int ++rtl2836_GetCarrierMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCarrierMode ++ ); ++ ++int ++rtl2836_GetPnMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pPnMode ++ ); ++ ++int ++rtl2836_GetQamMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++int ++rtl2836_GetCodeRateMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCodeRateMode ++ ); ++ ++int ++rtl2836_GetTimeInterleaverMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pTimeInterleaverMode ++ ); ++ ++int ++rtl2836_UpdateFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_ResetFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C command forwarding functions ++int ++rtl2836_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++rtl2836_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++// Register table initializing ++void ++rtl2836_InitRegTable( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C birdge module builder ++void ++rtl2836_BuildI2cBridgeModule( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// RTL2836 dependence ++int ++rtl2836_func1_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_func1_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_func2_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_func2_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2840.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2840.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2840.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2840.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,2437 @@ ++/** ++ ++@file ++ ++@brief RTL2840 QAM demod module definition ++ ++One can manipulate RTL2840 QAM demod through RTL2840 module. ++RTL2840 module is derived from QAM demod module. ++ ++*/ ++ ++ ++#include "demod_rtl2840.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2840 demod module builder ++ ++Use BuildRtl2840Module() to build RTL2840 module, set all module function pointers with the corresponding functions, and ++initialize module private variables. ++ ++ ++@param [in] ppDemod Pointer to RTL2840 demod module pointer ++@param [in] pQamDemodModuleMemory Pointer to an allocated QAM demod module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr RTL2840 I2C device address ++@param [in] CrystalFreqHz RTL2840 crystal frequency in Hz ++@param [in] TsInterfaceMode RTL2840 TS interface mode for setting ++@param [in] EnhancementMode RTL2840 enhancement mode for setting ++ ++ ++@note ++ -# One should call BuildRtl2840Module() to build RTL2840 module before using it. ++ ++*/ ++void ++BuildRtl2840Module( ++ QAM_DEMOD_MODULE **ppDemod, ++ QAM_DEMOD_MODULE *pQamDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int EnhancementMode ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ ++ // Set demod module pointer. ++ *ppDemod = pQamDemodModuleMemory; ++ ++ // Get demod module. ++ pDemod = *ppDemod; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pDemod->pBaseInterface = pBaseInterfaceModuleMemory; ++ pDemod->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ ++ // Set demod type. ++ pDemod->DemodType = QAM_DEMOD_TYPE_RTL2840; ++ ++ // Set demod I2C device address. ++ pDemod->DeviceAddr = DeviceAddr; ++ ++ // Set demod crystal frequency in Hz. ++ pDemod->CrystalFreqHz = CrystalFreqHz; ++ ++ // Set demod TS interface mode. ++ pDemod->TsInterfaceMode = TsInterfaceMode; ++ ++ ++ // Initialize demod parameter setting status ++ pDemod->IsQamModeSet = NO; ++ pDemod->IsSymbolRateHzSet = NO; ++ pDemod->IsAlphaModeSet = NO; ++ pDemod->IsIfFreqHzSet = NO; ++ pDemod->IsSpectrumModeSet = NO; ++ ++ ++ // Initialize register tables in demod extra module. ++ rtl2840_InitBaseRegTable(pDemod); ++ rtl2840_InitMonitorRegTable(pDemod); ++ ++ ++ // Build I2C birdge module. ++ rtl2840_BuildI2cBridgeModule(pDemod); ++ ++ ++ // Set demod module I2C function pointers with default functions. ++ pDemod->RegAccess.Addr8Bit.SetRegPage = qam_demod_addr_8bit_default_SetRegPage; ++ pDemod->RegAccess.Addr8Bit.SetRegBytes = qam_demod_addr_8bit_default_SetRegBytes; ++ pDemod->RegAccess.Addr8Bit.GetRegBytes = qam_demod_addr_8bit_default_GetRegBytes; ++ pDemod->RegAccess.Addr8Bit.SetRegMaskBits = qam_demod_addr_8bit_default_SetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.GetRegMaskBits = qam_demod_addr_8bit_default_GetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBits = qam_demod_addr_8bit_default_SetRegBits; ++ pDemod->RegAccess.Addr8Bit.GetRegBits = qam_demod_addr_8bit_default_GetRegBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage = qam_demod_addr_8bit_default_SetRegBitsWithPage; ++ pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage = qam_demod_addr_8bit_default_GetRegBitsWithPage; ++ ++ ++ // Set demod module manipulating function pointers with default functions. ++ pDemod->GetDemodType = qam_demod_default_GetDemodType; ++ pDemod->GetDeviceAddr = qam_demod_default_GetDeviceAddr; ++ pDemod->GetCrystalFreqHz = qam_demod_default_GetCrystalFreqHz; ++ ++ pDemod->GetQamMode = qam_demod_default_GetQamMode; ++ pDemod->GetSymbolRateHz = qam_demod_default_GetSymbolRateHz; ++ pDemod->GetAlphaMode = qam_demod_default_GetAlphaMode; ++ pDemod->GetIfFreqHz = qam_demod_default_GetIfFreqHz; ++ pDemod->GetSpectrumMode = qam_demod_default_GetSpectrumMode; ++ ++ ++ // Set demod module manipulating function pointers with particular functions. ++ // Note: Need to assign manipulating function pointers according to enhancement mode. ++ pDemod->IsConnectedToI2c = rtl2840_IsConnectedToI2c; ++ pDemod->SoftwareReset = rtl2840_SoftwareReset; ++ ++ pDemod->Initialize = rtl2840_Initialize; ++ pDemod->SetSymbolRateHz = rtl2840_SetSymbolRateHz; ++ pDemod->SetAlphaMode = rtl2840_SetAlphaMode; ++ pDemod->SetIfFreqHz = rtl2840_SetIfFreqHz; ++ pDemod->SetSpectrumMode = rtl2840_SetSpectrumMode; ++ ++ pDemod->GetRfAgc = rtl2840_GetRfAgc; ++ pDemod->GetIfAgc = rtl2840_GetIfAgc; ++ pDemod->GetDiAgc = rtl2840_GetDiAgc; ++ pDemod->GetTrOffsetPpm = rtl2840_GetTrOffsetPpm; ++ pDemod->GetCrOffsetHz = rtl2840_GetCrOffsetHz; ++ ++ pDemod->IsAagcLocked = rtl2840_IsAagcLocked; ++ pDemod->IsEqLocked = rtl2840_IsEqLocked; ++ pDemod->IsFrameLocked = rtl2840_IsFrameLocked; ++ ++ pDemod->GetErrorRate = rtl2840_GetErrorRate; ++ pDemod->GetSnrDb = rtl2840_GetSnrDb; ++ ++ pDemod->GetSignalStrength = rtl2840_GetSignalStrength; ++ pDemod->GetSignalQuality = rtl2840_GetSignalQuality; ++ ++ pDemod->UpdateFunction = rtl2840_UpdateFunction; ++ pDemod->ResetFunction = rtl2840_ResetFunction; ++ ++ switch(EnhancementMode) ++ { ++ case QAM_DEMOD_EN_NONE: ++ pDemod->SetQamMode = rtl2840_SetQamMode; ++ break; ++ ++ case QAM_DEMOD_EN_AM_HUM: ++ pDemod->SetQamMode = rtl2840_am_hum_en_SetQamMode; ++ break; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_CONNECTED_TO_I2C ++ ++*/ ++void ++rtl2840_IsConnectedToI2c( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ ++ // Set reading value to zero, and get SYS_VERSION value. ++ // Note: Use GetRegBitsWithPage() to get register bits with page setting. ++ ReadingValue = 0; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_SYS_VERSION, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Compare SYS_VERSION value with RTL2840_SYS_VERSION_VALUE. ++ if(ReadingValue == RTL2840_SYS_VERSION_VALUE) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return; ++ ++ ++error_status_get_demod_registers: ++ ++ *pAnswer = NO; ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SOFTWARE_RESET ++ ++*/ ++int ++rtl2840_SoftwareReset( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set register page number with system page number for software resetting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set and clear SOFT_RESET register bit. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SOFT_RESET, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SOFT_RESET, OFF) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_INITIALIZE ++ ++*/ ++int ++rtl2840_Initialize( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ } ++ INIT_REG_ENTRY; ++ ++ ++ typedef struct ++ { ++ unsigned char SpecReg0Sel; ++ unsigned char SpecReg0ValueTable[RTL2840_SPEC_REG_0_VALUE_TABLE_LEN]; ++ } ++ INIT_SPEC_REG_0_ENTRY; ++ ++ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[TS_INTERFACE_MODE_NUM]; ++ } ++ TS_INTERFACE_INIT_TABLE_ENTRY; ++ ++ ++ ++ static const INIT_REG_ENTRY InitRegTable[RTL2840_INIT_REG_TABLE_LEN] = ++ { ++ // PageNo, RegStartAddr, Msb, Lsb, WritingValue ++ {0, 0x04, 2, 0, 0x5 }, ++ {0, 0x04, 4, 3, 0x0 }, ++ {0, 0x04, 5, 5, 0x1 }, ++ {0, 0x06, 0, 0, 0x0 }, ++ {0, 0x07, 2, 2, 0x0 }, ++ {1, 0x04, 0, 0, 0x0 }, ++ {1, 0x04, 1, 1, 0x0 }, ++ {1, 0x04, 2, 2, 0x0 }, ++ {1, 0x04, 3, 3, 0x0 }, ++ {1, 0x0c, 2, 0, 0x7 }, ++ {1, 0x19, 5, 5, 0x0 }, ++ {1, 0x19, 6, 6, 0x1 }, ++ {1, 0x19, 7, 7, 0x1 }, ++ {1, 0x1a, 0, 0, 0x0 }, ++ {1, 0x1a, 1, 1, 0x1 }, ++ {1, 0x1a, 2, 2, 0x0 }, ++ {1, 0x1a, 3, 3, 0x1 }, ++ {1, 0x1a, 4, 4, 0x0 }, ++ {1, 0x1a, 5, 5, 0x1 }, ++ {1, 0x1a, 6, 6, 0x1 }, ++ {1, 0x1b, 3, 0, 0x7 }, ++ {1, 0x1b, 7, 4, 0xc }, ++ {1, 0x1c, 2, 0, 0x4 }, ++ {1, 0x1c, 5, 3, 0x3 }, ++ {1, 0x1d, 5, 0, 0x7 }, ++ {1, 0x27, 9, 0, 0x6d }, ++ {1, 0x2b, 7, 0, 0x26 }, ++ {1, 0x2c, 7, 0, 0x1e }, ++ {1, 0x2e, 7, 6, 0x3 }, ++ {1, 0x32, 2, 0, 0x7 }, ++ {1, 0x32, 5, 3, 0x0 }, ++ {1, 0x32, 6, 6, 0x1 }, ++ {1, 0x32, 7, 7, 0x0 }, ++ {1, 0x33, 6, 0, 0xf }, ++ {1, 0x33, 7, 7, 0x1 }, ++ {1, 0x39, 7, 0, 0x88 }, ++ {1, 0x3a, 7, 0, 0x36 }, ++ {1, 0x3e, 7, 0, 0x26 }, ++ {1, 0x3f, 7, 0, 0x15 }, ++ {1, 0x4b, 8, 0, 0x166 }, ++ {1, 0x4d, 8, 0, 0x166 }, ++ {2, 0x11, 0, 0, 0x0 }, ++ {2, 0x02, 7, 0, 0x7e }, ++ {2, 0x12, 3, 0, 0x7 }, ++ {2, 0x12, 7, 4, 0x7 }, ++ }; ++ ++ ++ static const INIT_SPEC_REG_0_ENTRY InitSpecReg0Table[RTL2840_INIT_SPEC_REG_0_TABLE_LEN] = ++ { ++ // SpecReg0Sel, {SpecReg0ValueTable } ++ {0, {0x00, 0xd0, 0x49, 0x8e, 0xf2, 0x01, 0x00, 0xc0, 0x62, 0x62, 0x00} }, ++ {1, {0x11, 0x21, 0x89, 0x8e, 0xf2, 0x01, 0x80, 0x8b, 0x62, 0xe2, 0x00} }, ++ {2, {0x22, 0x32, 0x89, 0x8e, 0x72, 0x00, 0xc0, 0x86, 0xe2, 0xe3, 0x00} }, ++ {3, {0x43, 0x44, 0x8b, 0x0e, 0xf2, 0xdd, 0xb5, 0x84, 0xe2, 0xcb, 0x00} }, ++ {4, {0x54, 0x55, 0xcb, 0x1e, 0xf3, 0x4d, 0xb5, 0x84, 0xe2, 0xcb, 0x00} }, ++ {5, {0x65, 0x66, 0xcb, 0x1e, 0xf5, 0x4b, 0xb4, 0x84, 0xe2, 0xcb, 0x00} }, ++ {6, {0x76, 0x77, 0xcb, 0x9e, 0xf7, 0xc7, 0x73, 0x80, 0xe2, 0xcb, 0x00} }, ++ {7, {0x87, 0x88, 0xcb, 0x2e, 0x48, 0x41, 0x72, 0x80, 0xe2, 0xcb, 0x00} }, ++ {8, {0x98, 0x99, 0xcc, 0x3e, 0x48, 0x21, 0x71, 0x80, 0xea, 0xcb, 0x00} }, ++ {11, {0xbb, 0xc8, 0xcb, 0x6e, 0x24, 0x18, 0x73, 0xa0, 0xfa, 0xcf, 0x01} }, ++ {13, {0x1d, 0x1e, 0x4f, 0x8e, 0xf2, 0x01, 0x00, 0x80, 0x62, 0x62, 0x00} }, ++ {14, {0x1e, 0x1f, 0x4f, 0x8e, 0xf2, 0x01, 0x00, 0x80, 0x62, 0x62, 0x00} }, ++ {15, {0x1f, 0x11, 0x4f, 0x8e, 0xf2, 0x01, 0x00, 0x80, 0x62, 0x62, 0x00} }, ++ }; ++ ++ ++ static const TS_INTERFACE_INIT_TABLE_ENTRY TsInterfaceInitTable[RTL2840_TS_INTERFACE_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Parallel, Serial} ++ {QAM_SERIAL, {0x0, 0x1}}, ++ {QAM_CDIV_PH0, {0x7, 0x0}}, ++ {QAM_CDIV_PH1, {0x7, 0x0}}, ++ }; ++ ++ ++ int i; ++ ++ int TsInterfaceMode; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ unsigned char SpecReg0Sel; ++ const unsigned char *pSpecReg0ValueTable; ++ ++ unsigned long QamSpecInitA2Backup; ++ unsigned long RegValue, RegValueComparison; ++ int AreAllValueEqual; ++ ++ ++ ++ // Get TS interface mode. ++ TsInterfaceMode = pDemod->TsInterfaceMode; ++ ++ // Initialize demod with register initializing table. ++ for(i = 0; i < RTL2840_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register initializing entry. ++ PageNo = InitRegTable[i].PageNo; ++ RegStartAddr = InitRegTable[i].RegStartAddr; ++ Msb = InitRegTable[i].Msb; ++ Lsb = InitRegTable[i].Lsb; ++ WritingValue = InitRegTable[i].WritingValue; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set register page number with inner page number for specific register 0 initializing. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Initialize demod with specific register 0 initializing table. ++ for(i = 0; i < RTL2840_INIT_SPEC_REG_0_TABLE_LEN; i++) ++ { ++ // Get all information from each specific register 0 initializing entry. ++ SpecReg0Sel = InitSpecReg0Table[i].SpecReg0Sel; ++ pSpecReg0ValueTable = InitSpecReg0Table[i].SpecReg0ValueTable; ++ ++ // Set specific register 0 selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_SEL, SpecReg0Sel) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 values. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RTL2840_SPEC_REG_0_VAL_START_ADDR, pSpecReg0ValueTable, LEN_11_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Initialize demod registers according to the TS interface initializing table. ++ for(i = 0; i < RTL2840_TS_INTERFACE_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, TsInterfaceInitTable[i].RegBitName, ++ TsInterfaceInitTable[i].WritingValue[TsInterfaceMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Backup SPEC_INIT_A2 value. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A2, &QamSpecInitA2Backup)!= FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Set SPEC_INIT_A2 with 0. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A2, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Get SPEC_MONITER_INIT_0 several times. ++ // If all SPEC_MONITER_INIT_0 getting values are the same, set SPEC_INIT_A1 with 0. ++ // Note: 1. Need to set SPEC_INIT_A2 with 0 when get SPEC_MONITER_INIT_0. ++ // 2. The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_SPEC_MONITER_INIT_0, &RegValueComparison) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ for(i = 0, AreAllValueEqual = YES; i < RTL2840_SPEC_MONITOR_INIT_0_COMPARISON_TIMES; i++) ++ { ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_SPEC_MONITER_INIT_0, &RegValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(RegValue != RegValueComparison) ++ { ++ AreAllValueEqual = NO; ++ ++ break; ++ } ++ } ++ ++ if(AreAllValueEqual == YES) ++ { ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A1, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ // Restore SPEC_INIT_A2 value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A2, QamSpecInitA2Backup) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_QAM_MODE ++ ++*/ ++int ++rtl2840_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue[QAM_QAM_MODE_NUM]; ++ } ++ QAM_MODE_REG_ENTRY; ++ ++ ++ typedef struct ++ { ++ unsigned char SpecReg0Sel; ++ unsigned char SpecReg0ValueTable[QAM_QAM_MODE_NUM][RTL2840_SPEC_REG_0_VALUE_TABLE_LEN]; ++ } ++ QAM_MODE_SPEC_REG_0_ENTRY; ++ ++ ++ ++ static const QAM_MODE_REG_ENTRY QamModeRegTable[RTL2840_QAM_MODE_REG_TABLE_LEN] = ++ { ++ // Reg, WritingValue according to QAM mode ++ // PageNo, StartAddr, Msb, Lsb, {4-Q, 16-Q, 32-Q, 64-Q, 128-Q, 256-Q, 512-Q, 1024-Q} ++ {1, 0x02, 2, 0, {0x7, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }}, ++ {1, 0x05, 7, 0, {0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b }}, ++ {1, 0x2f, 15, 5, {0x37, 0x82, 0xb9, 0x10e, 0x177, 0x21c, 0x2ee, 0x451 }}, ++ {1, 0x31, 5, 0, {0x1, 0x3, 0x4, 0x5, 0x8, 0xa, 0xf, 0x14 }}, ++ {1, 0x2e, 5, 0, {0x2, 0x4, 0x6, 0x8, 0xc, 0x10, 0x18, 0x20 }}, ++ {1, 0x18, 7, 0, {0x0, 0xdb, 0x79, 0x0, 0x8a, 0x0, 0x8c, 0x0 }}, ++ {1, 0x19, 4, 0, {0x14, 0x14, 0xf, 0x14, 0xf, 0x14, 0xf, 0x14 }}, ++ {1, 0x3b, 2, 0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3b, 5, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 4, 3, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3c, 6, 5, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 1, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 3, 2, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3d, 5, 4, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 7, 6, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x40, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x40, 5, 3, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3 }}, ++ {1, 0x41, 2, 0, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4 }}, ++ {1, 0x41, 4, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x41, 6, 5, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 1, 0, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ {1, 0x42, 3, 2, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x42, 5, 4, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 7, 6, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ }; ++ ++ ++ static const QAM_MODE_SPEC_REG_0_ENTRY QamModeSpecReg0Table[RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN] = ++ { ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {9, { {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {10, { {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {12, { {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 4-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 16-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 32-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 64-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 128-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 256-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 512-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, } // 1024-QAM ++ }, ++ }; ++ ++ ++ int i; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ unsigned char SpecReg0Sel; ++ const unsigned char *pSpecReg0ValueTable; ++ ++ ++ ++ // Set demod QAM mode with QAM mode register setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register setting entry according to QAM mode. ++ PageNo = QamModeRegTable[i].PageNo; ++ RegStartAddr = QamModeRegTable[i].RegStartAddr; ++ Msb = QamModeRegTable[i].Msb; ++ Lsb = QamModeRegTable[i].Lsb; ++ WritingValue = QamModeRegTable[i].WritingValue[QamMode]; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set register page number with inner page number for QAM mode specific register 0 setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set demod QAM mode with QAM mode specific register 0 setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN; i++) ++ { ++ // Get all information from each specific register 0 setting entry according to QAM mode. ++ SpecReg0Sel = QamModeSpecReg0Table[i].SpecReg0Sel; ++ pSpecReg0ValueTable = QamModeSpecReg0Table[i].SpecReg0ValueTable[QamMode]; ++ ++ // Set specific register 0 selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_SEL, SpecReg0Sel) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 values. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RTL2840_SPEC_REG_0_VAL_START_ADDR, pSpecReg0ValueTable, LEN_11_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod QAM mode parameter. ++ pDemod->QamMode = QamMode; ++ pDemod->IsQamModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ ++ ++*/ ++int ++rtl2840_SetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long SymbolRateHz ++ ) ++{ ++ typedef struct ++ { ++ unsigned long TrDeciRatioRangeMin; ++ unsigned char SymbolRateReg0; ++ unsigned long SymbolRateValue[RTL2840_SYMBOL_RATE_VALUE_TABLE_LEN]; ++ } ++ SYMBOL_RATE_ENTRY; ++ ++ ++ ++ static const SYMBOL_RATE_ENTRY SymbolRateTable[RTL2840_SYMBOL_RATE_TABLE_LEN] = ++ { ++ // TrDeciRatioRangeMin, SymbolRateReg0, {SymbolRateValue } ++ {0x1a0000, 0x4, {10, 14, 1, 988, 955, 977, 68, 257, 438} }, ++ {0x160000, 0x5, {2, 15, 19, 1017, 967, 950, 12, 208, 420} }, ++ {0x0, 0x6, {1019, 1017, 9, 29, 3, 957, 956, 105, 377} }, ++ }; ++ ++ ++ int i; ++ ++ unsigned long CrystalFreqHz; ++ const SYMBOL_RATE_ENTRY *pSymbolRateEntry; ++ ++ MPI MpiCrystalFreqHz, MpiSymbolRateHz, MpiConst, MpiVar, MpiNone; ++ ++ unsigned long TrDeciRatio; ++ unsigned char SymbolRateReg0; ++ unsigned long SymbolRateValue; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Calculate TR_DECI_RATIO value. ++ // Note: Original formula: TR_DECI_RATIO = round( (CrystalFreqHz * pow(2, 18)) / SymbolRateHz ) ++ // Adjusted formula: TR_DECI_RATIO = floor( ((CrystalFreqHz << 19) / SymbolRateHz + 1) >> 1 ) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiSymbolRateHz, SymbolRateHz); ++ MpiSetValue(&MpiConst, 1); ++ ++ MpiLeftShift(&MpiVar, MpiCrystalFreqHz, 19); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiSymbolRateHz); ++ MpiAdd(&MpiVar, MpiVar, MpiConst); ++ MpiRightShift(&MpiVar, MpiVar, 1); ++ ++ MpiGetValue(MpiVar, (long *)&TrDeciRatio); ++ ++ ++ // Determine symbol rate entry according to TR_DECI_RATIO value and minimum of TR_DECI_RATIO range. ++ for(i = 0; i < RTL2840_SYMBOL_RATE_TABLE_LEN; i++) ++ { ++ if(TrDeciRatio >= SymbolRateTable[i].TrDeciRatioRangeMin) ++ { ++ pSymbolRateEntry = &SymbolRateTable[i]; ++ ++ break; ++ } ++ } ++ ++ ++ // Set register page number with inner page number for symbol rate setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set TR_DECI_RATIO with calculated value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_TR_DECI_RATIO, TrDeciRatio) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set SPEC_SYMBOL_RATE_REG_0 value with determined symbol rate entry. ++ SymbolRateReg0 = pSymbolRateEntry->SymbolRateReg0; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_REG_0, SymbolRateReg0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set symbol rate value with determined symbol rate entry. ++ for(i = 0; i < RTL2840_SYMBOL_RATE_VALUE_TABLE_LEN; i++) ++ { ++ // Get symbol rate value. ++ SymbolRateValue = pSymbolRateEntry->SymbolRateValue[i]; ++ ++ // Set symbol rate register selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_SEL, i) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set symbol rate register value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_VAL, SymbolRateValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set symbol rate register strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod symbol rate parameter. ++ pDemod->SymbolRateHz = SymbolRateHz; ++ pDemod->IsSymbolRateHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_ALPHA_MODE ++ ++*/ ++int ++rtl2840_SetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int AlphaMode ++ ) ++{ ++ static const unsigned long AlphaValueTable[QAM_ALPHA_MODE_NUM][RTL2840_ALPHA_VALUE_TABLE_LEN] = ++ { ++ {258, 94, 156, 517, 6, 1015, 1016, 17, 11, 994, 1011, 51, 15, 926, 1008, 313}, // alpha = 0.12 ++ {258, 31, 28, 3, 6, 1016, 1016, 16, 11, 996, 1010, 50, 16, 927, 1007, 312}, // alpha = 0.13 ++ {131, 257, 27, 2, 8, 1017, 1013, 16, 14, 996, 1008, 50, 18, 927, 1004, 310}, // alpha = 0.15 ++ {0, 195, 30, 30, 6, 1022, 1014, 10, 14, 1002, 1006, 45, 21, 931, 1001, 307}, // alpha = 0.18 ++ {415, 68, 31, 29, 4, 1, 1016, 6, 13, 1006, 1006, 41, 23, 934, 998, 304}, // alpha = 0.20 ++ }; ++ ++ ++ int i; ++ unsigned long AlphaValue; ++ ++ ++ ++ // Set register page number with inner page number for alpha value setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set demod alpha mode with alpha value table. ++ for(i = 0; i < RTL2840_ALPHA_VALUE_TABLE_LEN; i++) ++ { ++ // Get alpha value from alpha value entry according to alpha mode. ++ AlphaValue = AlphaValueTable[AlphaMode][i]; ++ ++ // Set alpha register selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_ALPHA_SEL, i) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set alpha register value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_ALPHA_VAL, AlphaValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set alpha register strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_ALPHA_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod alpha mode parameter. ++ pDemod->AlphaMode = AlphaMode; ++ pDemod->IsAlphaModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_IF_FREQ_HZ ++ ++*/ ++int ++rtl2840_SetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ) ++{ ++ unsigned long CrystalFreqHz; ++ unsigned long DdcFreq; ++ ++ MPI MpiIfFreqHz, MpiCrystalFreqHz, MpiConst, MpiVar, MpiNone; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Calculate DDC_FREQ value. ++ // Note: Original formula: DDC_FREQ = round( (CrystalFreqHz - (IfFreqHz % CrystalFreqHz)) * pow(2, 15) / ++ // CrystalFreqHz ) ++ // Adjusted formula: DDC_FREQ = floor( ( ((CrystalFreqHz - (IfFreqHz % CrystalFreqHz)) << 16) / ++ // CrystalFreqHz + 1 ) >> 1) ++ MpiSetValue(&MpiIfFreqHz, IfFreqHz); ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiConst, 1); ++ ++ MpiSetValue(&MpiVar, CrystalFreqHz - (IfFreqHz % CrystalFreqHz)); ++ MpiLeftShift(&MpiVar, MpiVar, 16); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiCrystalFreqHz); ++ MpiAdd(&MpiVar, MpiVar, MpiConst); ++ MpiRightShift(&MpiVar, MpiVar, 1); ++ ++ MpiGetValue(MpiVar, (long *)&DdcFreq); ++ ++ ++ // Set DDC_FREQ with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_DDC_FREQ, DdcFreq) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set demod IF frequnecy parameter. ++ pDemod->IfFreqHz = IfFreqHz; ++ pDemod->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_SPECTRUM_MODE ++ ++*/ ++int ++rtl2840_SetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ) ++{ ++ static const char SpecInvValueTable[SPECTRUM_MODE_NUM] = ++ { ++ // SpecInv ++ 0, // Normal spectrum ++ 1, // Inverse spectrum ++ }; ++ ++ ++ unsigned long SpecInv; ++ ++ ++ ++ // Get SPEC_INV value from spectrum inverse value table according to spectrum mode. ++ SpecInv = SpecInvValueTable[SpectrumMode]; ++ ++ ++ // Set SPEC_INV with gotten value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INV, SpecInv) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set demod spectrum mode parameter. ++ pDemod->SpectrumMode = SpectrumMode; ++ pDemod->IsSpectrumModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_RF_AGC ++ ++*/ ++int ++rtl2840_GetRfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ) ++{ ++ unsigned long RfAgcBinary; ++ ++ ++ // Get RF AGC binary value from RF_AGC_VALUE monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_RF_AGC_VALUE, &RfAgcBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert RF AGC binary value to signed integer. ++ *pRfAgc = BinToSignedInt(RfAgcBinary, RTL2840_RF_AGC_VALUE_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_IF_AGC ++ ++*/ ++int ++rtl2840_GetIfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ) ++{ ++ unsigned long IfAgcBinary; ++ ++ ++ // Get IF AGC binary value from IF_AGC_VALUE monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_IF_AGC_VALUE, &IfAgcBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert IF AGC binary value to signed integer. ++ *pIfAgc = BinToSignedInt(IfAgcBinary, RTL2840_IF_AGC_VALUE_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_DI_AGC ++ ++*/ ++int ++rtl2840_GetDiAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ) ++{ ++ // Get digital AGC value from DAGC_VALUE monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_DAGC_VALUE, pDiAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++rtl2840_GetTrOffsetPpm( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ) ++{ ++ unsigned long SymbolRateHz; ++ unsigned long CrystalFreqHz; ++ ++ unsigned long TrOffsetBinary; ++ long TrOffsetInt; ++ ++ MPI MpiTrOffsetInt, MpiSymbolRateHz, MpiCrystalFreqHz, MpiVar0, MpiVar1; ++ ++ ++ ++ // Get demod symbol rate in Hz. ++ if(pDemod->GetSymbolRateHz(pDemod, &SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_symbol_rate; ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Get TR offset binary value from TR_OFFSET monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_TR_OFFSET, &TrOffsetBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert TR offset binary value to signed integer. ++ TrOffsetInt = BinToSignedInt(TrOffsetBinary, RTL2840_TR_OFFSET_BIT_NUM); ++ ++ ++ // Get TR offset in ppm. ++ // Note: (TR offset in ppm) = ((TR offset integer) * (symbol rate in Hz) * 1000000) / ++ // ((pow(2, 35) * (crystal frequency in Hz)) ++ // TR offset integer is 31 bit value. ++ MpiSetValue(&MpiTrOffsetInt, TrOffsetInt); ++ MpiSetValue(&MpiSymbolRateHz, (long)SymbolRateHz); ++ MpiSetValue(&MpiCrystalFreqHz, (long)CrystalFreqHz); ++ MpiSetValue(&MpiVar0, 1000000); ++ ++ MpiMul(&MpiVar0, MpiVar0, MpiTrOffsetInt); ++ MpiMul(&MpiVar0, MpiVar0, MpiSymbolRateHz); ++ MpiLeftShift(&MpiVar1, MpiCrystalFreqHz, 35); ++ MpiDiv(&MpiVar0, &MpiVar1, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, pTrOffsetPpm); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_symbol_rate: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++rtl2840_GetCrOffsetHz( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ) ++{ ++ unsigned long SymbolRateHz; ++ ++ unsigned long CrOffsetBinary; ++ long CrOffsetInt; ++ ++ MPI MpiCrOffsetInt, MpiSymbolRateHz, MpiMiddleResult; ++ ++ ++ ++ // Get demod symbol rate in Hz. ++ if(pDemod->GetSymbolRateHz(pDemod, &SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_symbol_rate; ++ ++ ++ // Get CR offset binary value from CR_OFFSET monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_CR_OFFSET, &CrOffsetBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert CR offset binary value to signed integer. ++ CrOffsetInt = BinToSignedInt(CrOffsetBinary, RTL2840_CR_OFFSET_BIT_NUM); ++ ++ ++ // Get CR offset in Hz. ++ // Note: (CR offset in Hz) = (CR offset integer) * (symbol rate in Hz) / pow(2, 34) ++ // CR offset integer is 32 bit value. ++ MpiSetValue(&MpiCrOffsetInt, CrOffsetInt); ++ MpiSetValue(&MpiSymbolRateHz, (long)SymbolRateHz); ++ ++ MpiMul(&MpiMiddleResult, MpiCrOffsetInt, MpiSymbolRateHz); ++ MpiRightShift(&MpiMiddleResult, MpiMiddleResult, 34); ++ ++ MpiGetValue(MpiMiddleResult, pCrOffsetHz); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_symbol_rate: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_AAGC_LOCKED ++ ++*/ ++int ++rtl2840_IsAagcLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long LockStatus; ++ ++ ++ ++ // Get AAGC lock status from AAGC_LD inner strobe register bits. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_AAGC_LD, &LockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine answer according to AAGC lock status. ++ if(LockStatus == LOCKED) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_EQ_LOCKED ++ ++*/ ++int ++rtl2840_IsEqLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long LockStatus; ++ ++ ++ ++ // Get EQ lock status from EQ_LD inner strobe register bits. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_EQ_LD, &LockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine answer according to EQ lock status. ++ if(LockStatus == LOCKED) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_FRAME_LOCKED ++ ++*/ ++int ++rtl2840_IsFrameLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long LossStatus; ++ ++ ++ ++ // Get frame loss status from SYNCLOST register bits. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_SYNCLOST, &LossStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine answer according to frame loss status. ++ if(LossStatus == NOT_LOST) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_ERROR_RATE ++ ++*/ ++int ++rtl2840_GetErrorRate( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned long TestPacketNum; ++ unsigned int WaitCnt; ++ int FrameLock; ++ unsigned long BerReg2, BerReg2Msb, BerReg2Lsb; ++ unsigned long BerReg0, BerReg1; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Calculate test packet number and wait counter value. ++ TestPacketNum = 0x1 << (TestVolume * 2 + 4); ++ WaitCnt = WaitTimeMsMax / RTL2840_BER_WAIT_TIME_MS; ++ ++ ++ // Set TEST_VOLUME with test volume. ++ // Note: The function SetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_TEST_VOLUME, TestVolume) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Clear and enable error counter. ++ // Note: The function SetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_BERT_EN, OFF) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_BERT_EN, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Check if error test is finished. ++ for(i = 0; i < WaitCnt; i++) ++ { ++ // Check if demod is frame-locked. ++ if(pDemod->IsFrameLocked(pDemod, &FrameLock) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(FrameLock == NO) ++ goto error_status_frame_lock; ++ ++ ++ // Wait a minute. ++ // Note: The input unit of WaitMs() is ms. ++ pBaseInterface->WaitMs(pBaseInterface, RTL2840_BER_WAIT_TIME_MS); ++ ++ ++ // Set error counter strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ // The function SetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_BER_RD_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Check if error test is finished. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG2_15_0, &BerReg2Lsb) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG2_18_16, &BerReg2Msb) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ BerReg2 = (BerReg2Msb << RTL2840_BER_REG2_MSB_SHIFT) | BerReg2Lsb; ++ ++ if(BerReg2 == TestPacketNum) ++ break; ++ } ++ ++ ++ // Check time-out status. ++ if(i == WaitCnt) ++ goto error_status_time_out; ++ ++ ++ // Get BER register 0 from BER_REG0. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG0, &BerReg0) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Get BER register 1 from BER_REG1. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG1, &BerReg1) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Set BER numerator and denominator. ++ *pBerNum = 27 * BerReg0 + BerReg1; ++ *pBerDen = 1632 * TestPacketNum; ++ ++ ++ // Set PER numerator and denominator. ++ *pPerNum = BerReg0; ++ *pPerDen = TestPacketNum; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++error_status_frame_lock: ++error_status_time_out: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SNR_DB ++ ++*/ ++int ++rtl2840_GetSnrDb( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ static const unsigned long SnrConstTable[QAM_QAM_MODE_NUM] = ++ { ++ 26880, // for 4-QAM mode ++ 29852, // for 16-QAM mode ++ 31132, // for 32-QAM mode ++ 32502, // for 64-QAM mode ++ 33738, // for 128-QAM mode ++ 35084, // for 256-QAM mode ++ 36298, // for 512-QAM mode ++ 37649, // for 1024-QAM mode ++ }; ++ ++ int QamMode; ++ ++ unsigned long Mse; ++ long MiddleResult; ++ MPI MpiMse, MpiResult; ++ ++ ++ ++ // Get demod QAM mode. ++ if(pDemod->GetQamMode(pDemod, &QamMode) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_qam_mode; ++ ++ ++ // Get mean-square error from MSE. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_MSE, &Mse) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Calculate SNR dB numerator. ++ MpiSetValue(&MpiMse, Mse); ++ MpiLog2(&MpiResult, MpiMse, RTL2840_SNR_FRAC_BIT_NUM); ++ MpiGetValue(MpiResult, &MiddleResult); ++ ++ *pSnrDbNum = SnrConstTable[QamMode] - 10 * MiddleResult; ++ ++ ++ // Set SNR dB denominator. ++ *pSnrDbDen = RTL2840_SNR_DB_DEN; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_qam_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++rtl2840_GetSignalStrength( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ) ++{ ++ int FrameLock; ++ long IfAgcValue; ++ ++ ++ ++ // Get demod frame lock status. ++ if(pDemod->IsFrameLocked(pDemod, &FrameLock) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // If demod is not frame-locked, set signal strength with zero. ++ if(FrameLock == NO) ++ { ++ *pSignalStrength = 0; ++ goto success_status_non_frame_lock; ++ } ++ ++ ++ // Get IF AGC value. ++ if(pDemod->GetIfAgc(pDemod, &IfAgcValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine signal strength according to IF AGC value. ++ // Note: Map IF AGC value (1023 ~ -1024) to signal strength (0 ~ 100). ++ *pSignalStrength = (102300 - IfAgcValue * 100) / 2047; ++ ++ ++success_status_non_frame_lock: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++rtl2840_GetSignalQuality( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ) ++{ ++ int FrameLock; ++ ++ unsigned long Mse; ++ long MiddleResult; ++ MPI MpiMse, MpiResult; ++ ++ ++ ++ // Get demod frame lock status. ++ if(pDemod->IsFrameLocked(pDemod, &FrameLock) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // If demod is not frame-locked, set signal quality with zero. ++ if(FrameLock == NO) ++ { ++ *pSignalQuality = 0; ++ goto success_status_non_frame_lock; ++ } ++ ++ ++ // Get mean-square error from MSE. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_MSE, &Mse) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine signal quality according to MSE value. ++ // Note: Map MSE value (pow(2, 19) ~ pow(2, 17)) to signal quality (0 ~ 100). ++ // If MSE value < pow(2, 17), signal quality is 100. ++ // If MSE value > pow(2, 19), signal quality is 0. ++ if(Mse > 524288) ++ { ++ *pSignalQuality = 0; ++ } ++ else if(Mse < 131072) ++ { ++ *pSignalQuality = 100; ++ } ++ else ++ { ++ MpiSetValue(&MpiMse, Mse); ++ MpiLog2(&MpiResult, MpiMse, RTL2840_SIGNAL_QUALITY_FRAC_BIT_NUM); ++ MpiGetValue(MpiResult, &MiddleResult); ++ ++ *pSignalQuality = (243200 - MiddleResult * 100) / 256; ++ } ++ ++ ++success_status_non_frame_lock: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2840_UpdateFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ // RTL2840 does not use UpdateFunction(), so we just return FUNCTION_SUCCESS. ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_RESET_FUNCTION ++ ++*/ ++int ++rtl2840_ResetFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ // RTL2840 does not use UpdateFunction(), so we just return FUNCTION_SUCCESS. ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_QAM_MODE ++ ++*/ ++int ++rtl2840_am_hum_en_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue[QAM_QAM_MODE_NUM]; ++ } ++ QAM_MODE_REG_ENTRY; ++ ++ ++ typedef struct ++ { ++ unsigned char SpecReg0Sel; ++ unsigned char SpecReg0ValueTable[QAM_QAM_MODE_NUM][RTL2840_SPEC_REG_0_VALUE_TABLE_LEN]; ++ } ++ QAM_MODE_SPEC_REG_0_ENTRY; ++ ++ ++ ++ static const QAM_MODE_REG_ENTRY QamModeRegTable[RTL2840_QAM_MODE_REG_TABLE_LEN] = ++ { ++ // Reg, WritingValue according to QAM mode ++ // PageNo, StartAddr, Msb, Lsb, {4-Q, 16-Q, 32-Q, 64-Q, 128-Q, 256-Q, 512-Q, 1024-Q} ++ {1, 0x02, 2, 0, {0x7, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }}, ++ {1, 0x2f, 15, 5, {0x37, 0x82, 0xb9, 0x10e, 0x177, 0x21c, 0x2ee, 0x451 }}, ++ {1, 0x31, 5, 0, {0x1, 0x3, 0x4, 0x5, 0x8, 0xa, 0xf, 0x14 }}, ++ {1, 0x2e, 5, 0, {0x2, 0x4, 0x6, 0x8, 0xc, 0x10, 0x18, 0x20 }}, ++ {1, 0x18, 7, 0, {0x0, 0xdb, 0x79, 0x0, 0x8a, 0x0, 0x8c, 0x0 }}, ++ {1, 0x19, 4, 0, {0x14, 0x14, 0xf, 0x14, 0xf, 0x14, 0xf, 0x14 }}, ++ {1, 0x3b, 2, 0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3b, 5, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 4, 3, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3c, 6, 5, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 1, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 3, 2, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3d, 5, 4, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 7, 6, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x41, 4, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x41, 6, 5, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 1, 0, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ {1, 0x42, 3, 2, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x42, 5, 4, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 7, 6, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ ++ ++ // For AM-hum enhancement ++ // Reg, WritingValue according to QAM mode ++ // PageNo, StartAddr, Msb, Lsb, {4-Q, 16-Q, 32-Q, 64-Q, 128-Q, 256-Q, 512-Q, 1024-Q} ++ {1, 0x05, 7, 0, {0x64, 0x64, 0x64, 0x64, 0x6b, 0x6b, 0x6b, 0x6b }}, ++ {1, 0x40, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x40, 5, 3, {0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x3, 0x3 }}, ++ {1, 0x41, 2, 0, {0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x4, 0x4 }}, ++ }; ++ ++ ++ static const QAM_MODE_SPEC_REG_0_ENTRY QamModeSpecReg0Table[RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN] = ++ { ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {9, { {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {10, { {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ ++ ++ // For AM-hum enhancement ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {12, { {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 4-QAM ++ {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 16-QAM ++ {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 32-QAM ++ {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 64-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 128-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 256-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 512-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, } // 1024-QAM ++ }, ++ }; ++ ++ ++ int i; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ unsigned char SpecReg0Sel; ++ const unsigned char *pSpecReg0ValueTable; ++ ++ ++ ++ // Set demod QAM mode with QAM mode register setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register setting entry according to QAM mode. ++ PageNo = QamModeRegTable[i].PageNo; ++ RegStartAddr = QamModeRegTable[i].RegStartAddr; ++ Msb = QamModeRegTable[i].Msb; ++ Lsb = QamModeRegTable[i].Lsb; ++ WritingValue = QamModeRegTable[i].WritingValue[QamMode]; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set register page number with inner page number for QAM mode specific register 0 setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set demod QAM mode with QAM mode specific register 0 setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN; i++) ++ { ++ // Get all information from each specific register 0 setting entry according to QAM mode. ++ SpecReg0Sel = QamModeSpecReg0Table[i].SpecReg0Sel; ++ pSpecReg0ValueTable = QamModeSpecReg0Table[i].SpecReg0ValueTable[QamMode]; ++ ++ // Set specific register 0 selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_SEL, SpecReg0Sel) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 values. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RTL2840_SPEC_REG_0_VAL_START_ADDR, pSpecReg0ValueTable, LEN_11_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod QAM mode parameter. ++ pDemod->QamMode = QamMode; ++ pDemod->IsQamModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ++ ++*/ ++int ++rtl2840_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module and tuner device address. ++ pDemod = (QAM_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Enable demod I2C relay. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Send I2C reading command. ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_reading_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_reading_command: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ++ ++*/ ++int ++rtl2840_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module and tuner device address. ++ pDemod = (QAM_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Enable demod I2C relay. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_writing_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_writing_command: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize base register table ++ ++RTL2840 builder will use rtl2840_InitBaseRegTable() to initialize base register table. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2840Module() ++ ++*/ ++void ++rtl2840_InitBaseRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const QAM_PRIMARY_BASE_REG_ENTRY_ADDR_8BIT PrimaryBaseRegTable[RTL2840_BASE_REG_TABLE_LEN] = ++ { ++ // Generality ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SYS_VERSION, 0, 0x01, 7, 0 }, ++ {QAM_OPT_I2C_RELAY, 0, 0x03, 5, 5 }, ++ {QAM_SOFT_RESET, 0, 0x09, 0, 0 }, ++ ++ // Miscellany ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_OPT_I2C_DRIVE_CURRENT, 0, 0x07, 7, 7 }, ++ {QAM_GPIO2_OEN, 0, 0x05, 6, 6 }, ++ {QAM_GPIO3_OEN, 0, 0x05, 7, 7 }, ++ {QAM_GPIO2_O, 0, 0x0a, 2, 2 }, ++ {QAM_GPIO3_O, 0, 0x0a, 3, 3 }, ++ {QAM_GPIO2_I, 0, 0x0a, 6, 6 }, ++ {QAM_GPIO3_I, 0, 0x0a, 7, 7 }, ++ {QAM_INNER_DATA_STROBE, 1, 0x69, 0, 0 }, ++ {QAM_INNER_DATA_SEL1, 1, 0x48, 7, 0 }, ++ {QAM_INNER_DATA_SEL2, 1, 0x49, 7, 0 }, ++ {QAM_INNER_DATA1, 1, 0x6a, 15, 0 }, ++ {QAM_INNER_DATA2, 1, 0x6c, 15, 0 }, ++ ++ // QAM mode ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_QAM_MODE, 1, 0x02, 2, 0 }, ++ ++ // AD ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_AD_AV, 0, 0x0b, 2, 0 }, ++ ++ // AAGC ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_OPT_RF_AAGC_DRIVE_CURRENT, 0, 0x07, 0, 0 }, ++ {QAM_OPT_IF_AAGC_DRIVE_CURRENT, 0, 0x07, 1, 1 }, ++ {QAM_OPT_RF_AAGC_DRIVE, 0, 0x04, 3, 3 }, ++ {QAM_OPT_IF_AAGC_DRIVE, 0, 0x04, 4, 4 }, ++ {QAM_OPT_RF_AAGC_OEN, 0, 0x04, 6, 6 }, ++ {QAM_OPT_IF_AAGC_OEN, 0, 0x04, 7, 7 }, ++ {QAM_PAR_RF_SD_IB, 0, 0x03, 0, 0 }, ++ {QAM_PAR_IF_SD_IB, 0, 0x03, 1, 1 }, ++ {QAM_AAGC_FZ_OPTION, 1, 0x04, 5, 4 }, ++ {QAM_AAGC_TARGET, 1, 0x05, 7, 0 }, ++ {QAM_RF_AAGC_MAX, 1, 0x06, 7, 0 }, ++ {QAM_RF_AAGC_MIN, 1, 0x07, 7, 0 }, ++ {QAM_IF_AAGC_MAX, 1, 0x08, 7, 0 }, ++ {QAM_IF_AAGC_MIN, 1, 0x09, 7, 0 }, ++ {QAM_VTOP, 1, 0x0b, 7, 0 }, ++ {QAM_KRF_MSB, 1, 0x0c, 6, 3 }, ++ {QAM_KRF_LSB, 1, 0x04, 7, 6 }, ++ {QAM_AAGC_MODE_SEL, 1, 0x0c, 7, 7 }, ++ {QAM_AAGC_LD, 1, 0x72, 0, 0 }, ++ {QAM_AAGC_INIT_LEVEL, 1, 0x0a, 7, 0 }, ++ ++ // DDC ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_DDC_FREQ, 1, 0x0d, 14, 0 }, ++ {QAM_SPEC_INV, 1, 0x0e, 7, 7 }, ++ ++ // Timing recovery ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_TR_DECI_RATIO, 1, 0x1f, 23, 0 }, ++ ++ // Carrier recovery ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_CR_LD, 1, 0x74, 5, 0 }, ++ ++ // Equalizer ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_EQ_LD, 1, 0x72, 1, 1 }, ++ {QAM_MSE, 1, 0x76, 21, 0 }, ++ ++ // Frame sync. indicator ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SYNCLOST, 2, 0x02, 7, 7 }, ++ ++ // BER ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_BER_RD_STROBE, 2, 0x05, 7, 7 }, ++ {QAM_BERT_EN, 2, 0x06, 0, 0 }, ++ {QAM_BERT_HOLD, 2, 0x06, 1, 1 }, ++ {QAM_DIS_AUTO_MODE, 2, 0x06, 2, 2 }, ++ {QAM_TEST_VOLUME, 2, 0x06, 5, 3 }, ++ {QAM_BER_REG0, 2, 0x0e, 15, 0 }, ++ {QAM_BER_REG1, 2, 0x07, 20, 0 }, ++ {QAM_BER_REG2_15_0, 2, 0x0a, 15, 0 }, ++ {QAM_BER_REG2_18_16, 2, 0x09, 7, 5 }, ++ ++ // MPEG TS output interface ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_CKOUTPAR, 2, 0x11, 0, 0 }, ++ {QAM_CKOUT_PWR, 2, 0x11, 1, 1 }, ++ {QAM_CDIV_PH0, 2, 0x12, 3, 0 }, ++ {QAM_CDIV_PH1, 2, 0x12, 7, 4 }, ++ {QAM_MPEG_OUT_EN, 0, 0x04, 5, 5 }, ++ {QAM_OPT_MPEG_DRIVE_CURRENT, 0, 0x07, 2, 2 }, ++ {QAM_NO_REINVERT, 2, 0x10, 2, 2 }, ++ {QAM_FIX_TEI, 2, 0x10, 3, 3 }, ++ {QAM_SERIAL, 2, 0x11, 2, 2 }, ++ ++ // Monitor ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_ADC_CLIP_CNT_REC, 1, 0x6a, 15, 4 }, ++ {QAM_DAGC_LEVEL_26_11, 1, 0x6a, 15, 0 }, ++ {QAM_DAGC_LEVEL_10_0, 1, 0x6c, 15, 5 }, ++ {QAM_RF_AAGC_SD_IN, 1, 0x6a, 15, 5 }, ++ {QAM_IF_AAGC_SD_IN, 1, 0x6c, 15, 5 }, ++ {QAM_KI_TR_OUT_30_15, 1, 0x6a, 15, 0 }, ++ {QAM_KI_TR_OUT_14_0, 1, 0x6c, 15, 1 }, ++ {QAM_KI_CR_OUT_15_0, 1, 0x6a, 15, 0 }, ++ {QAM_KI_CR_OUT_31_16, 1, 0x6c, 15, 0 }, ++ ++ // Specific register ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SPEC_SIGNAL_INDICATOR, 1, 0x73, 5, 3 }, ++ {QAM_SPEC_ALPHA_STROBE, 1, 0x57, 0, 0 }, ++ {QAM_SPEC_ALPHA_SEL, 1, 0x57, 4, 1 }, ++ {QAM_SPEC_ALPHA_VAL, 1, 0x57, 14, 5 }, ++ {QAM_SPEC_SYMBOL_RATE_REG_0, 1, 0x0f, 2, 0 }, ++ {QAM_SPEC_SYMBOL_RATE_STROBE, 1, 0x5b, 0, 0 }, ++ {QAM_SPEC_SYMBOL_RATE_SEL, 1, 0x5b, 4, 1 }, ++ {QAM_SPEC_SYMBOL_RATE_VAL, 1, 0x5b, 14, 5 }, ++ {QAM_SPEC_REG_0_STROBE, 1, 0x5d, 0, 0 }, ++ {QAM_SPEC_REG_0_SEL, 1, 0x5d, 4, 1 }, ++ ++ // Specific register for initialization ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SPEC_INIT_A0, 1, 0x6a, 15, 6 }, ++ {QAM_SPEC_INIT_A1, 0, 0x0f, 0, 0 }, ++ {QAM_SPEC_INIT_A2, 1, 0x2b, 1, 1 }, ++ ++ // Pseudo register for test only ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_TEST_REG_0, 1, 0x17, 6, 2 }, ++ {QAM_TEST_REG_1, 1, 0x17, 14, 1 }, ++ {QAM_TEST_REG_2, 1, 0x17, 21, 3 }, ++ {QAM_TEST_REG_3, 1, 0x17, 30, 2 }, ++ }; ++ ++ ++ int i; ++ int RegBitName; ++ ++ ++ ++ // Initialize base register table according to primary base register table. ++ // Note: 1. Base register table rows are sorted by register bit name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < QAM_BASE_REG_TABLE_LEN_MAX; i++) ++ pDemod->BaseRegTable.Addr8Bit[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2840_BASE_REG_TABLE_LEN; i++) ++ { ++ RegBitName = PrimaryBaseRegTable[i].RegBitName; ++ ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].IsAvailable = YES; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].PageNo = PrimaryBaseRegTable[i].PageNo; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].RegStartAddr = PrimaryBaseRegTable[i].RegStartAddr; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].Msb = PrimaryBaseRegTable[i].Msb; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].Lsb = PrimaryBaseRegTable[i].Lsb; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize monitor register table ++ ++RTL2840 builder will use rtl2840_InitMonitorRegTable() to initialize monitor register table. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2840Module() ++ ++*/ ++void ++rtl2840_InitMonitorRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const QAM_PRIMARY_MONITOR_REG_ENTRY_ADDR_8BIT PrimaryMonitorRegTable[RTL2840_MONITOR_REG_TABLE_LEN] = ++ { ++ // Generality ++ // MonitorRegBitName, InfoNum, {SelRegAddr, SelValue, RegBitName, Shift } ++ {QAM_ADC_CLIP_CNT, 1, { {0x48, 0x01, QAM_ADC_CLIP_CNT_REC, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ ++ {QAM_DAGC_VALUE, 2, { {0x48, 0x20, QAM_DAGC_LEVEL_26_11, 11 }, ++ {0x49, 0x20, QAM_DAGC_LEVEL_10_0, 0 }, }}, ++ ++ {QAM_RF_AGC_VALUE, 1, { {0x48, 0x80, QAM_RF_AAGC_SD_IN, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ ++ {QAM_IF_AGC_VALUE, 1, { {0x49, 0x80, QAM_IF_AAGC_SD_IN, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ ++ {QAM_TR_OFFSET, 2, { {0x48, 0xc2, QAM_KI_TR_OUT_30_15, 15 }, ++ {0x49, 0xc2, QAM_KI_TR_OUT_14_0, 0 }, }}, ++ ++ {QAM_CR_OFFSET, 2, { {0x48, 0xc3, QAM_KI_CR_OUT_15_0, 0 }, ++ {0x49, 0xc3, QAM_KI_CR_OUT_31_16, 16 }, }}, ++ ++ // Specific monitor register for initialization ++ // MonitorRegBitName, InfoNum, {SelRegAddr, SelValue, RegBitName, Shift } ++ {QAM_SPEC_MONITER_INIT_0, 1, { {0x48, 0x00, QAM_SPEC_INIT_A0, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ }; ++ ++ ++ int i, j; ++ int MonitorRegBitName; ++ ++ ++ ++ // Initialize monitor register table according to primary monitor register table. ++ // Note: 1. Monitor register table rows are sorted by monitor register name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < QAM_MONITOR_REG_TABLE_LEN_MAX; i++) ++ pDemod->MonitorRegTable.Addr8Bit[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2840_MONITOR_REG_TABLE_LEN; i++) ++ { ++ MonitorRegBitName = PrimaryMonitorRegTable[i].MonitorRegBitName; ++ ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].IsAvailable = YES; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoNum = PrimaryMonitorRegTable[i].InfoNum; ++ ++ for(j = 0; j < QAM_MONITOR_REG_INFO_TABLE_LEN; j++) ++ { ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].SelRegAddr = ++ PrimaryMonitorRegTable[i].InfoTable[j].SelRegAddr; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].SelValue = ++ PrimaryMonitorRegTable[i].InfoTable[j].SelValue; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].RegBitName = ++ PrimaryMonitorRegTable[i].InfoTable[j].RegBitName; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].Shift = ++ PrimaryMonitorRegTable[i].InfoTable[j].Shift; ++ } ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get inner strobe register bits. ++ ++RTL2840 upper level functions will use rtl2840_GetInnerStrobeRegBits() to get register bits with inner strobe. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and inner strobe. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Don't need to set register page before using rtl2840_GetInnerStrobeRegBits(). ++ ++*/ ++int ++rtl2840_GetInnerStrobeRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ // Set register page number with inner page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set inner data strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_INNER_DATA_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get the inner strobe register bits. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get monitor register bits. ++ ++RTL2840 upper level functions will use rtl2840_GetMonitorRegBits() to get monitor register bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] MonitorRegBitName Pre-defined demod monitor register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod monitor register bits successfully with monitor bit name. ++@retval FUNCTION_ERROR Get demod monitor register bits unsuccessfully. ++ ++ ++@note ++ -# Don't need to set register page before using rtl2840_GetMonitorRegBits(). ++ ++*/ ++int ++rtl2840_GetMonitorRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int MonitorRegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char InfoNum; ++ unsigned char SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ ++ unsigned long Buffer[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++ ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].IsAvailable == NO) ++ goto error_status_monitor_register_bit_name; ++ ++ ++ // Get information entry number from monitor register table by monitor register name key. ++ InfoNum = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoNum; ++ ++ ++ // Set register page number with inner page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set selection register with selection value for each information entry. ++ for(i = 0; i < InfoNum; i++) ++ { ++ // Get selection register address and value from information entry by monitor register name key. ++ SelRegAddr = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].SelRegAddr; ++ SelValue = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].SelValue; ++ ++ // Set selection register with selection value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, SelRegAddr, &SelValue, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set inner data strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_INNER_DATA_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register bits to buffer according to register bit names for each information entry. ++ for(i = 0; i < InfoNum; i++) ++ { ++ // Get register bit name from information entry by monitor register name key. ++ RegBitName = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].RegBitName; ++ ++ // Get register bits and store it to buffer. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, &Buffer[i]) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ // Combine the buffer values into reading value. ++ *pReadingValue = 0; ++ ++ for(i = 0; i < InfoNum; i++) ++ { ++ // Get shift from information entry by monitor register name key. ++ Shift = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].Shift; ++ ++ // Combine the buffer values into reading value with shift. ++ *pReadingValue |= Buffer[i] << Shift; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++error_status_monitor_register_bit_name: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set I2C bridge module demod arguments. ++ ++RTL2840 builder will use rtl2840_BuildI2cBridgeModule() to set I2C bridge module demod arguments. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2840Module() ++ ++*/ ++void ++rtl2840_BuildI2cBridgeModule( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ ++ // Get I2C bridge module. ++ pI2cBridge = pDemod->pI2cBridge; ++ ++ // Set I2C bridge module demod arguments. ++ pI2cBridge->pPrivateData = (void *)pDemod; ++ pI2cBridge->ForwardI2cReadingCmd = rtl2840_ForwardI2cReadingCmd; ++ pI2cBridge->ForwardI2cWritingCmd = rtl2840_ForwardI2cWritingCmd; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2840.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2840.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/demod_rtl2840.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/demod_rtl2840.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,386 @@ ++#ifndef __DEMOD_RTL2840_H ++#define __DEMOD_RTL2840_H ++ ++/** ++ ++@file ++ ++@brief RTL2840 QAM demod module declaration ++ ++One can manipulate RTL2840 QAM demod through RTL2840 module. ++RTL2840 module is derived from QAM demod module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the QAM demod example in qam_demod_base.h except the listed lines. ++ ++ ++ ++#include "demod_rtl2840.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ ++ ... ++ ++ ++ ++ // Build RTL2840 demod module. ++ BuildRtl2840Module( ++ &pDemod, ++ &QamDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x44, // I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM // Enhancement mode is AM-hum. ++ ); ++ ++ ++ ++ // See the example for other QAM demod functions in qam_demod_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "qam_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2840_BASE_REG_TABLE_LEN 88 ++#define RTL2840_MONITOR_REG_TABLE_LEN 7 ++ ++#define RTL2840_PAGE_REG_ADDR 0x0 ++#define RTL2840_SYS_VERSION_VALUE 0xa3 ++ ++ ++ ++// Specific register ++#define RTL2840_SPEC_REG_0_VAL_START_ADDR 0x5e ++ ++ ++ ++// Initialization ++#define RTL2840_SPEC_MONITOR_INIT_0_COMPARISON_TIMES 30 ++ ++// RF_AGC_VALUE register ++#define RTL2840_RF_AGC_VALUE_BIT_NUM 11 ++ ++// IF_AGC_VALUE register ++#define RTL2840_IF_AGC_VALUE_BIT_NUM 11 ++ ++// CR_OFFSET register ++#define RTL2840_CR_OFFSET_BIT_NUM 32 ++ ++// TR_OFFSET register ++#define RTL2840_TR_OFFSET_BIT_NUM 31 ++ ++ ++ ++// BER and UPER ++#define RTL2840_BER_WAIT_TIME_MS 10 ++#define RTL2840_BER_REG2_MSB_SHIFT 16 ++ ++// SNR ++// Note: RTL2840_SNR_DB_DEN = round(log2(10) * pow(2, RTL2840_SNR_FRAC_BIT_NUM)) ++#define RTL2840_SNR_FRAC_BIT_NUM 7 ++#define RTL2840_SNR_DB_DEN 425 ++ ++ ++ ++// Singal strength and signal quality ++#define RTL2840_SIGNAL_QUALITY_FRAC_BIT_NUM 7 ++ ++ ++ ++ ++ ++// Table length ++#define RTL2840_SPEC_REG_0_VALUE_TABLE_LEN 11 ++#define RTL2840_SYMBOL_RATE_VALUE_TABLE_LEN 9 ++ ++#define RTL2840_INIT_REG_TABLE_LEN 45 ++#define RTL2840_INIT_SPEC_REG_0_TABLE_LEN 13 ++#define RTL2840_TS_INTERFACE_INIT_TABLE_LEN 3 ++ ++#define RTL2840_QAM_MODE_REG_TABLE_LEN 25 ++#define RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN 3 ++ ++#define RTL2840_ALPHA_VALUE_TABLE_LEN 16 ++ ++#define RTL2840_SYMBOL_RATE_TABLE_LEN 3 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2840Module( ++ QAM_DEMOD_MODULE **ppDemod, ++ QAM_DEMOD_MODULE *pQamDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int EnhancementMode ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++rtl2840_IsConnectedToI2c( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_SoftwareReset( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2840_Initialize( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2840_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ); ++ ++int ++rtl2840_SetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long SymbolRateHz ++ ); ++ ++int ++rtl2840_SetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int AlphaMode ++ ); ++ ++int ++rtl2840_SetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++int ++rtl2840_SetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++int ++rtl2840_GetRfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++int ++rtl2840_GetIfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++int ++rtl2840_GetDiAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++int ++rtl2840_GetTrOffsetPpm( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++int ++rtl2840_GetCrOffsetHz( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++int ++rtl2840_IsAagcLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_IsEqLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_IsFrameLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_GetErrorRate( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++rtl2840_GetSnrDb( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++rtl2840_GetSignalStrength( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++rtl2840_GetSignalQuality( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++rtl2840_UpdateFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2840_ResetFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// Demod AM-hum enhancement functions ++int ++rtl2840_am_hum_en_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ); ++ ++ ++ ++ ++ ++// I2C command forwarding functions ++int ++rtl2840_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++rtl2840_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++// Register table initialization ++void ++rtl2840_InitBaseRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++void ++rtl2840_InitMonitorRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// Register getting methods ++int ++rtl2840_GetInnerStrobeRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++rtl2840_GetMonitorRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int MonitorRegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// I2C birdge module builder ++void ++rtl2840_BuildI2cBridgeModule( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_demod_base.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_demod_base.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_demod_base.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_demod_base.c 2010-10-12 19:35:16.000000000 +0200 +@@ -0,0 +1,1569 @@ ++/** ++ ++@file ++ ++@brief DTMB demod default function definition ++ ++DTMB demod default functions. ++ ++*/ ++#include "rtl2832u_io.h" ++#include "dtmb_demod_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register page with page number. ++ // Note: The I2C format of demod register page setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + DTMB_DEMOD_PAGE_REG_ADDR + PageNo + stop_bit ++ WritingBytes[0] = DTMB_DEMOD_PAGE_REG_ADDR; ++ WritingBytes[1] = (unsigned char)PageNo; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // temp, because page register is write-only. ++ pDemod->CurrentPageNo = PageNo; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Set register bytes separately. ++int ++internal_dtmb_demod_addr_8bit_SetRegBytesSeparately( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = (unsigned char)(RegStartAddr + i); ++ WritingBuffer[1] = pWritingBytes[i]; ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ struct dvb_usb_device *d; ++ unsigned int i; ++ unsigned char DeviceAddr; ++ //unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ unsigned long PageNo = pDemod->CurrentPageNo; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get user defined data pointer of base interface structure for context. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ ++ // Set demod register bytes with writing buffer. ++ if(write_demod_register(d, DeviceAddr, PageNo, RegStartAddr+i, (unsigned char*)pWritingBytes+i, LEN_1_BYTE)) ++ goto error_status_set_demod_registers; ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Set register bytes continuously. ++int ++internal_dtmb_demod_addr_8bit_SetRegBytesContinuously( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ unsigned long CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ ++ // Get page register number. ++ CurrentPageNo = pDemod->CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ // Set register bytes according to page register number. ++ switch(CurrentPageNo) ++ { ++ case 0: ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ ++ if(internal_dtmb_demod_addr_8bit_SetRegBytesSeparately(pDemod, RegStartAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ break; ++ ++ ++ default: ++ ++ goto error_status_set_demod_registers; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes separately. ++int ++internal_dtmb_demod_addr_8bit_GetRegBytesSeparately( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ ++ unsigned char DeviceAddr; ++ unsigned char RegAddr; ++ unsigned char RegByte; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ RegAddr = (unsigned char)(RegStartAddr + i); ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &RegByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Copy register byte to reading bytes. ++ pReadingBytes[i] = RegByte; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ struct dvb_usb_device *d; ++ unsigned int i; ++ ++ unsigned char DeviceAddr; ++ ++ unsigned long PageNo = pDemod->CurrentPageNo; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get user defined data pointer of base interface structure for context. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, PageNo, RegStartAddr+i, pReadingBytes+i, LEN_1_BYTE)) ++ goto error_status_get_demod_registers; ++ ++ ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++//error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes continuously. ++int ++internal_dtmb_demod_addr_8bit_GetRegBytesContinuously( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ struct dvb_usb_device *d; ++ ++ unsigned char DeviceAddr; ++ ++ unsigned long PageNo = pDemod->CurrentPageNo; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get user defined data pointer of base interface structure for context. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, PageNo, RegStartAddr, pReadingBytes, ByteNum)) ++ goto error_status_get_demod_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ unsigned long CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ ++ // Get page register number. ++ CurrentPageNo = pDemod->CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ // Get register bytes according to page register number. ++ switch(CurrentPageNo) ++ { ++ case 0: ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ ++ if(internal_dtmb_demod_addr_8bit_GetRegBytesSeparately(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ case 5: ++ case 6: ++ case 7: ++ case 8: ++ case 9: ++ ++ if(internal_dtmb_demod_addr_8bit_GetRegBytesContinuously(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ default: ++ ++ goto error_status_get_demod_registers; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, RegBitName, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned short RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_2_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddrMsb + RegWritingAddrLsb + ++ // writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = (RegWritingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegWritingAddr & BYTE_MASK; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_2_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_2_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes normally. ++int ++internal_dtmb_demod_addr_16bit_GetRegBytesNormally( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned short RegReadingAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddrMsb + RegReadingAddrLsb + stop_bit ++ WritingBuffer[0] = (RegReadingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegReadingAddr & BYTE_MASK; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes with freeze. ++// Note: The maximum reading byte must be greater than or equal to 4. ++ ++#define DTMB_I2C_REG_DEBUG_PAGE_ADDR 0xc708 ++#define DTMB_I2C_REG_DEBUG_ADDR_ADDR 0xc709 ++#define DTMB_I2C_REG_DEBUG_FREEZE_ADDR 0xc70a ++#define DTMB_I2C_REG_DEBUG_BYTE_ADDR 0xc70b ++ ++int ++internal_dtmb_demod_addr_16bit_GetRegBytesWithFreeze( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ ++ unsigned char WritingBuffer[LEN_4_BYTE]; ++ unsigned char ReadingBuffer[LEN_4_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddrMsb + RegWritingAddrLsb + writing_bytes (WritingByteNum bytes) + stop_bit ++ ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ ++ // Set I2C_REG_DEBUG_PAGE and I2C_REG_DEBUG_ADDR with register start address. ++ // Note: 1. Set I2C_REG_DEBUG_PAGE with register start address [11:8]. ++ // 2. Set I2C_REG_DEBUG_ADDR with register start address [7:0]. ++ WritingBuffer[0] = (DTMB_I2C_REG_DEBUG_PAGE_ADDR >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = DTMB_I2C_REG_DEBUG_PAGE_ADDR & BYTE_MASK; ++ WritingBuffer[2] = (RegStartAddr >> BYTE_SHIFT) & HEX_DIGIT_MASK; ++ WritingBuffer[3] = RegStartAddr & BYTE_MASK; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_4_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set I2C_REG_DEBUG_FREEZE with 0x1. ++ WritingBuffer[0] = (DTMB_I2C_REG_DEBUG_FREEZE_ADDR >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = DTMB_I2C_REG_DEBUG_FREEZE_ADDR & BYTE_MASK; ++ WritingBuffer[2] = 0x1; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_3_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get I2C_REG_DEBUG_BYTE 4 bytes. ++ WritingBuffer[0] = (DTMB_I2C_REG_DEBUG_BYTE_ADDR >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = DTMB_I2C_REG_DEBUG_BYTE_ADDR & BYTE_MASK; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, ReadingBuffer, LEN_4_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Arrange reading bytes from big-endian to little-endian. ++ // Note: 1. The bytes format reading from I2C_REG_DEBUG_BYTE is big-endian. ++ // 2. The bytes format we needs is little-endian. ++ for(i = 0; i < ByteNum; i++) ++ { ++ // Set reading bytes. ++ pReadingBytes[i] = ReadingBuffer[LEN_3_BYTE - i]; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ unsigned char RegStartAddrMsb; ++ ++ ++ ++ // Get regiser start address MSB. ++ RegStartAddrMsb = (RegStartAddr >> BYTE_SHIFT) & BYTE_MASK; ++ ++ ++ // Get register bytes according to page register number. ++ switch(RegStartAddrMsb) ++ { ++ case 0xc0: ++ case 0xc1: ++ case 0xc2: ++ case 0xc3: ++ case 0xc4: ++ case 0xc5: ++ case 0xc6: ++ case 0xc7: ++ case 0xe0: ++ case 0xf0: ++ ++ if(internal_dtmb_demod_addr_16bit_GetRegBytesNormally(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ case 0xc8: ++ case 0xc9: ++ case 0xca: ++ case 0xcb: ++ case 0xcc: ++ case 0xcd: ++ ++ if(internal_dtmb_demod_addr_16bit_GetRegBytesWithFreeze(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ default: ++ ++ goto error_status_get_demod_registers; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr16Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_DEMOD_TYPE ++ ++*/ ++void ++dtmb_demod_default_GetDemodType( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ) ++{ ++ // Get demod type from demod module. ++ *pDemodType = pDemod->DemodType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++dtmb_demod_default_GetDeviceAddr( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get demod I2C device address from demod module. ++ *pDeviceAddr = pDemod->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ ++ ++*/ ++void ++dtmb_demod_default_GetCrystalFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ) ++{ ++ // Get demod crystal frequency in Hz from demod module. ++ *pCrystalFreqHz = pDemod->CrystalFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_IF_FREQ_HZ ++ ++*/ ++int ++dtmb_demod_default_GetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ // Get demod IF frequency in Hz from demod module. ++ if(pDemod->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pDemod->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SPECTRUM_MODE ++ ++*/ ++int ++dtmb_demod_default_GetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ) ++{ ++ // Get demod spectrum mode from demod module. ++ if(pDemod->IsSpectrumModeSet != YES) ++ goto error_status_get_demod_spectrum_mode; ++ ++ *pSpectrumMode = pDemod->SpectrumMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_spectrum_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_demod_base.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_demod_base.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_demod_base.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_demod_base.h 2010-10-12 19:35:18.000000000 +0200 +@@ -0,0 +1,2497 @@ ++#ifndef __DTMB_DEMOD_BASE_H ++#define __DTMB_DEMOD_BASE_H ++ ++/** ++ ++@file ++ ++@brief DTMB demod base module definition ++ ++DTMB demod base module definitions contains demod module structure, demod funciton pointers, and demod definitions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_xxx.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ ++ long RfAgc, IfAgc; ++ unsigned long DiAgc; ++ ++ int Answer; ++ long TrOffsetPpm, CrOffsetHz; ++ unsigned long BerNum, BerDen; ++ double Ber; ++ unsigned long PerNum, PerDen; ++ double Per; ++ long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ unsigned long SignalStrength, SignalQuality; ++ ++ int CarrierMode; ++ int PnMode; ++ int QamMode; ++ int CodeRateMode; ++ int TimeInterleaverMode; ++ ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, // Set maximum I2C reading byte number with 9. ++ 8, // Set maximum I2C writing byte number with 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ); ++ ++ ++ // Build DTMB demod XXX module. ++ BuildXxxModule( ++ &pDemod, ++ &DtmbDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x3e, // Demod I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // Demod crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // Demod TS interface mode is serial. ++ DIVERSITY_OFF // Demod diversity is disabled. ++ ... // Other arguments by each demod module ++ ); ++ ++ ++ ++ ++ ++ // ==== Initialize DTMB demod and set its parameters ===== ++ ++ // Initialize demod. ++ pDemod->Initialize(pDemod); ++ ++ ++ // Set demod parameters. (IF frequency and spectrum mode) ++ // Note: In the example: ++ // 1. IF frequency is 36.125 MHz. ++ // 2. Spectrum mode is SPECTRUM_INVERSE. ++ IfFreqHz = IF_FREQ_36125000HZ; ++ SpectrumMode = SPECTRUM_INVERSE; ++ ++ pDemod->SetIfFreqHz(pDemod, IfFreqHz); ++ pDemod->SetSpectrumMode(pDemod, SpectrumMode); ++ ++ ++ // Need to set tuner before demod software reset. ++ // The order to set demod and tuner is not important. ++ // Note: One can use "pDemod->SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1);" ++ // for tuner I2C command forwarding. ++ ++ ++ // Reset demod by software reset. ++ pDemod->SoftwareReset(pDemod); ++ ++ ++ // Wait maximum 1000 ms for demod converge. ++ for(i = 0; i < 25; i++) ++ { ++ // Wait 40 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 40); ++ ++ // Check signal lock status. ++ // Note: If Answer is YES, signal is locked. ++ // If Answer is NO, signal is not locked. ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ if(Answer == YES) ++ { ++ // Signal is locked. ++ break; ++ } ++ } ++ ++ ++ ++ ++ ++ // ==== Get DTMB demod information ===== ++ ++ // Get demod type. ++ // Note: One can find demod type in MODULE_TYPE enumeration. ++ pDemod->GetDemodType(pDemod, &DemodType); ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Ask demod if it is connected to I2C bus. ++ // Note: If Answer is YES, demod is connected to I2C bus. ++ // If Answer is NO, demod is not connected to I2C bus. ++ pDemod->IsConnectedToI2c(pDemod, &Answer); ++ ++ ++ // Get demod parameters. (IF frequency and spectrum mode) ++ pDemod->GetIfFreqHz(pDemod, &IfFreqHz); ++ pDemod->GetSpectrumMode(pDemod, &SpectrumMode); ++ ++ ++ // Get demod AGC value. ++ // Note: The range of RF AGC and IF AGC value is -8192 ~ 8191. ++ // The range of digital AGC value is 0 ~ 255. ++ pDemod->GetRfAgc(pDemod, &RfAgc); ++ pDemod->GetIfAgc(pDemod, &IfAgc); ++ pDemod->GetDiAgc(pDemod, &DiAgc); ++ ++ ++ // Get demod lock status. ++ // Note: If Answer is YES, it is locked. ++ // If Answer is NO, it is not locked. ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz); ++ ++ ++ // Get BER. ++ pDemod->GetBer(pDemod, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get PER. ++ pDemod->GetPer(pDemod, &PerNum, &PerDen); ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pDemod->GetSignalStrength(pDemod, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pDemod->GetSignalQuality(pDemod, &SignalQuality); ++ ++ ++ // Get signal information. ++ // Note: One can find signal information definitions in the enumerations as follows: ++ // 1. DTMB_CARRIER_MODE ++ // 2. DTMB_PN_MODE ++ // 3. DTMB_QAM_MODE ++ // 4. DTMB_CODE_RATE_MODE ++ // 5. DTMB_TIME_INTERLEAVER_MODE ++ pDemod->GetCarrierMode(pDemod, &CarrierMode); ++ pDemod->GetPnMode(pDemod, &PnMode); ++ pDemod->GetQamMode(pDemod, &QamMode); ++ pDemod->GetCodeRateMode(pDemod, &CodeRateMode); ++ pDemod->GetTimeInterleaverMode(pDemod, &TimeInterleaverMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Page register address ++#define DTMB_DEMOD_PAGE_REG_ADDR 0x0 ++ ++ ++// Carrier mode ++enum DTMB_CARRIER_MODE ++{ ++ DTMB_CARRIER_SINGLE, ++ DTMB_CARRIER_MULTI, ++}; ++ ++ ++// PN mode ++enum DTMB_PN_MODE ++{ ++ DTMB_PN_420, ++ DTMB_PN_595, ++ DTMB_PN_945, ++}; ++ ++ ++// QAM mode ++enum DTMB_QAM_MODE ++{ ++ DTMB_QAM_4QAM_NR, ++ DTMB_QAM_4QAM, ++ DTMB_QAM_16QAM, ++ DTMB_QAM_32QAM, ++ DTMB_QAM_64QAM, ++}; ++#define DTMB_QAM_UNKNOWN -1 ++ ++ ++// Code rate mode ++enum DTMB_CODE_RATE_MODE ++{ ++ DTMB_CODE_RATE_0P4, ++ DTMB_CODE_RATE_0P6, ++ DTMB_CODE_RATE_0P8, ++}; ++#define DTMB_CODE_RATE_UNKNOWN -1 ++ ++ ++// Time interleaver mode ++enum DTMB_TIME_INTERLEAVER_MODE ++{ ++ DTMB_TIME_INTERLEAVER_240, ++ DTMB_TIME_INTERLEAVER_720, ++}; ++#define DTMB_TIME_INTERLEAVER_UNKNOWN -1 ++ ++ ++ ++ ++ ++// Register entry definitions ++ ++// Register entry for 8-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Primary register entry for 8-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_PRIMARY_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Register entry for 16-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Primary register entry for 16-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_PRIMARY_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++ ++ ++// Register table dependence ++ ++// Demod register bit names ++enum DTMB_REG_BIT_NAME ++{ ++ // Software reset ++ DTMB_SOFT_RST_N, ++ ++ // Tuner I2C forwording ++ DTMB_I2CT_EN_CTRL, ++ ++ // Chip ID ++ DTMB_CHIP_ID, ++ ++ ++ // IF setting ++ DTMB_EN_SP_INV, ++ DTMB_EN_DCR, ++ DTMB_BBIN_EN, ++ DTMB_IFFREQ, ++ ++ // AGC setting ++ DTMB_AGC_DRIVE_LV, // for RTL2836B DTMB only ++ DTMB_Z_AGC, // for RTL2836B DTMB only ++ DTMB_EN_PGA_MODE, // for RTL2836B DTMB only ++ DTMB_TARGET_VAL, ++ DTMB_AAGC_LOOPGAIN1, // for RTL2836B DTMB only ++ DTMB_POLAR_IFAGC, // for RTL2836B DTMB only ++ DTMB_POLAR_RFAGC, // for RTL2836B DTMB only ++ DTMB_INTEGRAL_CNT_LEN, // for RTL2836B DTMB only ++ DTMB_AAGC_LOCK_PGA_HIT_LEN, // for RTL2836B DTMB only ++ DTMB_THD_LOCK_UP, // for RTL2836B DTMB only ++ DTMB_THD_LOCK_DW, // for RTL2836B DTMB only ++ DTMB_THD_UP1, // for RTL2836B DTMB only ++ DTMB_THD_DW1, // for RTL2836B DTMB only ++ DTMB_THD_UP2, // for RTL2836B DTMB only ++ DTMB_THD_DW2, // for RTL2836B DTMB only ++ DTMB_GAIN_PULSE_SPACE_LEN, // for RTL2836B DTMB only ++ DTMB_GAIN_PULSE_HOLD_LEN, // for RTL2836B DTMB only ++ DTMB_GAIN_STEP_SUM_UP_THD, // for RTL2836B DTMB only ++ DTMB_GAIN_STEP_SUM_DW_THD, // for RTL2836B DTMB only ++ ++ ++ // TS interface ++ DTMB_SERIAL, ++ DTMB_CDIV_PH0, ++ DTMB_CDIV_PH1, ++ ++ ++ // Signal lock status ++ DTMB_TPS_LOCK, ++ DTMB_PN_PEAK_EXIST, ++ ++ // FSM ++ DTMB_FSM_STATE_R, ++ ++ // Performance measurement ++ DTMB_RO_PKT_ERR_RATE, ++ DTMB_EST_SNR, ++ DTMB_RO_LDPC_BER, ++ ++ // AGC ++ DTMB_GAIN_OUT_R, ++ DTMB_RF_AGC_VAL, ++ DTMB_IF_AGC_VAL, ++ ++ // TR and CR ++ DTMB_TR_OUT_R, ++ DTMB_SFOAQ_OUT_R, ++ DTMB_CFO_EST_R, ++ ++ // Signal information ++ DTMB_EST_CARRIER, ++ DTMB_RX_MODE_R, ++ DTMB_USE_TPS, ++ ++ // GPIO ++ DTMB_DMBT_GPIOA_OE, // For RTL2836B only ++ DTMB_DMBT_GPIOB_OE, // For RTL2836B only ++ DTMB_DMBT_OPT_GPIOA_SEL, // For RTL2836B only ++ DTMB_DMBT_OPT_GPIOB_SEL, // For RTL2836B only ++ DTMB_GPIOA_SEL, // For RTL2836B only ++ DTMB_GPIOB_SEL, // For RTL2836B only ++ ++ // AD7 ++ DTMB_RSSI_R, // For RTL2836B only ++ DTMB_AV_SET7, // For RTL2836B only ++ DTMB_IBX, // For RTL2836B only ++ DTMB_POW_AD7, // For RTL2836B only ++ DTMB_VICM_SET, // For RTL2836B only ++ DTMB_VRC, // For RTL2836B only ++ DTMB_ATT_AD7, // For RTL2836B only ++ ++ // Diversity ++ DTMB_DIV_EN, // For RTL2836B DTMB only ++ DTMB_DIV_MODE, // For RTL2836B DTMB only ++ DTMB_DIV_RX_CLK_XOR, // For RTL2836B DTMB only ++ ++ // Item terminator ++ DTMB_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++ ++// Register table length definitions ++#define DTMB_REG_TABLE_LEN_MAX DTMB_REG_BIT_NAME_ITEM_TERMINATOR ++ ++ ++ ++ ++ ++// DTMB demod module pre-definition ++typedef struct DTMB_DEMOD_MODULE_TAG DTMB_DEMOD_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register page setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_PAGE() to set demod register page. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] PageNo Page number ++ ++ ++@retval FUNCTION_SUCCESS Set register page successfully with page number. ++@retval FUNCTION_ERROR Set register page unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_PAGE() with the corresponding function. ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register page with page number 2. ++ pDemod->SetRegPage(pDemod, 2); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register byte setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_BYTES() to set demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bytes successfully with writing bytes. ++@retval FUNCTION_ERROR Set demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_SET_REG_BYTES(). ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_GET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char WritingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bytes (page 1, address 0x17 ~ 0x1b) with 5 writing bytes. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBytes(pDemod, 0x17, WritingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register byte getting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_GET_REG_BYTES() to get demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bytes successfully with reading byte number. ++@retval FUNCTION_ERROR Get demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_GET_REG_BYTES(). ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_SET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char ReadingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bytes (page 1, address 0x17 ~ 0x1b) with reading byte number 5. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBytes(pDemod, 0x17, ReadingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register mask bits setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_MASK_BITS() to set demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register mask bits successfully with writing value. ++@retval FUNCTION_ERROR Set demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_SET_REG_MASK_BITS(). ++ -# The constraints of DTMB_DEMOD_FP_SET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_GET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits (page 1, address {0x18, 0x17} [12:5]) with writing value 0x1d. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegMaskBits(pDemod, 0x17, 12, 5, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x17 0x18 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register mask bits getting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_GET_REG_MASK_BITS() to get demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register mask bits successfully. ++@retval FUNCTION_ERROR Get demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_GET_REG_MASK_BITS(). ++ -# The constraints of DTMB_DEMOD_FP_GET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_SET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits (page 1, address {0x18, 0x17} [12:5]). ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegMaskBits(pDemod, 0x17, 12, 5, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_BITS() to set demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DTMB_DEMOD_FP_SET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_GET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBits(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits getting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_GET_REG_BITS() to get demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DTMB_DEMOD_FP_GET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_SET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBits(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits setting function pointer (with page setting) ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE() to set demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name, page setting, and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits getting function pointer (with page setting) ++ ++Demod upper level functions will use DTMB_DEMOD_FPT_GET_REG_BITS_WITH_PAGE() to get demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and page setting. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->GetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// Demod register access for 8-bit address ++typedef struct ++{ ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE SetRegPage; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES SetRegBytes; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES GetRegBytes; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS SetRegBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS GetRegBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE SetRegBitsWithPage; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE GetRegBitsWithPage; ++} ++DTMB_DEMOD_REG_ACCESS_ADDR_8BIT; ++ ++ ++ ++ ++ ++// Demod register access for 16-bit address ++typedef struct ++{ ++ DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES SetRegBytes; ++ DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES GetRegBytes; ++ DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BITS SetRegBits; ++ DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BITS GetRegBits; ++} ++DTMB_DEMOD_REG_ACCESS_ADDR_16BIT; ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod type getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_DEMOD_TYPE() to get DTMB demod type. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDemodType Pointer to an allocated memory for storing demod type ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_DEMOD_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_GET_DEMOD_TYPE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod I2C device address getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_DEVICE_ADDR() to get DTMB demod I2C device address. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing demod I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get demod device address successfully. ++@retval FUNCTION_ERROR Get demod device address unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_GET_DEVICE_ADDR)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod crystal frequency getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() to get DTMB demod crystal frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrystalFreqHz Pointer to an allocated memory for storing demod crystal frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod crystal frequency successfully. ++@retval FUNCTION_ERROR Get demod crystal frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod I2C bus connection asking function pointer ++ ++One can use DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C() to ask DTMB demod if it is connected to I2C bus. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C() with the corresponding function. ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod software resetting function pointer ++ ++One can use DTMB_DEMOD_FP_SOFTWARE_RESET() to reset DTMB demod by software reset. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod by software reset successfully. ++@retval FUNCTION_ERROR Reset demod by software reset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SOFTWARE_RESET() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_SOFTWARE_RESET)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod initializing function pointer ++ ++One can use DTMB_DEMOD_FP_INITIALIZE() to initialie DTMB demod. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize demod successfully. ++@retval FUNCTION_ERROR Initialize demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_INITIALIZE)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod IF frequency setting function pointer ++ ++One can use DTMB_DEMOD_FP_SET_IF_FREQ_HZ() to set DTMB demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] IfFreqHz IF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod IF frequency successfully. ++@retval FUNCTION_ERROR Set demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_SET_IF_FREQ_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod spectrum mode setting function pointer ++ ++One can use DTMB_DEMOD_FP_SET_SPECTRUM_MODE() to set DTMB demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SpectrumMode Spectrum mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod spectrum mode successfully. ++@retval FUNCTION_ERROR Set demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_SET_SPECTRUM_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod IF frequency getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_IF_FREQ_HZ() to get DTMB demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfFreqHz Pointer to an allocated memory for storing demod IF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF frequency successfully. ++@retval FUNCTION_ERROR Get demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_IF_FREQ_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod spectrum mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SPECTRUM_MODE() to get DTMB demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSpectrumMode Pointer to an allocated memory for storing demod spectrum mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod spectrum mode successfully. ++@retval FUNCTION_ERROR Get demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SPECTRUM_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod signal lock asking function pointer ++ ++One can use DTMB_DEMOD_FP_IS_SIGNAL_LOCKED() to ask DTMB demod if it is signal-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_IS_SIGNAL_LOCKED)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod signal strength getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal strength successfully. ++@retval FUNCTION_ERROR Get demod signal strength unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod signal quality getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal quality successfully. ++@retval FUNCTION_ERROR Get demod signal quality unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SIGNAL_QUALITY)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod BER getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_BER() to get BER. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_BER)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod PER getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_PER() to get PER. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_PER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_PER)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod SNR getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod SNR successfully. ++@retval FUNCTION_ERROR Get demod SNR unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SNR_DB)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod RF AGC getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_RF_AGC() to get DTMB demod RF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pRfAgc Pointer to an allocated memory for storing RF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod RF AGC value successfully. ++@retval FUNCTION_ERROR Get demod RF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_RF_AGC() with the corresponding function. ++ -# The range of RF AGC value is 0 ~ (pow(2, 14) - 1). ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_RF_AGC)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod IF AGC getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_IF_AGC() to get DTMB demod IF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfAgc Pointer to an allocated memory for storing IF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF AGC value successfully. ++@retval FUNCTION_ERROR Get demod IF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_IF_AGC() with the corresponding function. ++ -# The range of IF AGC value is 0 ~ (pow(2, 14) - 1). ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_IF_AGC)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod digital AGC getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_DI_AGC() to get DTMB demod digital AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDiAgc Pointer to an allocated memory for storing digital AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod digital AGC value successfully. ++@retval FUNCTION_ERROR Get demod digital AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_DI_AGC() with the corresponding function. ++ -# The range of digital AGC value is 0 ~ (pow(2, 12) - 1). ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_DI_AGC)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod TR offset getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get demod TR offset successfully. ++@retval FUNCTION_ERROR Get demod TR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_TR_OFFSET_PPM)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod CR offset getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod CR offset successfully. ++@retval FUNCTION_ERROR Get demod CR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_CR_OFFSET_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod carrier mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CARRIER_MODE() to get DTMB demod carrier mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCarrierMode Pointer to an allocated memory for storing demod carrier mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod carrier mode successfully. ++@retval FUNCTION_ERROR Get demod carrier mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CARRIER_MODE() with the corresponding function. ++ ++ ++@see DTMB_CARRIER_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_CARRIER_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCarrierMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod PN mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_PN_MODE() to get DTMB demod PN mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pPnMode Pointer to an allocated memory for storing demod PN mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod PN mode successfully. ++@retval FUNCTION_ERROR Get demod PN mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_PN_MODE() with the corresponding function. ++ ++ ++@see DTMB_PN_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_PN_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pPnMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod QAM mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_QAM_MODE() to get DTMB demod QAM mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pQamMode Pointer to an allocated memory for storing demod QAM mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod QAM mode successfully. ++@retval FUNCTION_ERROR Get demod QAM mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_QAM_MODE() with the corresponding function. ++ ++ ++@see DTMB_QAM_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_QAM_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod code rate mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CODE_RATE_MODE() to get DTMB demod code rate mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCodeRateMode Pointer to an allocated memory for storing demod code rate mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod code rate mode successfully. ++@retval FUNCTION_ERROR Get demod code rate mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CODE_RATE_MODE() with the corresponding function. ++ ++ ++@see DTMB_CODE_RATE_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_CODE_RATE_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCodeRateMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod time interleaver mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE() to get DTMB demod time interleaver mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTimeInterleaverMode Pointer to an allocated memory for storing demod time interleaver mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod time interleaver mode successfully. ++@retval FUNCTION_ERROR Get demod time interleaver mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE() with the corresponding function. ++ ++ ++@see DTMB_TIME_INTERLEAVER_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pTimeInterleaverMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod updating function pointer ++ ++One can use DTMB_DEMOD_FP_UPDATE_FUNCTION() to update demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod setting successfully. ++@retval FUNCTION_ERROR Update demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_UPDATE_FUNCTION)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod reseting function pointer ++ ++One can use DTMB_DEMOD_FP_RESET_FUNCTION() to reset demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod setting successfully. ++@retval FUNCTION_ERROR Reset demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_RESET_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_RESET_FUNCTION)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/// RTL2836 extra module ++typedef struct RTL2836_EXTRA_MODULE_TAG RTL2836_EXTRA_MODULE; ++struct RTL2836_EXTRA_MODULE_TAG ++{ ++ // RTL2836 update procedure enabling status ++ int IsFunc1Enabled; ++ int IsFunc2Enabled; ++ ++ // RTL2836 update Function 1 variables ++ int Func1CntThd; ++ int Func1Cnt; ++ ++ // RTL2836 update Function 2 variables ++ int Func2SignalModePrevious; ++}; ++ ++ ++ ++ ++ ++/// DTMB demod module structure ++struct DTMB_DEMOD_MODULE_TAG ++{ ++ ++ // Private variables ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ int TsInterfaceMode; ++ int DiversityMode; ++ ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int IsIfFreqHzSet; ++ int IsSpectrumModeSet; ++ ++ unsigned long CurrentPageNo; // temp, because page register is write-only. ++ ++ union ///< Demod extra module used by driving module ++ { ++ RTL2836_EXTRA_MODULE Rtl2836; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ // Demod register table ++ union ++ { ++ DTMB_REG_ENTRY_ADDR_8BIT Addr8Bit[DTMB_REG_TABLE_LEN_MAX]; ++ DTMB_REG_ENTRY_ADDR_16BIT Addr16Bit[DTMB_REG_TABLE_LEN_MAX]; ++ } ++ RegTable; ++ ++ ++ // Demod I2C function pointers ++ union ++ { ++ DTMB_DEMOD_REG_ACCESS_ADDR_8BIT Addr8Bit; ++ DTMB_DEMOD_REG_ACCESS_ADDR_16BIT Addr16Bit; ++ } ++ RegAccess; ++ ++ ++ // Demod manipulating function pointers ++ DTMB_DEMOD_FP_GET_DEMOD_TYPE GetDemodType; ++ DTMB_DEMOD_FP_GET_DEVICE_ADDR GetDeviceAddr; ++ DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ GetCrystalFreqHz; ++ ++ DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C IsConnectedToI2c; ++ ++ DTMB_DEMOD_FP_SOFTWARE_RESET SoftwareReset; ++ ++ DTMB_DEMOD_FP_INITIALIZE Initialize; ++ DTMB_DEMOD_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ DTMB_DEMOD_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ DTMB_DEMOD_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ DTMB_DEMOD_FP_GET_SPECTRUM_MODE GetSpectrumMode; ++ ++ DTMB_DEMOD_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ ++ DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DTMB_DEMOD_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ ++ DTMB_DEMOD_FP_GET_BER GetBer; ++ DTMB_DEMOD_FP_GET_PER GetPer; ++ DTMB_DEMOD_FP_GET_SNR_DB GetSnrDb; ++ ++ DTMB_DEMOD_FP_GET_RF_AGC GetRfAgc; ++ DTMB_DEMOD_FP_GET_IF_AGC GetIfAgc; ++ DTMB_DEMOD_FP_GET_DI_AGC GetDiAgc; ++ ++ DTMB_DEMOD_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DTMB_DEMOD_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ ++ DTMB_DEMOD_FP_GET_CARRIER_MODE GetCarrierMode; ++ DTMB_DEMOD_FP_GET_PN_MODE GetPnMode; ++ DTMB_DEMOD_FP_GET_QAM_MODE GetQamMode; ++ DTMB_DEMOD_FP_GET_CODE_RATE_MODE GetCodeRateMode; ++ DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE GetTimeInterleaverMode; ++ ++ DTMB_DEMOD_FP_UPDATE_FUNCTION UpdateFunction; ++ DTMB_DEMOD_FP_RESET_FUNCTION ResetFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DTMB demod default I2C functions for 8-bit address ++int ++dtmb_demod_addr_8bit_default_SetRegPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// DTMB demod default I2C functions for 16-bit address ++int ++dtmb_demod_addr_16bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// DTMB demod default manipulating functions ++void ++dtmb_demod_default_GetDemodType( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++void ++dtmb_demod_default_GetDeviceAddr( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++void ++dtmb_demod_default_GetCrystalFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++int ++dtmb_demod_default_GetBandwidthMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ); ++ ++int ++dtmb_demod_default_GetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++dtmb_demod_default_GetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_nim_base.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_nim_base.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_nim_base.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_nim_base.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,545 @@ ++/** ++ ++@file ++ ++@brief DTMB NIM base module definition ++ ++DTMB NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++*/ ++ ++ ++#include "dtmb_nim_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_NIM_TYPE ++ ++*/ ++void ++dtmb_nim_default_GetNimType( ++ DTMB_NIM_MODULE *pNim, ++ int *pNimType ++ ) ++{ ++ // Get NIM type from NIM module. ++ *pNimType = pNim->NimType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++dtmb_nim_default_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_PARAMETERS ++ ++*/ ++int ++dtmb_nim_default_GetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ ++ ++ // Get tuner module. ++ pTuner = pNim->pTuner; ++ ++ ++ // Get tuner RF frequency in Hz. ++ if(pTuner->GetRfFreqHz(pTuner, pRfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_IS_SIGNAL_PRESENT ++ ++*/ ++int ++dtmb_nim_default_IsSignalPresent( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DTMB_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal present check. ++ for(i = 0; i < DTMB_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++dtmb_nim_default_IsSignalLocked( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DTMB_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal lock check. ++ for(i = 0; i < DTMB_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++dtmb_nim_default_GetSignalStrength( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal strength from demod. ++ if(pDemod->GetSignalStrength(pDemod, pSignalStrength) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++dtmb_nim_default_GetSignalQuality( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal quality from demod. ++ if(pDemod->GetSignalQuality(pDemod, pSignalQuality) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_BER ++ ++*/ ++int ++dtmb_nim_default_GetBer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get BER from demod. ++ if(pDemod->GetBer(pDemod, pBerNum, pBerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_PER ++ ++*/ ++int ++dtmb_nim_default_GetPer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get PER from demod. ++ if(pDemod->GetPer(pDemod, pPerNum, pPerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SNR_DB ++ ++*/ ++int ++dtmb_nim_default_GetSnrDb( ++ DTMB_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get SNR in dB from demod. ++ if(pDemod->GetSnrDb(pDemod, pSnrDbNum, pSnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++dtmb_nim_default_GetTrOffsetPpm( ++ DTMB_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TR offset in ppm from demod. ++ if(pDemod->GetTrOffsetPpm(pDemod, pTrOffsetPpm) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++dtmb_nim_default_GetCrOffsetHz( ++ DTMB_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get CR offset in Hz from demod. ++ if(pDemod->GetCrOffsetHz(pDemod, pCrOffsetHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SIGNAL_INFO ++ ++*/ ++int ++dtmb_nim_default_GetSignalInfo( ++ DTMB_NIM_MODULE *pNim, ++ int *pCarrierMode, ++ int *pPnMode, ++ int *pQamMode, ++ int *pCodeRateMode, ++ int *pTimeInterleaverMode ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal information from demod. ++ if(pDemod->GetCarrierMode(pDemod, pCarrierMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetPnMode(pDemod, pPnMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetQamMode(pDemod, pQamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetCodeRateMode(pDemod, pCodeRateMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetTimeInterleaverMode(pDemod, pTimeInterleaverMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++dtmb_nim_default_UpdateFunction( ++ DTMB_NIM_MODULE *pNim ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_nim_base.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_nim_base.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dtmb_nim_base.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dtmb_nim_base.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,936 @@ ++#ifndef __DTMB_NIM_BASE_H ++#define __DTMB_NIM_BASE_H ++ ++/** ++ ++@file ++ ++@brief DTMB NIM base module definition ++ ++DTMB NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ unsigned long RfFreqHz; ++ ++ int Answer; ++ unsigned long SignalStrength, SignalQuality; ++ unsigned long BerNum, BerDen; ++ double Ber; ++ unsigned long PerNum, PerDen; ++ double Per; ++ unsigned long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ long TrOffsetPpm, CrOffsetHz; ++ ++ int CarrierMode; ++ int PnMode; ++ int QamMode; ++ int CodeRateMode; ++ int TimeInterleaverMode; ++ ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ &pNim, ++ &DtmbNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ++ &DemodxExtraModuleMemory, // Employ Demod-X extra module. ++ 0x3e, // The Demod-X I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The Demod-X crystal frequency is 27.0 MHz. ++ ... // Other arguments for Demod-X ++ ++ &TunerxExtraModuleMemory, // Employ Tuner-Y extra module. ++ 0xc0, // The Tuner-Y I2C device address is 0xc0 in 8-bit format. ++ ... // Other arguments for Tuner-Y ++ ); ++ ++ ++ ++ // Get NIM type. ++ // Note: NIM types are defined in the MODULE_TYPE enumeration. ++ pNim->GetNimType(pNim, &NimType); ++ ++ ++ ++ ++ ++ ++ ++ // ==== Initialize NIM and set its parameters ===== ++ ++ // Initialize NIM. ++ pNim->Initialize(pNim); ++ ++ // Set NIM parameters. (RF frequency) ++ // Note: In the example: RF frequency is 666 MHz. ++ RfFreqHz = 666000000; ++ pNim->SetParameters(pNim, RfFreqHz); ++ ++ ++ ++ // Wait 1 second for demod convergence. ++ ++ ++ ++ ++ ++ // ==== Get NIM information ===== ++ ++ // Get NIM parameters. (RF frequency) ++ pNim->GetParameters(pNim, &RfFreqHz); ++ ++ ++ // Get signal present status. ++ // Note: 1. The argument Answer is YES when the NIM module has found DTMB signal in the RF channel. ++ // 2. The argument Answer is NO when the NIM module does not find DTMB signal in the RF channel. ++ // Recommendation: Use the IsSignalPresent() function for channel scan. ++ pNim->IsSignalPresent(pNim, &Answer); ++ ++ // Get signal lock status. ++ // Note: 1. The argument Answer is YES when the NIM module has locked DTMB signal in the RF channel. ++ // At the same time, the NIM module sends TS packets through TS interface hardware pins. ++ // 2. The argument Answer is NO when the NIM module does not lock DTMB signal in the RF channel. ++ // Recommendation: Use the IsSignalLocked() function for signal lock check. ++ pNim->IsSignalLocked(pNim, &Answer); ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pNim->GetSignalStrength(pNim, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pNim->GetSignalQuality(pNim, &SignalQuality); ++ ++ ++ // Get BER. ++ pNim->GetBer(pNim, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get PER. ++ pNim->GetPer(pNim, &PerNum, &PerDen); ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pNim->GetSnrDb(pNim, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pNim->GetTrOffsetPpm(pNim, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pNim->GetCrOffsetHz(pNim, &CrOffsetHz); ++ ++ ++ // Get signal information. ++ // Note: One can find signal information definitions in the enumerations as follows: ++ // 1. DTMB_CARRIER_MODE ++ // 2. DTMB_PN_MODE ++ // 3. DTMB_QAM_MODE ++ // 4. DTMB_CODE_RATE_MODE ++ // 5. DTMB_TIME_INTERLEAVER_MODE ++ pNim->GetSignalInfo(pNim, &CarrierMode, &PnMode, &QamMode, &CodeRateMode, &TimeInterleaverMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++#include "tuner_base.h" ++#include "dtmb_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define DTMB_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT 1 ++#define DTMB_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT 1 ++ ++ ++ ++ ++ ++/// DTMB NIM module pre-definition ++typedef struct DTMB_NIM_MODULE_TAG DTMB_NIM_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod type getting function pointer ++ ++One can use DTMB_NIM_FP_GET_NIM_TYPE() to get DTMB NIM type. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pNimType Pointer to an allocated memory for storing NIM type ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_NIM_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DTMB_NIM_FP_GET_NIM_TYPE)( ++ DTMB_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM initializing function pointer ++ ++One can use DTMB_NIM_FP_INITIALIZE() to initialie DTMB NIM. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize NIM successfully. ++@retval FUNCTION_ERROR Initialize NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_INITIALIZE)( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM parameter setting function pointer ++ ++One can use DTMB_NIM_FP_SET_PARAMETERS() to set DTMB NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set NIM parameters successfully. ++@retval FUNCTION_ERROR Set NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_SET_PARAMETERS() with the corresponding function. ++ ++ ++@see DTMB_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_SET_PARAMETERS)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM parameter getting function pointer ++ ++One can use DTMB_NIM_FP_GET_PARAMETERS() to get DTMB NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pRfFreqHz Pointer to an allocated memory for storing NIM RF frequency in Hz ++@param [out] pBandwidthMode Pointer to an allocated memory for storing NIM bandwidth mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM parameters successfully. ++@retval FUNCTION_ERROR Get NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_PARAMETERS() with the corresponding function. ++ ++ ++@see DTMB_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_PARAMETERS)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal present asking function pointer ++ ++One can use DTMB_NIM_FP_IS_SIGNAL_PRESENT() to ask DTMB NIM if signal is present. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal present asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal present asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_IS_SIGNAL_PRESENT() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_IS_SIGNAL_PRESENT)( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal lock asking function pointer ++ ++One can use DTMB_NIM_FP_IS_SIGNAL_LOCKED() to ask DTMB NIM if signal is locked. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_IS_SIGNAL_LOCKED)( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal strength getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal strength successfully. ++@retval FUNCTION_ERROR Get NIM signal strength unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SIGNAL_STRENGTH)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal quality getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal quality successfully. ++@retval FUNCTION_ERROR Get NIM signal quality unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SIGNAL_QUALITY)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM BER value getting function pointer ++ ++One can use DTMB_NIM_FP_GET_BER() to get BER. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM BER value successfully. ++@retval FUNCTION_ERROR Get NIM BER value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_BER)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM PER value getting function pointer ++ ++One can use DTMB_NIM_FP_GET_PER() to get PER. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM PER value successfully. ++@retval FUNCTION_ERROR Get NIM PER value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_PER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_PER)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM SNR getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM SNR successfully. ++@retval FUNCTION_ERROR Get NIM SNR unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SNR_DB)( ++ DTMB_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM TR offset getting function pointer ++ ++One can use DTMB_NIM_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TR offset successfully. ++@retval FUNCTION_ERROR Get NIM TR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_TR_OFFSET_PPM)( ++ DTMB_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM CR offset getting function pointer ++ ++One can use DTMB_NIM_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get NIM CR offset successfully. ++@retval FUNCTION_ERROR Get NIM CR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_CR_OFFSET_HZ)( ++ DTMB_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal information getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SIGNAL_INFO() to get signal information. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCarrierMode Pointer to an allocated memory for storing demod carrier mode ++@param [out] pPnMode Pointer to an allocated memory for storing demod PN mode ++@param [out] pQamMode Pointer to an allocated memory for storing demod QAM mode ++@param [out] pCodeRateMode Pointer to an allocated memory for storing demod code rate mode ++@param [out] pTimeInterleaverMode Pointer to an allocated memory for storing demod time interleaver mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal information successfully. ++@retval FUNCTION_ERROR Get NIM signal information unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SIGNAL_INFO() with the corresponding function. ++ ++ ++@see DTMB_CARRIER_MODE, DTMB_PN_MODE, DTMB_QAM_MODE, DTMB_CODE_RATE_MODE, DTMB_TIME_INTERLEAVER_MODE ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SIGNAL_INFO)( ++ DTMB_NIM_MODULE *pNim, ++ int *pCarrierMode, ++ int *pPnMode, ++ int *pQamMode, ++ int *pCodeRateMode, ++ int *pTimeInterleaverMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM updating function pointer ++ ++One can use DTMB_NIM_FP_UPDATE_FUNCTION() to update NIM register setting. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update NIM setting successfully. ++@retval FUNCTION_ERROR Update NIM setting unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ ... ++ ); ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pNim->UpdateFunction(pNim); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_UPDATE_FUNCTION)( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// RTL2836 E4000 extra module ++typedef struct RTL2836_E4000_EXTRA_MODULE_TAG RTL2836_E4000_EXTRA_MODULE; ++struct RTL2836_E4000_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2836B DTMB E4000 extra module ++typedef struct RTL2836B_DTMB_E4000_EXTRA_MODULE_TAG RTL2836B_DTMB_E4000_EXTRA_MODULE; ++struct RTL2836B_DTMB_E4000_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2836B DTMB FC0012 extra module ++typedef struct RTL2836B_DTMB_FC0012_EXTRA_MODULE_TAG RTL2836B_DTMB_FC0012_EXTRA_MODULE; ++struct RTL2836B_DTMB_FC0012_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++}; ++ ++ ++ ++ ++ ++/// DTMB NIM module structure ++struct DTMB_NIM_MODULE_TAG ++{ ++ // Private variables ++ int NimType; ++ ++ union ///< NIM extra module used by driving module ++ { ++ RTL2836_E4000_EXTRA_MODULE Rtl2836E4000; ++ RTL2836B_DTMB_E4000_EXTRA_MODULE Rtl2836bDtmbE4000; ++ RTL2836B_DTMB_FC0012_EXTRA_MODULE Rtl2836bDtmbFc0012; ++ } ++ Extra; ++ ++ ++ // Modules ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module pointer ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ///< Base interface module memory ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module pointer ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ///< I2C bridge module memory ++ ++ TUNER_MODULE *pTuner; ///< Tuner module pointer ++ TUNER_MODULE TunerModuleMemory; ///< Tuner module memory ++ ++ DTMB_DEMOD_MODULE *pDemod; ///< DTMB demod module pointer ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ///< DTMB demod module memory ++ ++ ++ // NIM manipulating functions ++ DTMB_NIM_FP_GET_NIM_TYPE GetNimType; ++ DTMB_NIM_FP_INITIALIZE Initialize; ++ DTMB_NIM_FP_SET_PARAMETERS SetParameters; ++ DTMB_NIM_FP_GET_PARAMETERS GetParameters; ++ DTMB_NIM_FP_IS_SIGNAL_PRESENT IsSignalPresent; ++ DTMB_NIM_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ DTMB_NIM_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DTMB_NIM_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ DTMB_NIM_FP_GET_BER GetBer; ++ DTMB_NIM_FP_GET_PER GetPer; ++ DTMB_NIM_FP_GET_SNR_DB GetSnrDb; ++ DTMB_NIM_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DTMB_NIM_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ DTMB_NIM_FP_GET_SIGNAL_INFO GetSignalInfo; ++ DTMB_NIM_FP_UPDATE_FUNCTION UpdateFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DTMB NIM default manipulaing functions ++void ++dtmb_nim_default_GetNimType( ++ DTMB_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++int ++dtmb_nim_default_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++int ++dtmb_nim_default_GetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz ++ ); ++ ++int ++dtmb_nim_default_IsSignalPresent( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dtmb_nim_default_IsSignalLocked( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dtmb_nim_default_GetSignalStrength( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++dtmb_nim_default_GetSignalQuality( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++dtmb_nim_default_GetBer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++dtmb_nim_default_GetPer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++dtmb_nim_default_GetSnrDb( ++ DTMB_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++dtmb_nim_default_GetTrOffsetPpm( ++ DTMB_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++int ++dtmb_nim_default_GetCrOffsetHz( ++ DTMB_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++int ++dtmb_nim_default_GetSignalInfo( ++ DTMB_NIM_MODULE *pNim, ++ int *pCarrierMode, ++ int *pPnMode, ++ int *pQamMode, ++ int *pCodeRateMode, ++ int *pTimeInterleaverMode ++ ); ++ ++int ++dtmb_nim_default_UpdateFunction( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_demod_base.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_demod_base.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_demod_base.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_demod_base.c 2010-10-27 08:17:24.000000000 +0200 +@@ -0,0 +1,816 @@ ++/** ++ ++@file ++ ++@brief DVB-T demod default function definition ++ ++DVB-T demod default functions. ++ ++*/ ++ ++#include "dvbt_demod_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE ++ ++*/ ++int ++dvbt_demod_default_SetRegPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register page with page number. ++ // Note: The I2C format of demod register page setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + DVBT_DEMOD_PAGE_REG_ADDR + PageNo + stop_bit ++ WritingBytes[0] = DVBT_DEMOD_PAGE_REG_ADDR; ++ WritingBytes[1] = (unsigned char)PageNo; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ if( mutex_lock_interruptible(&d->usb_mutex) ) goto error; ++ ++ pDemod->CurrentPageNo = PageNo; ++ ++ mutex_unlock(&d->usb_mutex); ++ ++ return FUNCTION_SUCCESS; ++ ++error: ++ return FUNCTION_ERROR; ++ ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++dvbt_demod_default_SetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned char WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[j] = pWritingBytes[i + j]; ++ ++ // Set demod register bytes with writing buffer. ++ if(write_demod_register( d, DeviceAddr, pDemod->CurrentPageNo, RegWritingAddr, WritingBuffer, WritingByteNum )) goto error; ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++error: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++dvbt_demod_default_GetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned char DeviceAddr; ++ unsigned char ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, pDemod->CurrentPageNo, RegReadingAddr, &pReadingBytes[i], ReadingByteNum)) goto error; ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++error: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++dvbt_demod_default_SetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value MSB. ++ // Put upper address byte on value LSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * (ByteNum - i -1)); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value MSB. ++ // Pick up upper address byte from value LSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * (ByteNum - i -1))) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++dvbt_demod_default_GetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value MSB. ++ // Put upper address byte on value LSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * (ByteNum - i -1)); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++dvbt_demod_default_SetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable[RegBitName].Msb; ++ Lsb = pDemod->RegTable[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++dvbt_demod_default_GetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable[RegBitName].Msb; ++ Lsb = pDemod->RegTable[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dvbt_demod_default_SetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set register mask bits with register bit name key. ++ if(pDemod->SetRegBits(pDemod, RegBitName, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dvbt_demod_default_GetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register mask bits with register bit name key. ++ if(pDemod->GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_DEMOD_TYPE ++ ++*/ ++void ++dvbt_demod_default_GetDemodType( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ) ++{ ++ // Get demod type from demod module. ++ *pDemodType = pDemod->DemodType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++dvbt_demod_default_GetDeviceAddr( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get demod I2C device address from demod module. ++ *pDeviceAddr = pDemod->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ ++ ++*/ ++void ++dvbt_demod_default_GetCrystalFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ) ++{ ++ // Get demod crystal frequency in Hz from demod module. ++ *pCrystalFreqHz = pDemod->CrystalFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_BANDWIDTH_MODE ++ ++*/ ++int ++dvbt_demod_default_GetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ) ++{ ++ // Get demod bandwidth mode from demod module. ++ if(pDemod->IsBandwidthModeSet != YES) ++ goto error_status_get_demod_bandwidth_mode; ++ ++ *pBandwidthMode = pDemod->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_IF_FREQ_HZ ++ ++*/ ++int ++dvbt_demod_default_GetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ // Get demod IF frequency in Hz from demod module. ++ if(pDemod->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pDemod->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SPECTRUM_MODE ++ ++*/ ++int ++dvbt_demod_default_GetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ) ++{ ++ // Get demod spectrum mode from demod module. ++ if(pDemod->IsSpectrumModeSet != YES) ++ goto error_status_get_demod_spectrum_mode; ++ ++ *pSpectrumMode = pDemod->SpectrumMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_spectrum_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_demod_base.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_demod_base.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_demod_base.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_demod_base.h 2010-10-12 19:35:18.000000000 +0200 +@@ -0,0 +1,2722 @@ ++#ifndef __DVBT_DEMOD_BASE_H ++#define __DVBT_DEMOD_BASE_H ++ ++/** ++ ++@file ++ ++@brief DVB-T demod base module definition ++ ++DVB-T demod base module definitions contains demod module structure, demod funciton pointers, and demod definitions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_xxx.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ int BandwidthMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ ++ long RfAgc, IfAgc; ++ unsigned char DiAgc; ++ ++ int Answer; ++ long TrOffsetPpm, CrOffsetHz; ++ unsigned long BerNum, BerDen; ++ double Ber; ++ long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ unsigned long SignalStrength, SignalQuality; ++ ++ int Constellation; ++ int Hierarchy; ++ int CodeRateLp; ++ int CodeRateHp; ++ int GuardInterval; ++ int FftMode; ++ ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, // Set maximum I2C reading byte number with 9. ++ 8, // Set maximum I2C writing byte number with 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ); ++ ++ ++ // Build DVB-T demod XXX module. ++ BuildXxxModule( ++ &pDemod, ++ &DvbtDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x20, // Demod I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Demod crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // Demod TS interface mode is serial. ++ ... // Other arguments by each demod module ++ ); ++ ++ ++ ++ ++ ++ // ==== Initialize DVB-T demod and set its parameters ===== ++ ++ // Initialize demod. ++ pDemod->Initialize(pDemod); ++ ++ ++ // Set demod parameters. (bandwidth mode, IF frequency, spectrum mode) ++ // Note: In the example: ++ // 1. Bandwidth mode is 8 MHz. ++ // 2. IF frequency is 36.125 MHz. ++ // 3. Spectrum mode is SPECTRUM_INVERSE. ++ BandwidthMode = DVBT_BANDWIDTH_8MHZ; ++ IfFreqHz = IF_FREQ_36125000HZ; ++ SpectrumMode = SPECTRUM_INVERSE; ++ ++ pDemod->SetBandwidthMode(pDemod, BandwidthMode); ++ pDemod->SetIfFreqHz(pDemod, IfFreqHz); ++ pDemod->SetSpectrumMode(pDemod, SpectrumMode); ++ ++ ++ // Need to set tuner before demod software reset. ++ // The order to set demod and tuner is not important. ++ // Note: One can use "pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1);" ++ // for tuner I2C command forwarding. ++ ++ ++ // Reset demod by software reset. ++ pDemod->SoftwareReset(pDemod); ++ ++ ++ // Wait maximum 1000 ms for demod converge. ++ for(i = 0; i < 25; i++) ++ { ++ // Wait 40 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 40); ++ ++ // Check signal lock status. ++ // Note: If Answer is YES, signal is locked. ++ // If Answer is NO, signal is not locked. ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ if(Answer == YES) ++ { ++ // Signal is locked. ++ break; ++ } ++ } ++ ++ ++ ++ ++ ++ // ==== Get DVB-T demod information ===== ++ ++ // Get demod type. ++ // Note: One can find demod type in MODULE_TYPE enumeration. ++ pDemod->GetDemodType(pDemod, &DemodType); ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Ask demod if it is connected to I2C bus. ++ // Note: If Answer is YES, demod is connected to I2C bus. ++ // If Answer is NO, demod is not connected to I2C bus. ++ pDemod->IsConnectedToI2c(pDemod, &Answer); ++ ++ ++ // Get demod parameters. (bandwidth mode, IF frequency, spectrum mode) ++ pDemod->GetBandwidthMode(pDemod, &BandwidthMode); ++ pDemod->GetIfFreqHz(pDemod, &IfFreqHz); ++ pDemod->GetSpectrumMode(pDemod, &SpectrumMode); ++ ++ ++ // Get demod AGC value. ++ // Note: The range of RF AGC and IF AGC value is -8192 ~ 8191. ++ // The range of digital AGC value is 0 ~ 255. ++ pDemod->GetRfAgc(pDemod, &RfAgc); ++ pDemod->GetIfAgc(pDemod, &IfAgc); ++ pDemod->GetDiAgc(pDemod, &DiAgc); ++ ++ ++ // Get demod lock status. ++ // Note: If Answer is YES, it is locked. ++ // If Answer is NO, it is not locked. ++ pDemod->IsTpsLocked(pDemod, &Answer); ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz); ++ ++ ++ // Get BER. ++ pDemod->GetBer(pDemod, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get SNR in dB. ++ pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pDemod->GetSignalStrength(pDemod, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pDemod->GetSignalQuality(pDemod, &SignalQuality); ++ ++ ++ // Get TPS information. ++ // Note: One can find TPS information definitions in the enumerations as follows: ++ // 1. DVBT_CONSTELLATION_MODE ++ // 2. DVBT_HIERARCHY_MODE ++ // 3. DVBT_CODE_RATE_MODE (for low-priority and high-priority code rate) ++ // 4. DVBT_GUARD_INTERVAL_MODE ++ // 5. DVBT_FFT_MODE_MODE ++ pDemod->GetConstellation(pDemod, &Constellation); ++ pDemod->GetHierarchy(pDemod, &Hierarchy); ++ pDemod->GetCodeRateLp(pDemod, &CodeRateLp); ++ pDemod->GetCodeRateHp(pDemod, &CodeRateHp); ++ pDemod->GetGuardInterval(pDemod, &GuardInterval); ++ pDemod->GetFftMode(pDemod, &FftMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Page register address ++#define DVBT_DEMOD_PAGE_REG_ADDR 0x00 ++ ++ ++// Bandwidth modes ++#define DVBT_BANDWIDTH_NONE -1 ++enum DVBT_BANDWIDTH_MODE ++{ ++ DVBT_BANDWIDTH_6MHZ, ++ DVBT_BANDWIDTH_7MHZ, ++ DVBT_BANDWIDTH_8MHZ, ++}; ++#define DVBT_BANDWIDTH_MODE_NUM 3 ++ ++ ++// Constellation ++enum DVBT_CONSTELLATION_MODE ++{ ++ DVBT_CONSTELLATION_QPSK, ++ DVBT_CONSTELLATION_16QAM, ++ DVBT_CONSTELLATION_64QAM, ++}; ++#define DVBT_CONSTELLATION_NUM 3 ++ ++ ++// Hierarchy ++enum DVBT_HIERARCHY_MODE ++{ ++ DVBT_HIERARCHY_NONE, ++ DVBT_HIERARCHY_ALPHA_1, ++ DVBT_HIERARCHY_ALPHA_2, ++ DVBT_HIERARCHY_ALPHA_4, ++}; ++#define DVBT_HIERARCHY_NUM 4 ++ ++ ++// Code rate ++enum DVBT_CODE_RATE_MODE ++{ ++ DVBT_CODE_RATE_1_OVER_2, ++ DVBT_CODE_RATE_2_OVER_3, ++ DVBT_CODE_RATE_3_OVER_4, ++ DVBT_CODE_RATE_5_OVER_6, ++ DVBT_CODE_RATE_7_OVER_8, ++}; ++#define DVBT_CODE_RATE_NUM 5 ++ ++ ++// Guard interval ++enum DVBT_GUARD_INTERVAL_MODE ++{ ++ DVBT_GUARD_INTERVAL_1_OVER_32, ++ DVBT_GUARD_INTERVAL_1_OVER_16, ++ DVBT_GUARD_INTERVAL_1_OVER_8, ++ DVBT_GUARD_INTERVAL_1_OVER_4, ++}; ++#define DVBT_GUARD_INTERVAL_NUM 4 ++ ++ ++// FFT mode ++enum DVBT_FFT_MODE_MODE ++{ ++ DVBT_FFT_MODE_2K, ++ DVBT_FFT_MODE_8K, ++}; ++#define DVBT_FFT_MODE_NUM 2 ++ ++ ++ ++ ++ ++// Register entry definitions ++ ++// Register entry ++typedef struct ++{ ++ int IsAvailable; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DVBT_REG_ENTRY; ++ ++ ++ ++// Primary register entry ++typedef struct ++{ ++ int RegBitName; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DVBT_PRIMARY_REG_ENTRY; ++ ++ ++ ++ ++ ++// Register table dependence ++ ++// Demod register bit names ++enum DVBT_REG_BIT_NAME ++{ ++ // Software reset register ++ DVBT_SOFT_RST, ++ ++ // Tuner I2C forwording register ++ DVBT_IIC_REPEAT, ++ ++ ++ // Registers for initializing ++ DVBT_TR_WAIT_MIN_8K, ++ DVBT_RSD_BER_FAIL_VAL, ++ DVBT_EN_BK_TRK, ++ DVBT_REG_PI, ++ ++ DVBT_REG_PFREQ_1_0, // For RTL2830 only ++ DVBT_PD_DA8, // For RTL2830 only ++ DVBT_LOCK_TH, // For RTL2830 only ++ DVBT_BER_PASS_SCAL, // For RTL2830 only ++ DVBT_CE_FFSM_BYPASS, // For RTL2830 only ++ DVBT_ALPHAIIR_N, // For RTL2830 only ++ DVBT_ALPHAIIR_DIF, // For RTL2830 only ++ DVBT_EN_TRK_SPAN, // For RTL2830 only ++ DVBT_LOCK_TH_LEN, // For RTL2830 only ++ DVBT_CCI_THRE, // For RTL2830 only ++ DVBT_CCI_MON_SCAL, // For RTL2830 only ++ DVBT_CCI_M0, // For RTL2830 only ++ DVBT_CCI_M1, // For RTL2830 only ++ DVBT_CCI_M2, // For RTL2830 only ++ DVBT_CCI_M3, // For RTL2830 only ++ DVBT_SPEC_INIT_0, // For RTL2830 only ++ DVBT_SPEC_INIT_1, // For RTL2830 only ++ DVBT_SPEC_INIT_2, // For RTL2830 only ++ ++ DVBT_AD_EN_REG, // For RTL2832 only ++ DVBT_AD_EN_REG1, // For RTL2832 only ++ DVBT_EN_BBIN, // For RTL2832 only ++ DVBT_MGD_THD0, // For RTL2832 only ++ DVBT_MGD_THD1, // For RTL2832 only ++ DVBT_MGD_THD2, // For RTL2832 only ++ DVBT_MGD_THD3, // For RTL2832 only ++ DVBT_MGD_THD4, // For RTL2832 only ++ DVBT_MGD_THD5, // For RTL2832 only ++ DVBT_MGD_THD6, // For RTL2832 only ++ DVBT_MGD_THD7, // For RTL2832 only ++ DVBT_EN_CACQ_NOTCH, // For RTL2832 only ++ DVBT_AD_AV_REF, // For RTL2832 only ++ DVBT_PIP_ON, // For RTL2832 only ++ DVBT_SCALE1_B92, // For RTL2832 only ++ DVBT_SCALE1_B93, // For RTL2832 only ++ DVBT_SCALE1_BA7, // For RTL2832 only ++ DVBT_SCALE1_BA9, // For RTL2832 only ++ DVBT_SCALE1_BAA, // For RTL2832 only ++ DVBT_SCALE1_BAB, // For RTL2832 only ++ DVBT_SCALE1_BAC, // For RTL2832 only ++ DVBT_SCALE1_BB0, // For RTL2832 only ++ DVBT_SCALE1_BB1, // For RTL2832 only ++ DVBT_KB_P1, // For RTL2832 only ++ DVBT_KB_P2, // For RTL2832 only ++ DVBT_KB_P3, // For RTL2832 only ++ DVBT_OPT_ADC_IQ, // For RTL2832 only ++ DVBT_AD_AVI, // For RTL2832 only ++ DVBT_AD_AVQ, // For RTL2832 only ++ DVBT_K1_CR_STEP12, // For RTL2832 only ++ ++ // Registers for initializing according to mode ++ DVBT_TRK_KS_P2, ++ DVBT_TRK_KS_I2, ++ DVBT_TR_THD_SET2, ++ DVBT_TRK_KC_P2, ++ DVBT_TRK_KC_I2, ++ DVBT_CR_THD_SET2, ++ ++ // Registers for IF setting ++ DVBT_PSET_IFFREQ, ++ DVBT_SPEC_INV, ++ ++ ++ // Registers for bandwidth programming ++ DVBT_BW_INDEX, // For RTL2830 only ++ ++ DVBT_RSAMP_RATIO, // For RTL2832 only ++ DVBT_CFREQ_OFF_RATIO, // For RTL2832 only ++ ++ ++ // FSM stage register ++ DVBT_FSM_STAGE, ++ ++ // TPS content registers ++ DVBT_RX_CONSTEL, ++ DVBT_RX_HIER, ++ DVBT_RX_C_RATE_LP, ++ DVBT_RX_C_RATE_HP, ++ DVBT_GI_IDX, ++ DVBT_FFT_MODE_IDX, ++ ++ // Performance measurement registers ++ DVBT_RSD_BER_EST, ++ DVBT_CE_EST_EVM, ++ ++ // AGC registers ++ DVBT_RF_AGC_VAL, ++ DVBT_IF_AGC_VAL, ++ DVBT_DAGC_VAL, ++ ++ // TR offset and CR offset registers ++ DVBT_SFREQ_OFF, ++ DVBT_CFREQ_OFF, ++ ++ ++ // AGC relative registers ++ DVBT_POLAR_RF_AGC, ++ DVBT_POLAR_IF_AGC, ++ DVBT_AAGC_HOLD, ++ DVBT_EN_RF_AGC, ++ DVBT_EN_IF_AGC, ++ DVBT_IF_AGC_MIN, ++ DVBT_IF_AGC_MAX, ++ DVBT_RF_AGC_MIN, ++ DVBT_RF_AGC_MAX, ++ DVBT_IF_AGC_MAN, ++ DVBT_IF_AGC_MAN_VAL, ++ DVBT_RF_AGC_MAN, ++ DVBT_RF_AGC_MAN_VAL, ++ DVBT_DAGC_TRG_VAL, ++ ++ DVBT_AGC_TARG_VAL, // For RTL2830 only ++ DVBT_LOOP_GAIN_3_0, // For RTL2830 only ++ DVBT_LOOP_GAIN_4, // For RTL2830 only ++ DVBT_VTOP, // For RTL2830 only ++ DVBT_KRF, // For RTL2830 only ++ ++ DVBT_AGC_TARG_VAL_0, // For RTL2832 only ++ DVBT_AGC_TARG_VAL_8_1, // For RTL2832 only ++ DVBT_AAGC_LOOP_GAIN, // For RTL2832 only ++ DVBT_LOOP_GAIN2_3_0, // For RTL2832 only ++ DVBT_LOOP_GAIN2_4, // For RTL2832 only ++ DVBT_LOOP_GAIN3, // For RTL2832 only ++ DVBT_VTOP1, // For RTL2832 only ++ DVBT_VTOP2, // For RTL2832 only ++ DVBT_VTOP3, // For RTL2832 only ++ DVBT_KRF1, // For RTL2832 only ++ DVBT_KRF2, // For RTL2832 only ++ DVBT_KRF3, // For RTL2832 only ++ DVBT_KRF4, // For RTL2832 only ++ DVBT_EN_GI_PGA, // For RTL2832 only ++ DVBT_THD_LOCK_UP, // For RTL2832 only ++ DVBT_THD_LOCK_DW, // For RTL2832 only ++ DVBT_THD_UP1, // For RTL2832 only ++ DVBT_THD_DW1, // For RTL2832 only ++ DVBT_INTER_CNT_LEN, // For RTL2832 only ++ DVBT_GI_PGA_STATE, // For RTL2832 only ++ DVBT_EN_AGC_PGA, // For RTL2832 only ++ ++ ++ // TS interface registers ++ DVBT_CKOUTPAR, ++ DVBT_CKOUT_PWR, ++ DVBT_SYNC_DUR, ++ DVBT_ERR_DUR, ++ DVBT_SYNC_LVL, ++ DVBT_ERR_LVL, ++ DVBT_VAL_LVL, ++ DVBT_SERIAL, ++ DVBT_SER_LSB, ++ DVBT_CDIV_PH0, ++ DVBT_CDIV_PH1, ++ ++ DVBT_MPEG_IO_OPT_2_2, // For RTL2832 only ++ DVBT_MPEG_IO_OPT_1_0, // For RTL2832 only ++ DVBT_CKOUTPAR_PIP, // For RTL2832 only ++ DVBT_CKOUT_PWR_PIP, // For RTL2832 only ++ DVBT_SYNC_LVL_PIP, // For RTL2832 only ++ DVBT_ERR_LVL_PIP, // For RTL2832 only ++ DVBT_VAL_LVL_PIP, // For RTL2832 only ++ DVBT_CKOUTPAR_PID, // For RTL2832 only ++ DVBT_CKOUT_PWR_PID, // For RTL2832 only ++ DVBT_SYNC_LVL_PID, // For RTL2832 only ++ DVBT_ERR_LVL_PID, // For RTL2832 only ++ DVBT_VAL_LVL_PID, // For RTL2832 only ++ ++ ++ // FSM state-holding register ++ DVBT_SM_PASS, ++ ++ // Registers for function 2 (for RTL2830 only) ++ DVBT_UPDATE_REG_2, ++ ++ // Registers for function 3 (for RTL2830 only) ++ DVBT_BTHD_P3, ++ DVBT_BTHD_D3, ++ ++ // Registers for function 4 (for RTL2830 only) ++ DVBT_FUNC4_REG0, ++ DVBT_FUNC4_REG1, ++ DVBT_FUNC4_REG2, ++ DVBT_FUNC4_REG3, ++ DVBT_FUNC4_REG4, ++ DVBT_FUNC4_REG5, ++ DVBT_FUNC4_REG6, ++ DVBT_FUNC4_REG7, ++ DVBT_FUNC4_REG8, ++ DVBT_FUNC4_REG9, ++ DVBT_FUNC4_REG10, ++ ++ // Registers for functin 5 (for RTL2830 only) ++ DVBT_FUNC5_REG0, ++ DVBT_FUNC5_REG1, ++ DVBT_FUNC5_REG2, ++ DVBT_FUNC5_REG3, ++ DVBT_FUNC5_REG4, ++ DVBT_FUNC5_REG5, ++ DVBT_FUNC5_REG6, ++ DVBT_FUNC5_REG7, ++ DVBT_FUNC5_REG8, ++ DVBT_FUNC5_REG9, ++ DVBT_FUNC5_REG10, ++ DVBT_FUNC5_REG11, ++ DVBT_FUNC5_REG12, ++ DVBT_FUNC5_REG13, ++ DVBT_FUNC5_REG14, ++ DVBT_FUNC5_REG15, ++ DVBT_FUNC5_REG16, ++ DVBT_FUNC5_REG17, ++ DVBT_FUNC5_REG18, ++ ++ ++ // AD7 registers (for RTL2832 only) ++ DVBT_AD7_SETTING, ++ DVBT_RSSI_R, ++ ++ // ACI detection registers (for RTL2832 only) ++ DVBT_ACI_DET_IND, ++ ++ // Clock output registers (for RTL2832 only) ++ DVBT_REG_MON, ++ DVBT_REG_MONSEL, ++ DVBT_REG_GPE, ++ DVBT_REG_GPO, ++ DVBT_REG_4MSEL, ++ ++ ++ // Test registers for test only ++ DVBT_TEST_REG_1, ++ DVBT_TEST_REG_2, ++ DVBT_TEST_REG_3, ++ DVBT_TEST_REG_4, ++ ++ // Item terminator ++ DVBT_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++ ++// Register table length definitions ++#define DVBT_REG_TABLE_LEN_MAX DVBT_REG_BIT_NAME_ITEM_TERMINATOR ++ ++ ++ ++ ++ ++// DVB-T demod module pre-definition ++typedef struct DVBT_DEMOD_MODULE_TAG DVBT_DEMOD_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register page setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_PAGE() to set demod register page. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] PageNo Page number ++ ++ ++@retval FUNCTION_SUCCESS Set register page successfully with page number. ++@retval FUNCTION_ERROR Set register page unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_PAGE() with the corresponding function. ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register page with page number 2. ++ pDemod->SetRegPage(pDemod, 2); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_PAGE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register byte setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BYTES() to set demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bytes successfully with writing bytes. ++@retval FUNCTION_ERROR Set demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_SET_REG_BYTES(). ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char WritingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bytes (page 1, address 0x17 ~ 0x1b) with 5 writing bytes. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBytes(pDemod, 0x17, WritingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_BYTES)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register byte getting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BYTES() to get demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bytes successfully with reading byte number. ++@retval FUNCTION_ERROR Get demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_GET_REG_BYTES(). ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char ReadingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bytes (page 1, address 0x17 ~ 0x1b) with reading byte number 5. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBytes(pDemod, 0x17, ReadingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_BYTES)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register mask bits setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_MASK_BITS() to set demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register mask bits successfully with writing value. ++@retval FUNCTION_ERROR Set demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_SET_REG_MASK_BITS(). ++ -# The constraints of DVBT_DEMOD_FP_SET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits (page 1, address {0x18, 0x17} [12:5]) with writing value 0x1d. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegMaskBits(pDemod, 0x17, 12, 5, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x17 0x18 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_MASK_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register mask bits getting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_MASK_BITS() to get demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register mask bits successfully. ++@retval FUNCTION_ERROR Get demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_GET_REG_MASK_BITS(). ++ -# The constraints of DVBT_DEMOD_FP_GET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits (page 1, address {0x18, 0x17} [12:5]). ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegMaskBits(pDemod, 0x17, 12, 5, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_MASK_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BITS() to set demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DVBT_DEMOD_FP_SET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBits(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits getting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BITS() to get demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DVBT_DEMOD_FP_GET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBits(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits setting function pointer (with page setting) ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE() to set demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name, page setting, and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits getting function pointer (with page setting) ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE() to get demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and page setting. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->GetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod type getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DEMOD_TYPE() to get DVB-T demod type. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDemodType Pointer to an allocated memory for storing demod type ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DEMOD_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_GET_DEMOD_TYPE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod I2C device address getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DEVICE_ADDR() to get DVB-T demod I2C device address. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing demod I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get demod device address successfully. ++@retval FUNCTION_ERROR Get demod device address unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_GET_DEVICE_ADDR)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod crystal frequency getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() to get DVB-T demod crystal frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrystalFreqHz Pointer to an allocated memory for storing demod crystal frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod crystal frequency successfully. ++@retval FUNCTION_ERROR Get demod crystal frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod I2C bus connection asking function pointer ++ ++One can use DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C() to ask DVB-T demod if it is connected to I2C bus. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C() with the corresponding function. ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod software resetting function pointer ++ ++One can use DVBT_DEMOD_FP_SOFTWARE_RESET() to reset DVB-T demod by software reset. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod by software reset successfully. ++@retval FUNCTION_ERROR Reset demod by software reset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SOFTWARE_RESET() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SOFTWARE_RESET)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod initializing function pointer ++ ++One can use DVBT_DEMOD_FP_INITIALIZE() to initialie DVB-T demod. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize demod successfully. ++@retval FUNCTION_ERROR Initialize demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_INITIALIZE)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod bandwidth mode setting function pointer ++ ++One can use DVBT_DEMOD_FP_SET_DVBT_MODE() to set DVB-T demod bandwidth mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] BandwidthMode Bandwidth mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod bandwidth mode successfully. ++@retval FUNCTION_ERROR Set demod bandwidth mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_DVBT_MODE() with the corresponding function. ++ ++ ++@see DVBT_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_BANDWIDTH_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod IF frequency setting function pointer ++ ++One can use DVBT_DEMOD_FP_SET_IF_FREQ_HZ() to set DVB-T demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] IfFreqHz IF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod IF frequency successfully. ++@retval FUNCTION_ERROR Set demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_IF_FREQ_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod spectrum mode setting function pointer ++ ++One can use DVBT_DEMOD_FP_SET_SPECTRUM_MODE() to set DVB-T demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SpectrumMode Spectrum mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod spectrum mode successfully. ++@retval FUNCTION_ERROR Set demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_SPECTRUM_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod bandwidth mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DVBT_MODE() to get DVB-T demod bandwidth mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pBandwidthMode Pointer to an allocated memory for storing demod bandwidth mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod bandwidth mode successfully. ++@retval FUNCTION_ERROR Get demod bandwidth mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DVBT_MODE() with the corresponding function. ++ ++ ++@see DVBT_DVBT_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_BANDWIDTH_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod IF frequency getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_IF_FREQ_HZ() to get DVB-T demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfFreqHz Pointer to an allocated memory for storing demod IF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF frequency successfully. ++@retval FUNCTION_ERROR Get demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_IF_FREQ_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod spectrum mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SPECTRUM_MODE() to get DVB-T demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSpectrumMode Pointer to an allocated memory for storing demod spectrum mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod spectrum mode successfully. ++@retval FUNCTION_ERROR Get demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SPECTRUM_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod TPS lock asking function pointer ++ ++One can use DVBT_DEMOD_FP_IS_TPS_LOCKED() to ask DVB-T demod if it is TPS-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform TPS lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform TPS lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_IS_TPS_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_IS_TPS_LOCKED)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod signal lock asking function pointer ++ ++One can use DVBT_DEMOD_FP_IS_SIGNAL_LOCKED() to ask DVB-T demod if it is signal-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_IS_SIGNAL_LOCKED)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod signal strength getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal strength successfully. ++@retval FUNCTION_ERROR Get demod signal strength unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod signal quality getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal quality successfully. ++@retval FUNCTION_ERROR Get demod signal quality unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SIGNAL_QUALITY)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod BER getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_BER() to get BER. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_BER)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod SNR getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod SNR successfully. ++@retval FUNCTION_ERROR Get demod SNR unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SNR_DB)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod RF AGC getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_RF_AGC() to get DVB-T demod RF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pRfAgc Pointer to an allocated memory for storing RF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod RF AGC value successfully. ++@retval FUNCTION_ERROR Get demod RF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_RF_AGC() with the corresponding function. ++ -# The range of RF AGC value is (-pow(2, 13)) ~ (pow(2, 13) - 1). ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_RF_AGC)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod IF AGC getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_IF_AGC() to get DVB-T demod IF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfAgc Pointer to an allocated memory for storing IF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF AGC value successfully. ++@retval FUNCTION_ERROR Get demod IF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_IF_AGC() with the corresponding function. ++ -# The range of IF AGC value is (-pow(2, 13)) ~ (pow(2, 13) - 1). ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_IF_AGC)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod digital AGC getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DI_AGC() to get DVB-T demod digital AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDiAgc Pointer to an allocated memory for storing digital AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod digital AGC value successfully. ++@retval FUNCTION_ERROR Get demod digital AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DI_AGC() with the corresponding function. ++ -# The range of digital AGC value is 0 ~ (pow(2, 8) - 1). ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_DI_AGC)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDiAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod TR offset getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get demod TR offset successfully. ++@retval FUNCTION_ERROR Get demod TR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_TR_OFFSET_PPM)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod CR offset getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod CR offset successfully. ++@retval FUNCTION_ERROR Get demod CR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CR_OFFSET_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod constellation mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CONSTELLATION() to get DVB-T demod constellation mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pConstellation Pointer to an allocated memory for storing demod constellation mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod constellation mode successfully. ++@retval FUNCTION_ERROR Get demod constellation mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CONSTELLATION() with the corresponding function. ++ ++ ++@see DVBT_CONSTELLATION_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CONSTELLATION)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConstellation ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod hierarchy mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_HIERARCHY() to get DVB-T demod hierarchy mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pHierarchy Pointer to an allocated memory for storing demod hierarchy mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod hierarchy mode successfully. ++@retval FUNCTION_ERROR Get demod hierarchy mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_HIERARCHY() with the corresponding function. ++ ++ ++@see DVBT_HIERARCHY_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_HIERARCHY)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pHierarchy ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod low-priority code rate mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CODE_RATE_LP() to get DVB-T demod low-priority code rate mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCodeRateLp Pointer to an allocated memory for storing demod low-priority code rate mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod low-priority code rate mode successfully. ++@retval FUNCTION_ERROR Get demod low-priority code rate mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CODE_RATE_LP() with the corresponding function. ++ ++ ++@see DVBT_CODE_RATE_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CODE_RATE_LP)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateLp ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod high-priority code rate mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CODE_RATE_HP() to get DVB-T demod high-priority code rate mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCodeRateHp Pointer to an allocated memory for storing demod high-priority code rate mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod high-priority code rate mode successfully. ++@retval FUNCTION_ERROR Get demod high-priority code rate mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CODE_RATE_HP() with the corresponding function. ++ ++ ++@see DVBT_CODE_RATE_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CODE_RATE_HP)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateHp ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod guard interval mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_GUARD_INTERVAL() to get DVB-T demod guard interval mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pGuardInterval Pointer to an allocated memory for storing demod guard interval mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod guard interval mode successfully. ++@retval FUNCTION_ERROR Get demod guard interval mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_GUARD_INTERVAL() with the corresponding function. ++ ++ ++@see DVBT_GUARD_INTERVAL_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_GUARD_INTERVAL)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pGuardInterval ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod FFT mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_FFT_MODE() to get DVB-T demod FFT mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pFftMode Pointer to an allocated memory for storing demod FFT mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod FFT mode successfully. ++@retval FUNCTION_ERROR Get demod FFT mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_FFT_MODE() with the corresponding function. ++ ++ ++@see DVBT_FFT_MODE_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_FFT_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pFftMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod updating function pointer ++ ++One can use DVBT_DEMOD_FP_UPDATE_FUNCTION() to update demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod setting successfully. ++@retval FUNCTION_ERROR Update demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_UPDATE_FUNCTION)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod reseting function pointer ++ ++One can use DVBT_DEMOD_FP_RESET_FUNCTION() to reset demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod setting successfully. ++@retval FUNCTION_ERROR Reset demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_RESET_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_RESET_FUNCTION)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/// RTL2830 extra module ++ ++// Definitions for Function 4 ++#define DVBT_FUNC4_REG_VALUE_NUM 5 ++ ++typedef struct RTL2830_EXTRA_MODULE_TAG RTL2830_EXTRA_MODULE; ++ ++/* ++ ++@brief RTL2830 application mode getting function pointer ++ ++One can use RTL2830_FP_GET_APP_MODE() to get RTL2830 application mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAppMode Pointer to an allocated memory for storing demod application mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod application mode successfully. ++@retval FUNCTION_ERROR Get demod application mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set RTL2830_FP_GET_APP_MODE() with the corresponding function. ++ ++ ++@see RTL2830_APPLICATION_MODE ++ ++*/ ++typedef void ++(*RTL2830_FP_GET_APP_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ); ++ ++struct RTL2830_EXTRA_MODULE_TAG ++{ ++ // RTL2830 variables ++ int AppMode; ++ ++ // RTL2830 update procedure enabling status ++ int IsFunction2Enabled; ++ int IsFunction3Enabled; ++ int IsFunction4Enabled; ++ int IsFunction5Enabled; ++ ++ // RTL2830 update procedure variables ++ unsigned char Func2Executing; ++ unsigned char Func3State; ++ unsigned char Func3Executing; ++ unsigned char Func4State; ++ unsigned long Func4DelayCnt; ++ unsigned long Func4DelayCntMax; ++ unsigned char Func4ParamSetting; ++ unsigned long Func4RegValue[DVBT_FUNC4_REG_VALUE_NUM]; ++ unsigned char Func5State; ++ unsigned char Func5QamBak; ++ unsigned char Func5HierBak; ++ unsigned char Func5LpCrBak; ++ unsigned char Func5HpCrBak; ++ unsigned char Func5GiBak; ++ unsigned char Func5FftBak; ++ ++ // RTL2830 extra function pointers ++ RTL2830_FP_GET_APP_MODE GetAppMode; ++}; ++ ++ ++ ++ ++ ++/// RTL2832 extra module ++typedef struct RTL2832_EXTRA_MODULE_TAG RTL2832_EXTRA_MODULE; ++ ++/* ++ ++@brief RTL2832 application mode getting function pointer ++ ++One can use RTL2832_FP_GET_APP_MODE() to get RTL2832 application mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAppMode Pointer to an allocated memory for storing demod application mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod application mode successfully. ++@retval FUNCTION_ERROR Get demod application mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set RTL2832_FP_GET_APP_MODE() with the corresponding function. ++ ++ ++@see RTL2832_APPLICATION_MODE ++ ++*/ ++typedef void ++(*RTL2832_FP_GET_APP_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ); ++ ++struct RTL2832_EXTRA_MODULE_TAG ++{ ++ // RTL2832 extra variables ++ int AppMode; ++ ++ // RTL2832 update procedure enabling status ++ int IsFunc1Enabled; ++ ++ // RTL2832 update Function 1 variables ++ int Func1State; ++ ++ int Func1WaitTimeMax; ++ int Func1GettingTimeMax; ++ int Func1GettingNumEachTime; ++ ++ int Func1WaitTime; ++ int Func1GettingTime; ++ ++ unsigned long Func1RsdBerEstSumNormal; ++ unsigned long Func1RsdBerEstSumConfig1; ++ unsigned long Func1RsdBerEstSumConfig2; ++ unsigned long Func1RsdBerEstSumConfig3; ++ ++ int Func1QamBak; ++ int Func1HierBak; ++ int Func1LpCrBak; ++ int Func1HpCrBak; ++ int Func1GiBak; ++ int Func1FftBak; ++ ++ // RTL2832 extra function pointers ++ RTL2832_FP_GET_APP_MODE GetAppMode; ++}; ++ ++ ++ ++ ++ ++/// DVB-T demod module structure ++struct DVBT_DEMOD_MODULE_TAG ++{ ++ unsigned long CurrentPageNo; ++ // Private variables ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ int TsInterfaceMode; ++ ++ int BandwidthMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int IsBandwidthModeSet; ++ int IsIfFreqHzSet; ++ int IsSpectrumModeSet; ++ ++ union ///< Demod extra module used by driving module ++ { ++ RTL2830_EXTRA_MODULE Rtl2830; ++ RTL2832_EXTRA_MODULE Rtl2832; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ // Demod register table ++ DVBT_REG_ENTRY RegTable[DVBT_REG_TABLE_LEN_MAX]; ++ ++ ++ // Demod I2C function pointers ++ DVBT_DEMOD_FP_SET_REG_PAGE SetRegPage; ++ DVBT_DEMOD_FP_SET_REG_BYTES SetRegBytes; ++ DVBT_DEMOD_FP_GET_REG_BYTES GetRegBytes; ++ DVBT_DEMOD_FP_SET_REG_MASK_BITS SetRegMaskBits; ++ DVBT_DEMOD_FP_GET_REG_MASK_BITS GetRegMaskBits; ++ DVBT_DEMOD_FP_SET_REG_BITS SetRegBits; ++ DVBT_DEMOD_FP_GET_REG_BITS GetRegBits; ++ DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE SetRegBitsWithPage; ++ DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE GetRegBitsWithPage; ++ ++ ++ // Demod manipulating function pointers ++ DVBT_DEMOD_FP_GET_DEMOD_TYPE GetDemodType; ++ DVBT_DEMOD_FP_GET_DEVICE_ADDR GetDeviceAddr; ++ DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ GetCrystalFreqHz; ++ ++ DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C IsConnectedToI2c; ++ ++ DVBT_DEMOD_FP_SOFTWARE_RESET SoftwareReset; ++ ++ DVBT_DEMOD_FP_INITIALIZE Initialize; ++ DVBT_DEMOD_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ DVBT_DEMOD_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ DVBT_DEMOD_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ DVBT_DEMOD_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ DVBT_DEMOD_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ DVBT_DEMOD_FP_GET_SPECTRUM_MODE GetSpectrumMode; ++ ++ DVBT_DEMOD_FP_IS_TPS_LOCKED IsTpsLocked; ++ DVBT_DEMOD_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ ++ DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DVBT_DEMOD_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ ++ DVBT_DEMOD_FP_GET_BER GetBer; ++ DVBT_DEMOD_FP_GET_SNR_DB GetSnrDb; ++ ++ DVBT_DEMOD_FP_GET_RF_AGC GetRfAgc; ++ DVBT_DEMOD_FP_GET_IF_AGC GetIfAgc; ++ DVBT_DEMOD_FP_GET_DI_AGC GetDiAgc; ++ ++ DVBT_DEMOD_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DVBT_DEMOD_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ ++ DVBT_DEMOD_FP_GET_CONSTELLATION GetConstellation; ++ DVBT_DEMOD_FP_GET_HIERARCHY GetHierarchy; ++ DVBT_DEMOD_FP_GET_CODE_RATE_LP GetCodeRateLp; ++ DVBT_DEMOD_FP_GET_CODE_RATE_HP GetCodeRateHp; ++ DVBT_DEMOD_FP_GET_GUARD_INTERVAL GetGuardInterval; ++ DVBT_DEMOD_FP_GET_FFT_MODE GetFftMode; ++ ++ DVBT_DEMOD_FP_UPDATE_FUNCTION UpdateFunction; ++ DVBT_DEMOD_FP_RESET_FUNCTION ResetFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DVB-T demod default I2C functions ++int ++dvbt_demod_default_SetRegPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++int ++dvbt_demod_default_SetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ); ++ ++int ++dvbt_demod_default_GetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ); ++ ++int ++dvbt_demod_default_SetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++dvbt_demod_default_GetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dvbt_demod_default_SetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dvbt_demod_default_GetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dvbt_demod_default_SetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dvbt_demod_default_GetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// DVB-T demod default manipulating functions ++void ++dvbt_demod_default_GetDemodType( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++void ++dvbt_demod_default_GetDeviceAddr( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++void ++dvbt_demod_default_GetCrystalFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++int ++dvbt_demod_default_GetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ); ++ ++int ++dvbt_demod_default_GetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++dvbt_demod_default_GetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_nim_base.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_nim_base.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_nim_base.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_nim_base.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,531 @@ ++/** ++ ++@file ++ ++@brief DVB-T NIM base module definition ++ ++DVB-T NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++*/ ++ ++ ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_NIM_TYPE ++ ++*/ ++void ++dvbt_nim_default_GetNimType( ++ DVBT_NIM_MODULE *pNim, ++ int *pNimType ++ ) ++{ ++ // Get NIM type from NIM module. ++ *pNimType = pNim->NimType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++dvbt_nim_default_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_PARAMETERS ++ ++*/ ++int ++dvbt_nim_default_GetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pBandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Get tuner RF frequency in Hz. ++ if(pTuner->GetRfFreqHz(pTuner, pRfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, pBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_IS_SIGNAL_PRESENT ++ ++*/ ++int ++dvbt_nim_default_IsSignalPresent( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DVBT_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal present check. ++ for(i = 0; i < DVBT_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check TPS present status on demod. ++ // Note: If TPS is locked, stop signal present check. ++ if(pDemod->IsTpsLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++dvbt_nim_default_IsSignalLocked( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DVBT_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal lock check. ++ for(i = 0; i < DVBT_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++dvbt_nim_default_GetSignalStrength( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal strength from demod. ++ if(pDemod->GetSignalStrength(pDemod, pSignalStrength) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++dvbt_nim_default_GetSignalQuality( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal quality from demod. ++ if(pDemod->GetSignalQuality(pDemod, pSignalQuality) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_BER ++ ++*/ ++int ++dvbt_nim_default_GetBer( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get BER from demod. ++ if(pDemod->GetBer(pDemod, pBerNum, pBerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_SNR_DB ++ ++*/ ++int ++dvbt_nim_default_GetSnrDb( ++ DVBT_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get SNR in dB from demod. ++ if(pDemod->GetSnrDb(pDemod, pSnrDbNum, pSnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++dvbt_nim_default_GetTrOffsetPpm( ++ DVBT_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TR offset in ppm from demod. ++ if(pDemod->GetTrOffsetPpm(pDemod, pTrOffsetPpm) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++dvbt_nim_default_GetCrOffsetHz( ++ DVBT_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get CR offset in Hz from demod. ++ if(pDemod->GetCrOffsetHz(pDemod, pCrOffsetHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_TPS_INFO ++ ++*/ ++int ++dvbt_nim_default_GetTpsInfo( ++ DVBT_NIM_MODULE *pNim, ++ int *pConstellation, ++ int *pHierarchy, ++ int *pCodeRateLp, ++ int *pCodeRateHp, ++ int *pGuardInterval, ++ int *pFftMode ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TPS constellation information from demod. ++ if(pDemod->GetConstellation(pDemod, pConstellation) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS hierarchy information from demod. ++ if(pDemod->GetHierarchy(pDemod, pHierarchy) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS low-priority code rate information from demod. ++ if(pDemod->GetCodeRateLp(pDemod, pCodeRateLp) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS high-priority code rate information from demod. ++ if(pDemod->GetCodeRateHp(pDemod, pCodeRateHp) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS guard interval information from demod. ++ if(pDemod->GetGuardInterval(pDemod, pGuardInterval) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS FFT mode information from demod. ++ if(pDemod->GetFftMode(pDemod, pFftMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++dvbt_nim_default_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_nim_base.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_nim_base.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/dvbt_nim_base.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/dvbt_nim_base.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,919 @@ ++#ifndef __DVBT_NIM_BASE_H ++#define __DVBT_NIM_BASE_H ++ ++/** ++ ++@file ++ ++@brief DVB-T NIM base module definition ++ ++DVB-T NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ unsigned long RfFreqHz; ++ int BandwidthMode; ++ ++ int Answer; ++ unsigned long SignalStrength, SignalQuality; ++ unsigned long BerNum, BerDen, PerNum, PerDen; ++ double Ber, Per; ++ unsigned long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ long TrOffsetPpm, CrOffsetHz; ++ ++ int Constellation; ++ int Hierarchy; ++ int CodeRateLp; ++ int CodeRateHp; ++ int GuardInterval; ++ int FftMode; ++ ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ &DemodxExtraModuleMemory, // Employ Demod-X extra module. ++ 0x20, // The Demod-X I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The Demod-X crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The Demod-X TS interface mode is serial. ++ ... // Other arguments for Demod-X ++ ++ &TunerxExtraModuleMemory, // Employ Tuner-Y extra module. ++ 0xc0, // The Tuner-Y I2C device address is 0xc0 in 8-bit format. ++ ... // Other arguments for Tuner-Y ++ ); ++ ++ ++ ++ // Get NIM type. ++ // Note: NIM types are defined in the MODULE_TYPE enumeration. ++ pNim->GetNimType(pNim, &NimType); ++ ++ ++ ++ ++ ++ ++ ++ // ==== Initialize NIM and set its parameters ===== ++ ++ // Initialize NIM. ++ pNim->Initialize(pNim); ++ ++ // Set NIM parameters. (RF frequency, bandwdith mode) ++ // Note: In the example: ++ // 1. RF frequency is 666 MHz. ++ // 2. Bandwidth mode is 8 MHz. ++ RfFreqHz = 666000000; ++ BandwidthMode = DVBT_BANDWIDTH_8MHZ; ++ pNim->SetParameters(pNim, RfFreqHz, BandwidthMode); ++ ++ ++ ++ // Wait 1 second for demod convergence. ++ ++ ++ ++ ++ ++ // ==== Get NIM information ===== ++ ++ // Get NIM parameters. (RF frequency, bandwdith mode) ++ pNim->GetParameters(pNim, &RfFreqHz, &BandwidthMode); ++ ++ ++ // Get signal present status. ++ // Note: 1. The argument Answer is YES when the NIM module has found DVB-T signal in the RF channel. ++ // 2. The argument Answer is NO when the NIM module does not find DVB-T signal in the RF channel. ++ // Recommendation: Use the IsSignalPresent() function for channel scan. ++ pNim->IsSignalPresent(pNim, &Answer); ++ ++ // Get signal lock status. ++ // Note: 1. The argument Answer is YES when the NIM module has locked DVB-T signal in the RF channel. ++ // At the same time, the NIM module sends TS packets through TS interface hardware pins. ++ // 2. The argument Answer is NO when the NIM module does not lock DVB-T signal in the RF channel. ++ // Recommendation: Use the IsSignalLocked() function for signal lock check. ++ pNim->IsSignalLocked(pNim, &Answer); ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pNim->GetSignalStrength(pNim, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pNim->GetSignalQuality(pNim, &SignalQuality); ++ ++ ++ // Get BER. ++ pNim->GetBer(pNim, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get SNR in dB. ++ pNim->GetSnrDb(pNim, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pNim->GetTrOffsetPpm(pNim, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pNim->GetCrOffsetHz(pNim, &CrOffsetHz); ++ ++ ++ // Get TPS information. ++ // Note: One can find TPS information definitions in the enumerations as follows: ++ // 1. DVBT_CONSTELLATION_MODE. ++ // 2. DVBT_HIERARCHY_MODE. ++ // 3. DVBT_CODE_RATE_MODE. (for low-priority and high-priority code rate) ++ // 4. DVBT_GUARD_INTERVAL_MODE. ++ // 5. DVBT_FFT_MODE_MODE ++ pNim->GetTpsInfo(pNim, &Constellation, &Hierarchy, &CodeRateLp, &CodeRateHp, &GuardInterval, &FftMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++#include "tuner_base.h" ++#include "dvbt_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define DVBT_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT 1 ++#define DVBT_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT 1 ++ ++ ++ ++ ++ ++/// DVB-T NIM module pre-definition ++typedef struct DVBT_NIM_MODULE_TAG DVBT_NIM_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod type getting function pointer ++ ++One can use DVBT_NIM_FP_GET_NIM_TYPE() to get DVB-T NIM type. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pNimType Pointer to an allocated memory for storing NIM type ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_NIM_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DVBT_NIM_FP_GET_NIM_TYPE)( ++ DVBT_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM initializing function pointer ++ ++One can use DVBT_NIM_FP_INITIALIZE() to initialie DVB-T NIM. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize NIM successfully. ++@retval FUNCTION_ERROR Initialize NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_INITIALIZE)( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM parameter setting function pointer ++ ++One can use DVBT_NIM_FP_SET_PARAMETERS() to set DVB-T NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++@param [in] BandwidthMode Bandwidth mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set NIM parameters successfully. ++@retval FUNCTION_ERROR Set NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_SET_PARAMETERS() with the corresponding function. ++ ++ ++@see DVBT_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_SET_PARAMETERS)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM parameter getting function pointer ++ ++One can use DVBT_NIM_FP_GET_PARAMETERS() to get DVB-T NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pRfFreqHz Pointer to an allocated memory for storing NIM RF frequency in Hz ++@param [out] pBandwidthMode Pointer to an allocated memory for storing NIM bandwidth mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM parameters successfully. ++@retval FUNCTION_ERROR Get NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_PARAMETERS() with the corresponding function. ++ ++ ++@see DVBT_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_PARAMETERS)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal present asking function pointer ++ ++One can use DVBT_NIM_FP_IS_SIGNAL_PRESENT() to ask DVB-T NIM if signal is present. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal present asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal present asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_IS_SIGNAL_PRESENT() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_IS_SIGNAL_PRESENT)( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal lock asking function pointer ++ ++One can use DVBT_NIM_FP_IS_SIGNAL_LOCKED() to ask DVB-T NIM if signal is locked. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_IS_SIGNAL_LOCKED)( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal strength getting function pointer ++ ++One can use DVBT_NIM_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal strength successfully. ++@retval FUNCTION_ERROR Get NIM signal strength unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_SIGNAL_STRENGTH)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal quality getting function pointer ++ ++One can use DVBT_NIM_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal quality successfully. ++@retval FUNCTION_ERROR Get NIM signal quality unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_SIGNAL_QUALITY)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM BER value getting function pointer ++ ++One can use DVBT_NIM_FP_GET_BER() to get BER. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM BER value successfully. ++@retval FUNCTION_ERROR Get NIM BER value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_BER)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM SNR getting function pointer ++ ++One can use DVBT_NIM_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM SNR successfully. ++@retval FUNCTION_ERROR Get NIM SNR unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_SNR_DB)( ++ DVBT_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM TR offset getting function pointer ++ ++One can use DVBT_NIM_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TR offset successfully. ++@retval FUNCTION_ERROR Get NIM TR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_TR_OFFSET_PPM)( ++ DVBT_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM CR offset getting function pointer ++ ++One can use DVBT_NIM_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get NIM CR offset successfully. ++@retval FUNCTION_ERROR Get NIM CR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_CR_OFFSET_HZ)( ++ DVBT_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM TPS information getting function pointer ++ ++One can use DVBT_NIM_FP_GET_TPS_INFO() to get TPS information. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pConstellation Pointer to an allocated memory for storing demod constellation mode ++@param [out] pHierarchy Pointer to an allocated memory for storing demod hierarchy mode ++@param [out] pCodeRateLp Pointer to an allocated memory for storing demod low-priority code rate mode ++@param [out] pCodeRateHp Pointer to an allocated memory for storing demod high-priority code rate mode ++@param [out] pGuardInterval Pointer to an allocated memory for storing demod guard interval mode ++@param [out] pFftMode Pointer to an allocated memory for storing demod FFT mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TPS information successfully. ++@retval FUNCTION_ERROR Get NIM TPS information unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_TPS_INFO() with the corresponding function. ++ ++ ++@see DVBT_CONSTELLATION_MODE, DVBT_HIERARCHY_MODE, DVBT_CODE_RATE_MODE, DVBT_GUARD_INTERVAL_MODE, DVBT_FFT_MODE_MODE ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_TPS_INFO)( ++ DVBT_NIM_MODULE *pNim, ++ int *pConstellation, ++ int *pHierarchy, ++ int *pCodeRateLp, ++ int *pCodeRateHp, ++ int *pGuardInterval, ++ int *pFftMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM updating function pointer ++ ++One can use DVBT_NIM_FP_UPDATE_FUNCTION() to update NIM register setting. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update NIM setting successfully. ++@retval FUNCTION_ERROR Update NIM setting unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ ... ++ ); ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pNim->UpdateFunction(pNim); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_UPDATE_FUNCTION)( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MT2266 extra module ++typedef struct RTL2832_MT2266_EXTRA_MODULE_TAG RTL2832_MT2266_EXTRA_MODULE; ++struct RTL2832_MT2266_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned char LnaConfig; ++ unsigned char UhfSens; ++ unsigned char AgcCurrentState; ++ unsigned long LnaGainOld; ++}; ++ ++ ++ ++ ++ ++// RTL2832 E4000 extra module ++typedef struct RTL2832_E4000_EXTRA_MODULE_TAG RTL2832_E4000_EXTRA_MODULE; ++struct RTL2832_E4000_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2832 MT2063 extra module ++typedef struct RTL2832_MT2063_EXTRA_MODULE_TAG RTL2832_MT2063_EXTRA_MODULE; ++struct RTL2832_MT2063_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long IfFreqHz; ++}; ++ ++ ++ ++ ++ ++// RTL2832 FC0012 extra module ++typedef struct RTL2832_FC0012_EXTRA_MODULE_TAG RTL2832_FC0012_EXTRA_MODULE; ++struct RTL2832_FC0012_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++}; ++ ++ ++ ++ ++ ++/// DVB-T NIM module structure ++struct DVBT_NIM_MODULE_TAG ++{ ++ // Private variables ++ int NimType; ++ ++ union ///< NIM extra module used by driving module ++ { ++ RTL2832_MT2266_EXTRA_MODULE Rtl2832Mt2266; ++ RTL2832_E4000_EXTRA_MODULE Rtl2832E4000; ++ RTL2832_MT2063_EXTRA_MODULE Rtl2832Mt2063; ++ RTL2832_FC0012_EXTRA_MODULE Rtl2832Fc0012; ++ } ++ Extra; ++ ++ ++ // Modules ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module pointer ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ///< Base interface module memory ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module pointer ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ///< I2C bridge module memory ++ ++ TUNER_MODULE *pTuner; ///< Tuner module pointer ++ TUNER_MODULE TunerModuleMemory; ///< Tuner module memory ++ ++ DVBT_DEMOD_MODULE *pDemod; ///< DVB-T demod module pointer ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ///< DVB-T demod module memory ++ ++ ++ // NIM manipulating functions ++ DVBT_NIM_FP_GET_NIM_TYPE GetNimType; ++ DVBT_NIM_FP_INITIALIZE Initialize; ++ DVBT_NIM_FP_SET_PARAMETERS SetParameters; ++ DVBT_NIM_FP_GET_PARAMETERS GetParameters; ++ DVBT_NIM_FP_IS_SIGNAL_PRESENT IsSignalPresent; ++ DVBT_NIM_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ DVBT_NIM_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DVBT_NIM_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ DVBT_NIM_FP_GET_BER GetBer; ++ DVBT_NIM_FP_GET_SNR_DB GetSnrDb; ++ DVBT_NIM_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DVBT_NIM_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ DVBT_NIM_FP_GET_TPS_INFO GetTpsInfo; ++ DVBT_NIM_FP_UPDATE_FUNCTION UpdateFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DVB-T NIM default manipulaing functions ++void ++dvbt_nim_default_GetNimType( ++ DVBT_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++int ++dvbt_nim_default_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++dvbt_nim_default_GetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pBandwidthMode ++ ); ++ ++int ++dvbt_nim_default_IsSignalPresent( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dvbt_nim_default_IsSignalLocked( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dvbt_nim_default_GetSignalStrength( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++dvbt_nim_default_GetSignalQuality( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++dvbt_nim_default_GetBer( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++dvbt_nim_default_GetSnrDb( ++ DVBT_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++dvbt_nim_default_GetTrOffsetPpm( ++ DVBT_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++int ++dvbt_nim_default_GetCrOffsetHz( ++ DVBT_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++int ++dvbt_nim_default_GetTpsInfo( ++ DVBT_NIM_MODULE *pNim, ++ int *pConstellation, ++ int *pHierarchy, ++ int *pCodeRateLp, ++ int *pCodeRateHp, ++ int *pGuardInterval, ++ int *pFftMode ++ ); ++ ++int ++dvbt_nim_default_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/foundation.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/foundation.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/foundation.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/foundation.c 2010-10-27 08:17:24.000000000 +0200 +@@ -0,0 +1,352 @@ ++/** ++ ++@file ++ ++@brief Fundamental interface definition ++ ++Fundamental interface contains base function pointers and some mathematics tools. ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Base interface builder ++void ++BuildBaseInterface( ++ BASE_INTERFACE_MODULE **ppBaseInterface, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ unsigned long I2cReadingByteNumMax, ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs ++ ) ++{ ++ // Set base interface module pointer. ++ *ppBaseInterface = pBaseInterfaceModuleMemory; ++ ++ ++ // Set all base interface function pointers and arguments. ++ (*ppBaseInterface)->I2cReadingByteNumMax = I2cReadingByteNumMax; ++ (*ppBaseInterface)->I2cWritingByteNumMax = I2cWritingByteNumMax; ++ (*ppBaseInterface)->I2cRead = I2cRead; ++ (*ppBaseInterface)->I2cWrite = I2cWrite; ++ (*ppBaseInterface)->WaitMs = WaitMs; ++ (*ppBaseInterface)->SetUserDefinedDataPointer = base_interface_SetUserDefinedDataPointer; ++ (*ppBaseInterface)->GetUserDefinedDataPointer = base_interface_GetUserDefinedDataPointer; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set user defined data pointer of base interface structure for custom basic function implementation. ++ ++@note ++ -# Base interface builder will set BASE_FP_SET_USER_DEFINED_DATA_POINTER() function pointer with ++ base_interface_SetUserDefinedDataPointer(). ++ ++@see BASE_FP_SET_USER_DEFINED_DATA_POINTER ++ ++*/ ++void ++base_interface_SetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void *pUserDefinedData ++ ) ++{ ++ // Set user defined data pointer of base interface structure with user defined data pointer argument. ++ pBaseInterface->pUserDefinedData = pUserDefinedData; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get user defined data pointer of base interface structure for custom basic function implementation. ++ ++@note ++ -# Base interface builder will set BASE_FP_GET_USER_DEFINED_DATA_POINTER() function pointer with ++ base_interface_GetUserDefinedDataPointer(). ++ ++@see BASE_FP_GET_USER_DEFINED_DATA_POINTER ++ ++*/ ++void ++base_interface_GetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void **ppUserDefinedData ++ ) ++{ ++ // Get user defined data pointer from base interface structure to the caller user defined data pointer. ++ *ppUserDefinedData = pBaseInterface->pUserDefinedData; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Convert signed integer to binary. ++ ++Convert 2's complement signed integer to binary with bit number. ++ ++ ++@param [in] Value the converting value in 2's complement format ++@param [in] BitNum the bit number of the converting value ++ ++ ++@return Converted binary ++ ++ ++@note ++ The converting value must be -pow(2, BitNum - 1) ~ (pow(2, BitNum - 1) -1). ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++int main(void) ++{ ++ long Value = -345; ++ unsigned long Binary; ++ ++ ++ // Convert 2's complement integer to binary with 10 bit number. ++ Binary = SignedIntToBin(Value, 10); ++ ++ ++ // Result in base 2: ++ // Value = 1111 1111 1111 1111 1111 1110 1010 0111 b = -345 (in 32-bit 2's complement format) ++ // Binary = 0000 0000 0000 0000 0000 0010 1010 0111 b = 679 (in 10-bit binary format) ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++unsigned long ++SignedIntToBin( ++ long Value, ++ unsigned char BitNum ++ ) ++{ ++ unsigned int i; ++ unsigned long Mask, Binary; ++ ++ ++ ++ // Generate Mask according to BitNum. ++ Mask = 0; ++ for(i = 0; i < BitNum; i++) ++ Mask |= 0x1 << i; ++ ++ ++ // Convert signed integer to binary with Mask. ++ Binary = Value & Mask; ++ ++ ++ return Binary; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Convert binary to signed integer. ++ ++Convert binary to 2's complement signed integer with bit number. ++ ++ ++@param [in] Binary the converting binary ++@param [in] BitNum the bit number of the converting binary ++ ++ ++@return Converted 2's complement signed integer ++ ++ ++@note ++ The converting binary must be 0 ~ (pow(2, BitNum) - 1). ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++int main(void) ++{ ++ unsigned long Binary = 679; ++ long Value; ++ ++ ++ // Convert binary to 2's complement integer with 10 bit number. ++ Value = BinToSignedInt(Binary, 10); ++ ++ ++ // Result in base 2: ++ // Binary = 0000 0000 0000 0000 0000 0010 1010 0111 b = 679 (in 10-bit binary format) ++ // Value = 1111 1111 1111 1111 1111 1110 1010 0111 b = -345 (in 32-bit 2's complement format) ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++long ++BinToSignedInt( ++ unsigned long Binary, ++ unsigned char BitNum ++ ) ++{ ++ int i; ++ ++ unsigned char SignedBit; ++ unsigned long SignedBitExtension; ++ ++ long Value; ++ ++ ++ ++ // Get signed bit. ++ SignedBit = (unsigned char)((Binary >> (BitNum - 1)) & BIT_0_MASK); ++ ++ ++ // Generate signed bit extension. ++ SignedBitExtension = 0; ++ ++ for(i = BitNum; i < LONG_BIT_NUM; i++) ++ SignedBitExtension |= SignedBit << i; ++ ++ ++ // Combine binary value and signed bit extension to signed integer value. ++ Value = (long)(Binary | SignedBitExtension); ++ ++ ++ return Value; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get devision reult with ceiling. ++ ++Get unsigned devision reult with ceiling. ++ ++ ++@param [in] Dividend the dividend ++@param [in] Divisor the divisor ++ ++ ++@return Result with ceiling ++ ++ ++@note ++ The dividend and divisor must be unsigned integer. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++int main(void) ++{ ++ long Value; ++ ++ ++ // Get ceil(100 / 20) reult. ++ Value = DivideWithCeiling(100, 20); ++ ++ // Result: Value = 5 ++ ++ ++ // Get ceil(100 / 30) reult. ++ Value = DivideWithCeiling(100, 30); ++ ++ // Result: Value = 4 ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++unsigned long ++DivideWithCeiling( ++ unsigned long Dividend, ++ unsigned long Divisor ++ ) ++{ ++ unsigned long Result; ++ ++ ++ // Get primitive division result. ++ Result = Dividend / Divisor; ++ ++ // Adjust primitive result with ceiling. ++ if(Dividend % Divisor > 0) ++ Result += 1; ++ ++ ++ return Result; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/foundation.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/foundation.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/foundation.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/foundation.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,979 @@ ++#ifndef __FOUNDATION_H ++#define __FOUNDATION_H ++ ++/** ++ ++@file ++ ++@brief Fundamental interface declaration ++ ++Fundamental interface contains base function pointers and some mathematics tools. ++ ++*/ ++ ++ ++#include "i2c_bridge.h" ++#include "math_mpi.h" ++ ++ ++ ++#include "dvb-usb.h" ++#include "rtl2832u_io.h" ++ ++ ++ ++// Definitions ++ ++// API version ++#define REALTEK_NIM_API_VERSION "Realtek NIM API 2010.09.29" ++ ++ ++ ++// Constants ++#define INVALID_POINTER_VALUE 0 ++#define NO_USE 0 ++ ++#define LEN_1_BYTE 1 ++#define LEN_2_BYTE 2 ++#define LEN_3_BYTE 3 ++#define LEN_4_BYTE 4 ++#define LEN_5_BYTE 5 ++#define LEN_6_BYTE 6 ++#define LEN_11_BYTE 11 ++ ++#define LEN_1_BIT 1 ++ ++#define BYTE_MASK 0xff ++#define BYTE_SHIFT 8 ++#define HEX_DIGIT_MASK 0xf ++#define BYTE_BIT_NUM 8 ++#define LONG_BIT_NUM 32 ++ ++#define BIT_0_MASK 0x1 ++#define BIT_1_MASK 0x2 ++#define BIT_2_MASK 0x4 ++#define BIT_3_MASK 0x8 ++ ++ ++#define BIT_4_MASK 0x10 ++#define BIT_5_MASK 0x20 ++#define BIT_6_MASK 0x40 ++#define BIT_7_MASK 0x80 ++ ++ ++#define BIT_8_MASK 0x100 ++#define BIT_7_SHIFT 7 ++#define BIT_8_SHIFT 8 ++ ++ ++ ++// I2C buffer length ++// Note: I2C_BUFFER_LEN must be greater than I2cReadingByteNumMax and I2cWritingByteNumMax in BASE_INTERFACE_MODULE. ++#define I2C_BUFFER_LEN 128 ++ ++ ++ ++ ++ ++/// Module types ++enum MODULE_TYPE ++{ ++ // DVB-T demod ++ DVBT_DEMOD_TYPE_RTL2830, ///< RTL2830 DVB-T demod ++ DVBT_DEMOD_TYPE_RTL2832, ///< RTL2832 DVB-T demod ++ ++ // QAM demod ++ QAM_DEMOD_TYPE_RTL2840, ///< RTL2840 DVB-C demod ++ QAM_DEMOD_TYPE_RTL2810_OC, ///< RTL2810 OpenCable demod ++ QAM_DEMOD_TYPE_RTL2820_OC, ///< RTL2820 OpenCable demod ++ QAM_DEMOD_TYPE_RTD2885_QAM, ///< RTD2885 QAM demod ++ QAM_DEMOD_TYPE_RTD2932_QAM, ///< RTD2932 QAM demod ++ QAM_DEMOD_TYPE_RTL2836B_DVBC, ///< RTL2836 DVB-C demod ++ QAM_DEMOD_TYPE_RTL2810B_QAM, ///< RTL2810B QAM demod ++ QAM_DEMOD_TYPE_RTD2840B_QAM, ///< RTD2840B QAM demod ++ ++ // OOB demod ++ OOB_DEMOD_TYPE_RTL2820_OOB, ///< RTL2820 OOB demod ++ ++ // ATSC demod ++ ATSC_DEMOD_TYPE_RTL2820_ATSC, ///< RTL2820 ATSC demod ++ ATSC_DEMOD_TYPE_RTD2885_ATSC, ///< RTD2885 ATSC demod ++ ATSC_DEMOD_TYPE_RTD2932_ATSC, ///< RTD2932 ATSC demod ++ ATSC_DEMOD_TYPE_RTL2810B_ATSC, ///< RTL2810B ATSC demod ++ ++ // DTMB demod ++ DTMB_DEMOD_TYPE_RTL2836, ///< RTL2836 DTMB demod ++ DTMB_DEMOD_TYPE_RTL2836B_DTMB, ///< RTL2836B DTMB demod ++ ++ // Tuner ++ TUNER_TYPE_TDCGG052D, ///< TDCG-G052D tuner (QAM) ++ TUNER_TYPE_TDCHG001D, ///< TDCH-G001D tuner (QAM) ++ TUNER_TYPE_TDQE3003A, ///< TDQE3-003A tuner (QAM) ++ TUNER_TYPE_DCT7045, ///< DCT-7045 tuner (QAM) ++ TUNER_TYPE_MT2062, ///< MT2062 tuner (QAM) ++ TUNER_TYPE_MXL5005S, ///< MxL5005S tuner (DVB-T, ATSC) ++ TUNER_TYPE_TDVMH715P, ///< TDVM-H751P tuner (QAM, OOB, ATSC) ++ TUNER_TYPE_UBA00AL, ///< UBA00AL tuner (QAM, ATSC) ++ TUNER_TYPE_MT2266, ///< MT2266 tuner (DVB-T) ++ TUNER_TYPE_FC2580, ///< FC2580 tuner (DVB-T, DTMB) ++ TUNER_TYPE_TUA9001, ///< TUA9001 tuner (DVB-T) ++ TUNER_TYPE_DTT75300, ///< DTT-75300 tuner (DVB-T) ++ TUNER_TYPE_MXL5007T, ///< MxL5007T tuner (DVB-T, ATSC) ++ TUNER_TYPE_VA1T1ED6093, ///< VA1T1ED6093 tuner (DTMB) ++ TUNER_TYPE_TUA8010, ///< TUA8010 tuner (DVB-T) ++ TUNER_TYPE_E4000, ///< E4000 tuner (DVB-T) ++ TUNER_TYPE_DCT70704, ///< DCT-70704 tuner (QAM) ++ TUNER_TYPE_MT2063, ///< MT2063 tuner (DVB-T, QAM) ++ TUNER_TYPE_FC0012, ///< FC0012 tuner (DVB-T) ++ TUNER_TYPE_TDAG, ///< TDAG tuner (DTMB) ++ TUNER_TYPE_ADMTV804, ///< ADMTV804 tuner (DVB-T) ++ TUNER_TYPE_MAX3543, ///< MAX3543 tuner (DVB-T) ++ TUNER_TYPE_TDA18272, ///< TDA18272 tuner (DVB-T, QAM, DTMB) ++ TUNER_TYPE_FC0013, ///< FC0013 tuner (DVB-T, DTMB) ++ TUNER_TYPE_VA1E1ED2403, ///< VA1E1ED2403 tuner (DTMB) ++ TUNER_TYPE_AVALON, ///< AVALON tuner (DTMB) ++ TUNER_TYPE_SUTRE201, ///< SUTRE201 tuner (DTMB) ++ TUNER_TYPE_MR1300, ///< MR1300 tuner (ISDB-T 1-Seg) ++ TUNER_TYPE_TDAC7, ///< TDAC7 tuner (DTMB, QAM) ++ ++ // DVB-T NIM ++ DVBT_NIM_USER_DEFINITION, ///< DVB-T NIM: User definition ++ DVBT_NIM_RTL2832_MT2266, ///< DVB-T NIM: RTL2832 + MT2266 ++ DVBT_NIM_RTL2832_FC2580, ///< DVB-T NIM: RTL2832 + FC2580 ++ DVBT_NIM_RTL2832_TUA9001, ///< DVB-T NIM: RTL2832 + TUA9001 ++ DVBT_NIM_RTL2832_MXL5005S, ///< DVB-T NIM: RTL2832 + MxL5005S ++ DVBT_NIM_RTL2832_DTT75300, ///< DVB-T NIM: RTL2832 + DTT-75300 ++ DVBT_NIM_RTL2832_MXL5007T, ///< DVB-T NIM: RTL2832 + MxL5007T ++ DVBT_NIM_RTL2832_TUA8010, ///< DVB-T NIM: RTL2832 + TUA8010 ++ DVBT_NIM_RTL2832_E4000, ///< DVB-T NIM: RTL2832 + E4000 ++ DVBT_NIM_RTL2832_MT2063, ///< DVB-T NIM: RTL2832 + MT2063 ++ DVBT_NIM_RTL2832_FC0012, ///< DVB-T NIM: RTL2832 + FC0012 ++ DVBT_NIM_RTL2832_ADMTV804, ///< DVB-T NIM: RTL2832 + ADMTV804 ++ DVBT_NIM_RTL2832_MAX3543, ///< DVB-T NIM: RTL2832 + MAX3543 ++ DVBT_NIM_RTL2832_TDA18272, ///< DVB-T NIM: RTL2832 + TDA18272 ++ DVBT_NIM_RTL2832_FC0013, ///< DVB-T NIM: RTL2832 + FC0013 ++ ++ // QAM NIM ++ QAM_NIM_USER_DEFINITION, ///< QAM NIM: User definition ++ QAM_NIM_RTL2840_TDQE3003A, ///< QAM NIM: RTL2840 + TDQE3-003A ++ QAM_NIM_RTL2840_DCT7045, ///< QAM NIM: RTL2840 + DCT-7045 ++ QAM_NIM_RTL2840_DCT7046, ///< QAM NIM: RTL2840 + DCT-7046 ++ QAM_NIM_RTL2840_MT2062, ///< QAM NIM: RTL2840 + MT2062 ++ QAM_NIM_RTL2840_DCT70704, ///< QAM NIM: RTL2840 + DCT-70704 ++ QAM_NIM_RTL2840_MT2063, ///< QAM NIM: RTL2840 + MT2063 ++ QAM_NIM_RTL2840_MAX3543, ///< QAM NIM: RTL2840 + MAX3543 ++ QAM_NIM_RTL2836B_DVBC_VA1T1ED6093, ///< QAM NIM: RTL2836B DVB-C + VA1T1ED6093 ++ ++ // DCR NIM ++ DCR_NIM_RTL2820_TDVMH715P, ///< DCR NIM: RTL2820 + TDVM-H751P ++ DCR_NIM_RTD2885_UBA00AL, ///< DCR NIM: RTD2885 + UBA00AL ++ ++ // ATSC NIM ++ ATSC_NIM_RTD2885_ATSC_TDA18272, ///< ATSC NIM: RTD2885 ATSC + TDA18272 ++ ++ // DTMB NIM ++ DTMB_NIM_RTL2836_FC2580, ///< DTMB NIM: RTL2836 + FC2580 ++ DTMB_NIM_RTL2836_VA1T1ED6093, ///< DTMB NIM: RTL2836 + VA1T1ED6093 ++ DTMB_NIM_RTL2836_TDAG, ///< DTMB NIM: RTL2836 + TDAG ++ DTMB_NIM_RTL2836_MXL5007T, ///< DTMB NIM: RTL2836 + MxL5007T ++ DTMB_NIM_RTL2836_E4000, ///< DTMB NIM: RTL2836 + E4000 ++ DTMB_NIM_RTL2836_TDA18272, ///< DTMB NIM: RTL2836 + TDA18272 ++ DTMB_NIM_RTL2836B_DTMB_VA1T1ED6093, ///< DTMB NIM: RTL2836B DTMB + VA1T1ED6093 ++ DTMB_NIM_RTL2836B_DTMB_ADMTV804, ///< DTMB NIM: RTL2836B DTMB + ADMTV804 ++ DTMB_NIM_RTL2836B_DTMB_E4000, ///< DTMB NIM: RTL2836B DTMB + E4000 ++ DTMB_NIM_RTL2836B_DTMB_FC0012, ///< DTMB NIM: RTL2836B DTMB + FC0012 ++ DTMB_NIM_RTL2836B_DTMB_VA1E1ED2403, ///< DTMB NIM: RTL2836B DTMB + VA1E1ED2403 ++ DTMB_NIM_RTL2836B_DTMB_TDA18272, ///< DTMB NIM: RTL2836B DTMB + TDA18272 ++ DTMB_NIM_RTL2836B_DTMB_AVALON, ///< DTMB NIM: RTL2836B DTMB + AVALON ++ DTMB_NIM_RTL2836B_DTMB_SUTRE201, ///< DTMB NIM: RTL2836B DTMB + SUTRE201 ++ DTMB_NIM_RTL2836B_DTMB_TDAC7, ///< DTMB NIM: RTL2836B DTMB + ALPS TDAC7 ++ DTMB_NIM_RTL2836B_DTMB_FC0013, ///< DTMB NIM: RTL2836B DTMB + FC0013 ++}; ++ ++ ++ ++ ++ ++/// On/off status ++enum ON_OFF_STATUS ++{ ++ OFF, ///< Off ++ ON, ///< On ++}; ++ ++ ++/// Yes/no status ++enum YES_NO_STATUS ++{ ++ NO, ///< No ++ YES, ///< Yes ++}; ++ ++ ++/// Lock status ++enum LOCK_STATUS ++{ ++ NOT_LOCKED, ///< Not locked ++ LOCKED, ///< Locked ++}; ++ ++ ++/// Loss status ++enum LOSS_STATUS ++{ ++ NOT_LOST, ///< Not lost ++ LOST, ///< Lost ++}; ++ ++ ++/// Function return status ++enum FUNCTION_RETURN_STATUS ++{ ++ FUNCTION_SUCCESS, ///< Execute function successfully. ++ FUNCTION_ERROR, ///< Execute function unsuccessfully. ++}; ++ ++ ++/// Crystal frequency ++enum CRYSTAL_FREQ_HZ ++{ ++ CRYSTAL_FREQ_4000000HZ = 4000000, ///< Crystal frequency = 4.0 MHz ++ CRYSTAL_FREQ_16000000HZ = 16000000, ///< Crystal frequency = 16.0 MHz ++ CRYSTAL_FREQ_16384000HZ = 16384000, ///< Crystal frequency = 16.384 MHz ++ CRYSTAL_FREQ_16457143HZ = 16457143, ///< Crystal frequency = 16.457 MHz ++ CRYSTAL_FREQ_20000000HZ = 20000000, ///< Crystal frequency = 20.0 MHz ++ CRYSTAL_FREQ_20250000HZ = 20250000, ///< Crystal frequency = 20.25 MHz ++ CRYSTAL_FREQ_20480000HZ = 20480000, ///< Crystal frequency = 20.48 MHz ++ CRYSTAL_FREQ_24000000HZ = 24000000, ///< Crystal frequency = 24.0 MHz ++ CRYSTAL_FREQ_25000000HZ = 25000000, ///< Crystal frequency = 25.0 MHz ++ CRYSTAL_FREQ_25200000HZ = 25200000, ///< Crystal frequency = 25.2 MHz ++ CRYSTAL_FREQ_26000000HZ = 26000000, ///< Crystal frequency = 26.0 MHz ++ CRYSTAL_FREQ_26690000HZ = 26690000, ///< Crystal frequency = 26.69 MHz ++ CRYSTAL_FREQ_27000000HZ = 27000000, ///< Crystal frequency = 27.0 MHz ++ CRYSTAL_FREQ_28800000HZ = 28800000, ///< Crystal frequency = 28.8 MHz ++ CRYSTAL_FREQ_32000000HZ = 32000000, ///< Crystal frequency = 32.0 MHz ++ CRYSTAL_FREQ_36000000HZ = 36000000, ///< Crystal frequency = 36.0 MHz ++}; ++ ++ ++/// IF frequency ++enum IF_FREQ_HZ ++{ ++ IF_FREQ_0HZ = 0, ///< IF frequency = 0 MHz ++ IF_FREQ_4000000HZ = 4000000, ///< IF frequency = 4.0 MHz ++ IF_FREQ_4570000HZ = 4570000, ///< IF frequency = 4.57 MHz ++ IF_FREQ_4571429HZ = 4571429, ///< IF frequency = 4.571 MHz ++ IF_FREQ_5000000HZ = 5000000, ///< IF frequency = 5.0 MHz ++ IF_FREQ_36000000HZ = 36000000, ///< IF frequency = 36.0 MHz ++ IF_FREQ_36125000HZ = 36125000, ///< IF frequency = 36.125 MHz ++ IF_FREQ_36150000HZ = 36150000, ///< IF frequency = 36.15 MHz ++ IF_FREQ_36166667HZ = 36166667, ///< IF frequency = 36.167 MHz ++ IF_FREQ_36170000HZ = 36170000, ///< IF frequency = 36.17 MHz ++ IF_FREQ_43750000HZ = 43750000, ///< IF frequency = 43.75 MHz ++ IF_FREQ_44000000HZ = 44000000, ///< IF frequency = 44.0 MHz ++}; ++ ++ ++/// Spectrum mode ++enum SPECTRUM_MODE ++{ ++ SPECTRUM_NORMAL, ///< Normal spectrum ++ SPECTRUM_INVERSE, ///< Inverse spectrum ++}; ++#define SPECTRUM_MODE_NUM 2 ++ ++ ++/// TS interface mode ++enum TS_INTERFACE_MODE ++{ ++ TS_INTERFACE_PARALLEL, ///< Parallel TS interface ++ TS_INTERFACE_SERIAL, ///< Serial TS interface ++}; ++#define TS_INTERFACE_MODE_NUM 2 ++ ++ ++/// Diversity mode ++enum DIVERSITY_MODE ++{ ++ DIVERSITY_OFF, ///< Diversity disable ++ DIVERSITY_ON_MASTER, ///< Diversity enable for Master Demod ++ DIVERSITY_ON_SLAVE, ///< Diversity enable for Slave Demod ++}; ++#define DIVERSITY_MODE_NUM 3 ++ ++ ++ ++ ++ ++/// Base interface module alias ++typedef struct BASE_INTERFACE_MODULE_TAG BASE_INTERFACE_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief Basic I2C reading function pointer ++ ++Upper layer functions will use BASE_FP_I2C_READ() to read ByteNum bytes from I2C device to pReadingBytes buffer. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [out] pReadingBytes Buffer pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Read bytes from I2C device with reading byte number successfully. ++@retval FUNCTION_ERROR Read bytes from I2C device unsuccessfully. ++ ++ ++@note ++ The requirements of BASE_FP_I2C_READ() function are described as follows: ++ -# Follow the I2C format for BASE_FP_I2C_READ(). \n ++ start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ -# Don't allocate memory on pReadingBytes. ++ -# Upper layer functions should allocate memory on pReadingBytes before using BASE_FP_I2C_READ(). ++ -# Need to assign I2C reading funtion to BASE_FP_I2C_READ() for upper layer functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char ReadingBytes[100]; ++ ++ ++ // Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...); ++ ++ ... ++ ++ // Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes. ++ pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*BASE_FP_I2C_READ)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Basic I2C writing function pointer ++ ++Upper layer functions will use BASE_FP_I2C_WRITE() to write ByteNum bytes from pWritingBytes buffer to I2C device. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [in] pWritingBytes Buffer pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Write bytes to I2C device with writing bytes successfully. ++@retval FUNCTION_ERROR Write bytes to I2C device unsuccessfully. ++ ++ ++@note ++ The requirements of BASE_FP_I2C_WRITE() function are described as follows: ++ -# Follow the I2C format for BASE_FP_I2C_WRITE(). \n ++ start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ -# Need to assign I2C writing funtion to BASE_FP_I2C_WRITE() for upper layer functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer. ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char WritingBytes[100]; ++ ++ ++ // Assign implemented I2C writing funciton to BASE_FP_I2C_WRITE in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., CustomI2cWrite, ...); ++ ++ ... ++ ++ // Use I2cWrite() to write 33 bytes from WritingBytes to I2C device. ++ pBaseInterface->I2cWrite(pBaseInterface, 0x20, WritingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*BASE_FP_I2C_WRITE)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Basic waiting function pointer ++ ++Upper layer functions will use BASE_FP_WAIT_MS() to wait WaitTimeMs milliseconds. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] WaitTimeMs Waiting time in millisecond ++ ++ ++@note ++ The requirements of BASE_FP_WAIT_MS() function are described as follows: ++ -# Need to assign a waiting function to BASE_FP_WAIT_MS() for upper layer functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement waiting funciton for BASE_FP_WAIT_MS function pointer. ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ ... ++ ++ return; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ ++ // Assign implemented waiting funciton to BASE_FP_WAIT_MS in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., ..., CustomWaitMs); ++ ++ ... ++ ++ // Use WaitMs() to wait 30 millisecond. ++ pBaseInterface->WaitMs(pBaseInterface, 30); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef void ++(*BASE_FP_WAIT_MS)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief User defined data pointer setting function pointer ++ ++One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for ++custom basic function implementation. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] pUserDefinedData Pointer to user defined data ++ ++ ++@note ++ One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for ++ custom basic function implementation. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ CUSTOM_USER_DEFINED_DATA *pUserDefinedData; ++ ++ ++ // Get user defined data pointer of base interface structure for custom I2C reading function. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData); ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char ReadingBytes[100]; ++ ++ CUSTOM_USER_DEFINED_DATA UserDefinedData; ++ ++ ++ // Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...); ++ ++ ... ++ ++ // Set user defined data pointer of base interface structure for custom basic functions. ++ pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData); ++ ++ // Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes. ++ pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef void ++(*BASE_FP_SET_USER_DEFINED_DATA_POINTER)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void *pUserDefinedData ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief User defined data pointer getting function pointer ++ ++One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for ++custom basic function implementation. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] ppUserDefinedData Pointer to user defined data pointer ++ ++ ++@note ++ One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for ++ custom basic function implementation. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ CUSTOM_USER_DEFINED_DATA *pUserDefinedData; ++ ++ ++ // Get user defined data pointer of base interface structure for custom I2C reading function. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData); ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char ReadingBytes[100]; ++ ++ CUSTOM_USER_DEFINED_DATA UserDefinedData; ++ ++ ++ // Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...); ++ ++ ... ++ ++ // Set user defined data pointer of base interface structure for custom basic functions. ++ pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData); ++ ++ // Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes. ++ pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef void ++(*BASE_FP_GET_USER_DEFINED_DATA_POINTER)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void **ppUserDefinedData ++ ); ++ ++ ++ ++ ++ ++/// Base interface module structure ++struct BASE_INTERFACE_MODULE_TAG ++{ ++ // Variables and function pointers ++ unsigned long I2cReadingByteNumMax; ++ unsigned long I2cWritingByteNumMax; ++ ++ BASE_FP_I2C_READ I2cRead; ++ BASE_FP_I2C_WRITE I2cWrite; ++ BASE_FP_WAIT_MS WaitMs; ++ ++ BASE_FP_SET_USER_DEFINED_DATA_POINTER SetUserDefinedDataPointer; ++ BASE_FP_GET_USER_DEFINED_DATA_POINTER GetUserDefinedDataPointer; ++ ++ ++ // User defined data ++ void *pUserDefinedData; ++}; ++ ++ ++ ++ ++ ++/** ++ ++@brief Base interface builder ++ ++Use BuildBaseInterface() to build base interface for module functions to access basic functions. ++ ++ ++@param [in] ppBaseInterface Pointer to base interface module pointer ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++ ++ ++@note ++ -# One should build base interface before using module functions. ++ -# The I2C reading format is described as follows: ++ start_bit + (device_addr | reading_bit) + reading_byte * byte_num + stop_bit ++ -# The I2cReadingByteNumMax is the maximum byte_num of the I2C reading format. ++ -# The I2C writing format is described as follows: ++ start_bit + (device_addr | writing_bit) + writing_byte * byte_num + stop_bit ++ -# The I2cWritingByteNumMax is the maximum byte_num of the I2C writing format. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer. ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++// Implement waiting funciton for BASE_FP_WAIT_MS function pointer. ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ ... ++ ++ return; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ ++ // Build base interface with the following settings. ++ // ++ // 1. Assign 9 to maximum I2C reading byte number. ++ // 2. Assign 8 to maximum I2C writing byte number. ++ // 3. Assign CustomI2cRead() to basic I2C reading function pointer. ++ // 4. Assign CustomI2cWrite() to basic I2C writing function pointer. ++ // 5. Assign CustomWaitMs() to basic waiting function pointer. ++ // ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, ++ 8, ++ CustomI2cRead, ++ CustomI2cWrite, ++ CustomWaitMs ++ ); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++void ++BuildBaseInterface( ++ BASE_INTERFACE_MODULE **ppBaseInterface, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ unsigned long I2cReadingByteNumMax, ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs ++ ); ++ ++ ++ ++ ++ ++// User data pointer of base interface structure setting and getting functions ++void ++base_interface_SetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void *pUserDefinedData ++ ); ++ ++void ++base_interface_GetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void **ppUserDefinedData ++ ); ++ ++ ++ ++ ++ ++// Math functions ++ ++// Binary and signed integer converter ++unsigned long ++SignedIntToBin( ++ long Value, ++ unsigned char BitNum ++ ); ++ ++long ++BinToSignedInt( ++ unsigned long Binary, ++ unsigned char BitNum ++ ); ++ ++ ++ ++// Arithmetic ++unsigned long ++DivideWithCeiling( ++ unsigned long Dividend, ++ unsigned long Divisor ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++/** ++ ++@mainpage Realtek demod Source Code Manual ++ ++@note ++ -# The Realtek demod API source code is designed for demod IC driver porting. ++ -# The API source code is written in C language without floating-point arithmetic. ++ -# One can use the API to manipulate Realtek demod IC. ++ -# The API will call custom underlayer functions through API base interface module. ++ ++ ++@par Important: ++ -# Please assign API base interface module with custom underlayer functions instead of modifying API source code. ++ -# Please see the example code to understand the relation bewteen API and custom system. ++ ++*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/i2c_bridge.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/i2c_bridge.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/i2c_bridge.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/i2c_bridge.h 2010-10-27 08:17:24.000000000 +0200 +@@ -0,0 +1,122 @@ ++#ifndef __I2C_BRIDGE_H ++#define __I2C_BRIDGE_H ++ ++/** ++ ++@file ++ ++@brief I2C bridge module ++ ++I2C bridge module contains I2C forwarding function pointers. ++ ++*/ ++ ++ ++ ++ ++ ++/// I2C bridge module pre-definition ++typedef struct I2C_BRIDGE_MODULE_TAG I2C_BRIDGE_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief I2C reading command forwarding function pointer ++ ++Tuner upper level functions will use I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD() to send tuner I2C reading command through ++demod. ++ ++ ++@param [in] pI2cBridge The I2C bridge module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Forwarding I2C reading command successfully. ++@retval FUNCTION_ERROR Forwarding I2C reading command unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD() with the corresponding function. ++ ++*/ ++typedef int ++(*I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD)( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief I2C writing command forwarding function pointer ++ ++Tuner upper level functions will use I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD() to send tuner I2C writing command through ++demod. ++ ++ ++@param [in] pI2cBridge The I2C bridge module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [out] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Forwarding I2C writing command successfully. ++@retval FUNCTION_ERROR Forwarding I2C writing command unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD() with the corresponding function. ++ ++*/ ++typedef int ++(*I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD)( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/// I2C bridge module structure ++struct I2C_BRIDGE_MODULE_TAG ++{ ++ // Private variables ++ void *pPrivateData; ++ ++ ++ // I2C bridge function pointers ++ I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ForwardI2cReadingCmd; ///< I2C reading command forwading function pointer ++ I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ForwardI2cWritingCmd; ///< I2C writing command forwading function pointer ++ ++}; ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/Kconfig linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/Kconfig +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/Kconfig 2011-06-03 02:34:20.000000000 +0200 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/Kconfig 2011-06-15 11:42:15.046448622 +0200 +@@ -304,6 +304,12 @@ + help + Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. + ++config DVB_USB_RTL2832U ++ tristate "Realtek RTL2832U DVB-T USB2.0 support" ++ depends on DVB_USB ++ help ++ Realtek RTL2832U DVB-T driver. ++ + config DVB_USB_AF9015 + tristate "Afatech AF9015 DVB-T USB2.0 support" + depends on DVB_USB +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/Makefile linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/Makefile +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/Makefile 2011-06-03 02:34:20.000000000 +0200 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/Makefile 2011-06-15 11:43:11.194185349 +0200 +@@ -70,6 +70,9 @@ + dvb-usb-dtv5100-objs = dtv5100.o + obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o + ++dvb-usb-rtl2832u-objs = demod_rtl2832.o dvbt_demod_base.o dvbt_nim_base.o foundation.o math_mpi.o nim_rtl2832_mxl5007t.o nim_rtl2832_fc2580.o nim_rtl2832_mt2266.o rtl2832u.o rtl2832u_fe.o rtl2832u_io.o tuner_mxl5007t.o tuner_fc2580.o tuner_mt2266.o tuner_tua9001.o nim_rtl2832_tua9001.o tuner_fc0012.o nim_rtl2832_fc0012.o demod_rtl2836.o dtmb_demod_base.o dtmb_nim_base.o nim_rtl2836_fc2580.o nim_rtl2836_mxl5007t.o tuner_e4000.o nim_rtl2832_e4000.o tuner_mt2063.o demod_rtl2840.o tuner_max3543.o nim_rtl2832_mt2063.o nim_rtl2832_max3543.o nim_rtl2840_mt2063.o nim_rtl2840_max3543.o qam_demod_base.o qam_nim_base.o ++obj-$(CONFIG_DVB_USB_RTL2832U) += dvb-usb-rtl2832u.o ++ + dvb-usb-af9015-objs = af9015.o + obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o + +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/math_mpi.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/math_mpi.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/math_mpi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/math_mpi.c 2010-10-12 19:35:18.000000000 +0200 +@@ -0,0 +1,1054 @@ ++/** ++ ++@file ++ ++@brief Mutliple precision integer (MPI) arithmetic definition ++ ++One can use to mutliple precision arithmetic to manipulate large signed integers. ++ ++*/ ++ ++ ++#include "math_mpi.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief Set multiple precision signed integer value. ++ ++Use MpiSetValue() to set multiple precision signed integer MPI value. ++ ++ ++@param [in] pMpiVar Pointer to an MPI variable ++@param [in] Value Value for setting ++ ++ ++@note ++ The MPI bit number will be minimized in MpiSetValue(). ++ ++*/ ++void ++MpiSetValue( ++ MPI *pMpiVar, ++ long Value ++ ) ++{ ++ int i; ++ unsigned char SignedBit; ++ unsigned char ExtensionByte; ++ ++ ++ ++ // Set MPI value according to ansigned value. ++ for(i = 0; i < MPI_LONG_BYTE_NUM; i++) ++ pMpiVar->Value[i] = (unsigned char)((Value >> (MPI_BYTE_SHIFT * i)) & MPI_BYTE_MASK); ++ ++ ++ // Get extension byte according to signed bit. ++ SignedBit = (unsigned char)((Value >> (MPI_LONG_BIT_NUM - 1)) & MPI_BIT_0_MASK); ++ ExtensionByte = (SignedBit == 0x0) ? 0x00 : 0xff; ++ ++ ++ // Extend MPI signed bit with extension byte stuff. ++ for(i = MPI_LONG_BYTE_NUM; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ pMpiVar->Value[i] = ExtensionByte; ++ ++ ++ // Minimize MPI bit number. ++ MpiMinimizeBitNum(pMpiVar); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get multiple precision signed integer value. ++ ++Use MpiGetValue() to get multiple precision unsigned integer MPI value. ++ ++ ++@param [in] MpiVar Pointer to an MPI variable ++@param [out] pValue Pointer to an allocated memory for getting MPI value ++ ++ ++@note ++ The necessary bit number of MPI value must be less than or equal to 32 bits. ++ ++*/ ++void ++MpiGetValue( ++ MPI MpiVar, ++ long *pValue ++ ) ++{ ++ int i; ++ unsigned long Value; ++ ++ ++ ++ // Set value with zero. ++ Value = 0x0; ++ ++ ++ // Combine MPI value bytes into value. ++ for(i = 0; i < MPI_LONG_BYTE_NUM; i++) ++ Value |= MpiVar.Value[i] << (MPI_BYTE_SHIFT * i); ++ ++ ++ // Assigned value to value pointer. ++ *pValue = (long)Value; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set multiple precision signed integer bit value. ++ ++Use MpiSetBit() to set multiple precision signed integer MPI bit value. ++ ++ ++@param [in] pMpiVar Pointer to an MPI variable ++@param [in] BitPosition Bit position with zero-based index ++@param [in] BitValue Bit value for setting ++ ++ ++@note ++ Bit position must be 0 ~ (MPI bit number). ++ ++*/ ++void ++MpiSetBit( ++ MPI *pMpiVar, ++ unsigned long BitPosition, ++ unsigned char BitValue ++ ) ++{ ++ unsigned long TargetBytePos, TargetBitPos; ++ ++ ++ ++ // Calculate target byte and bit position. ++ TargetBytePos = BitPosition / MPI_BYTE_BIT_NUM; ++ TargetBitPos = BitPosition % MPI_BYTE_BIT_NUM; ++ ++ ++ // Set MPI bit value according to calculated target byte and bit position. ++ pMpiVar->Value[TargetBytePos] &= (unsigned char)(~(0x1 << TargetBitPos)); ++ pMpiVar->Value[TargetBytePos] |= (BitValue & MPI_BIT_0_MASK) << TargetBitPos; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++/** ++ ++@brief Get multiple precision signed integer bit value. ++ ++Use MpiGetBit() to get multiple precision unsigned integer MPI bit value. ++ ++ ++@param [in] MpiVar Pointer to an MPI variable ++@param [in] BitPosition Bit position with zero-based index ++@param [out] pBitValue Pointer to an allocated memory for getting MPI bit value ++ ++ ++@note ++ Bit position must be 0 ~ (MPI bit number). ++ ++*/ ++void ++MpiGetBit( ++ MPI MpiVar, ++ unsigned long BitPosition, ++ unsigned char *pBitValue ++ ) ++{ ++ unsigned long TargetBytePos, TargetBitPos; ++ ++ ++ ++ // Calculate target byte and bit position. ++ TargetBytePos = BitPosition / MPI_BYTE_BIT_NUM; ++ TargetBitPos = BitPosition % MPI_BYTE_BIT_NUM; ++ ++ ++ // Get MPI bit value according to calculated target byte and bit position. ++ *pBitValue = (MpiVar.Value[TargetBytePos] >> TargetBitPos) & MPI_BIT_0_MASK; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get multiple precision signed integer signed bit value. ++ ++Use MpiGetBit() to get multiple precision unsigned integer MPI signed bit value. ++ ++ ++@param [in] MpiVar Pointer to an MPI variable ++@param [out] pSignedBitValue Pointer to an allocated memory for getting MPI signed bit value ++ ++*/ ++void ++MpiGetSignedBit( ++ MPI MpiVar, ++ unsigned char *pSignedBitValue ++ ) ++{ ++ // Get MPI variable signed bit. ++ MpiGetBit(MpiVar, MPI_VALUE_BIT_NUM_MAX - 1, pSignedBitValue); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Assign multiple precision signed integer with another one. ++ ++Use MpiAssign() to assign multiple precision signed integer with another one. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++ ++ ++@note ++ The result bit number will be minimized in MpiAssign(). ++ ++*/ ++void ++MpiAssign( ++ MPI *pResult, ++ MPI Operand ++ ) ++{ ++ unsigned int i; ++ ++ ++ ++ // Copy value bytes from operand to result. ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ pResult->Value[i] = Operand.Value[i]; ++ ++ ++ // Minimize result bit nubmer. ++ MpiMinimizeBitNum(pResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Minus unary multiple precision signed integer. ++ ++Use MpiUnaryMinus() to minus unary multiple precision signed integer. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++ ++ ++@note ++ The result bit number will be minimized in MpiUnaryMinus(). ++ ++*/ ++void ++MpiUnaryMinus( ++ MPI *pResult, ++ MPI Operand ++ ) ++{ ++ unsigned int i; ++ MPI Const; ++ ++ ++ ++ // Set result value byte with operand bitwise complement value byte. ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ pResult->Value[i] = ~Operand.Value[i]; ++ ++ ++ // Add result with 0x1. ++ // Note: MpiAdd() will minimize result bit number. ++ MpiSetValue(&Const, 0x1); ++ MpiAdd(pResult, *pResult, Const); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Add multiple precision signed integers. ++ ++Use MpiAdd() to add multiple precision signed integers. ++ ++ ++@param [out] pSum Pointer to an allocated memory for storing sum ++@param [in] Augend Augend ++@param [in] Addend Addend ++ ++ ++@note ++ The sum bit number will be minimized in MpiAdd(). ++ ++*/ ++void ++MpiAdd( ++ MPI *pSum, ++ MPI Augend, ++ MPI Addend ++ ) ++{ ++ unsigned int i; ++ unsigned long MiddleResult; ++ unsigned char Carry; ++ ++ ++ // Add augend and addend to sum form value LSB byte to value MSB byte. ++ Carry = 0; ++ ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ { ++ // Set current sum value byte and determine carry. ++ MiddleResult = Augend.Value[i] + Addend.Value[i] + Carry; ++ pSum->Value[i] = (unsigned char)(MiddleResult & MPI_BYTE_MASK); ++ Carry = (unsigned char)((MiddleResult >> MPI_BYTE_SHIFT) & MPI_BYTE_MASK); ++ } ++ ++ ++ // Minimize sum bit nubmer. ++ MpiMinimizeBitNum(pSum); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief subtract multiple precision signed integers. ++ ++Use MpiSub() to subtract multiple precision signed integers. ++ ++ ++@param [out] pDifference Pointer to an allocated memory for storing difference ++@param [in] Minuend Minuend ++@param [in] Subtrahend Subtrahend ++ ++ ++@note ++ The difference bit number will be minimized in MpiSub(). ++ ++*/ ++void ++MpiSub( ++ MPI *pDifference, ++ MPI Minuend, ++ MPI Subtrahend ++ ) ++{ ++ MPI MiddleResult; ++ ++ ++ ++ // Take subtrahend unary minus value. ++ MpiUnaryMinus(&MiddleResult, Subtrahend); ++ ++ ++ // Add minuend and subtrahend unary minus value to difference. ++ // Note: MpiAdd() will minimize result bit number. ++ MpiAdd(pDifference, Minuend, MiddleResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Multiply arbitrary precision signed integers. ++ ++Use MpiMul() to multiply arbitrary precision signed integers. ++ ++ ++@param [out] pProduct Pointer to an allocated memory for storing product ++@param [in] Multiplicand Multiplicand ++@param [in] Multiplicator Multiplicator ++ ++ ++@note ++ -# The sum of multiplicand and multiplicator bit number must be less MPI_VALUE_BIT_NUM_MAX. ++ -# The product bit number will be minimized in MpiMul(). ++ ++*/ ++void ++MpiMul( ++ MPI *pProduct, ++ MPI Multiplicand, ++ MPI Multiplicator ++ ) ++{ ++ int i; ++ ++ unsigned char MultiplicandSignedBit, MultiplicatorSignedBit; ++ MPI MultiplicandAbs, MultiplicatorAbs; ++ ++ unsigned char CurrentBit; ++ ++ ++ ++ // Get multiplicand signed bit. ++ MpiGetSignedBit(Multiplicand, &MultiplicandSignedBit); ++ ++ // Take absolute value of multiplicand. ++ if(MultiplicandSignedBit == 0x0) ++ MpiAssign(&MultiplicandAbs, Multiplicand); ++ else ++ MpiUnaryMinus(&MultiplicandAbs, Multiplicand); ++ ++ ++ // Get multiplicator signed bit. ++ MpiGetSignedBit(Multiplicator, &MultiplicatorSignedBit); ++ ++ // Take absolute value of multiplicator. ++ if(MultiplicatorSignedBit == 0x0) ++ MpiAssign(&MultiplicatorAbs, Multiplicator); ++ else ++ MpiUnaryMinus(&MultiplicatorAbs, Multiplicator); ++ ++ ++ // Multiply multiplicand and multiplicator from LSB bit to MSB bit. ++ MpiSetValue(pProduct, 0x0); ++ ++ for(i = MPI_VALUE_BIT_NUM_MAX - 1; i > -1; i--) ++ { ++ // Shift product toward left with one bit. ++ MpiLeftShift(pProduct, *pProduct, 1); ++ ++ // Get current absolute multiplicator bit value. ++ MpiGetBit(MultiplicatorAbs, i, &CurrentBit); ++ ++ // If current multiplicator bit is 0x1, add absolute multiplicand value to product. ++ // Note: MpiAdd() will minimize result bit number. ++ if(CurrentBit == 0x1) ++ MpiAdd(pProduct, *pProduct, MultiplicandAbs); ++ } ++ ++ ++ // Determine the signed bit of product according to signed bits of multiplicand and multiplicator. ++ // Note: MpiUnaryMinus() will minimize result bit number. ++ if(MultiplicandSignedBit != MultiplicatorSignedBit) ++ MpiUnaryMinus(pProduct, *pProduct); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Divide arbitrary precision signed integers. ++ ++Use MpiDiv() to divide arbitrary precision signed integers. ++ ++ ++@param [out] pQuotient Pointer to an allocated memory for storing quotient ++@param [out] pRemainder Pointer to an allocated memory for storing remainder ++@param [in] Dividend Dividend ++@param [in] Divisor Divisor ++ ++ ++@note ++ -# The dividend bit number must be minimized. ++ -# The divisor must be not equal to zero. ++ -# The product bit number will be minimized in MpiDiv(). ++ ++*/ ++void ++MpiDiv( ++ MPI *pQuotient, ++ MPI *pRemainder, ++ MPI Dividend, ++ MPI Divisor ++ ) ++{ ++ unsigned int i; ++ ++ unsigned char DividendSignedBit, DivisorSignedBit; ++ MPI DividendAbs, DivisorAbs; ++ ++ unsigned long PrimaryDividendBitNum; ++ unsigned char ShiftBit; ++ ++ MPI Const; ++ MPI MiddleResult; ++ ++ ++ ++ // Get dividend signed bit. ++ MpiGetSignedBit(Dividend, &DividendSignedBit); ++ ++ // Take absolute value of dividend. ++ if(DividendSignedBit == 0x0) ++ MpiAssign(&DividendAbs, Dividend); ++ else ++ MpiUnaryMinus(&DividendAbs, Dividend); ++ ++ ++ // Get divisor signed bit. ++ MpiGetSignedBit(Divisor, &DivisorSignedBit); ++ ++ // Take absolute value of divisor. ++ if(DivisorSignedBit == 0x0) ++ MpiAssign(&DivisorAbs, Divisor); ++ else ++ MpiUnaryMinus(&DivisorAbs, Divisor); ++ ++ ++ // Get primary absolute dividend bit number. ++ PrimaryDividendBitNum = DividendAbs.BitNum; ++ ++ ++ // Get quotient and remainder by division algorithm. ++ MpiSetValue(pQuotient, 0x0); ++ MpiSetValue(pRemainder, 0x0); ++ ++ for(i = 0; i < PrimaryDividendBitNum; i++) ++ { ++ // Shift quotient toward left with one bit. ++ // Note: MpiLeftShift() will minimize result bit number. ++ MpiLeftShift(pQuotient, *pQuotient, 1); ++ ++ // Shift remainder toward left with one bit. ++ MpiLeftShift(pRemainder, *pRemainder, 1); ++ ++ // Shift absolute dividend toward left with one bit. ++ MpiLeftShift(&DividendAbs, DividendAbs, 1); ++ ++ // Set remainder LSB according to absolute dividend. ++ MpiGetBit(DividendAbs, PrimaryDividendBitNum, &ShiftBit); ++ MpiSetBit(pRemainder, 0, ShiftBit); ++ ++ // If remainder is greater than or equal to absolute divisor, ++ // substract absolute divisor from remainder and set quotient LSB with one. ++ if(MpiGreaterThan(*pRemainder, DivisorAbs) || MpiEqualTo(*pRemainder, DivisorAbs)) ++ { ++ MpiSub(pRemainder, *pRemainder, DivisorAbs); ++ MpiSetBit(pQuotient, 0, 0x1); ++ } ++ } ++ ++ ++ // Modify quotient according to dividend signed bit, divisor signed bit, and remainder. ++ ++ // Determine the signed bit of quotient. ++ if(DividendSignedBit != DivisorSignedBit) ++ { ++ // Take unary minus quotient. ++ // Note: MpiUnaryMinus() will minimize result bit number. ++ MpiUnaryMinus(pQuotient, *pQuotient); ++ ++ // If remainder is greater than zero, subtract 1 from quotient. ++ // Note: MpiSub() will minimize result bit number. ++ MpiSetValue(&Const, 0x0); ++ ++ if(MpiGreaterThan(*pRemainder, Const)) ++ { ++ MpiSetValue(&Const, 0x1); ++ MpiSub(pQuotient, *pQuotient, Const); ++ } ++ } ++ ++ ++ // Modify remainder according to dividend, divisor, and quotient. ++ ++ // Remainder = dividend - divisor * quotient; ++ // Note: MpiSub() will minimize result bit number. ++ MpiMul(&MiddleResult, Divisor, *pQuotient); ++ MpiSub(pRemainder, Dividend, MiddleResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Shift multiple precision signed integer toward right. ++ ++Use MpiRightShift() to shift arbitrary precision signed integer toward right with assigned bit number. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++@param [in] ShiftBitNum Shift bit number ++ ++ ++@note ++ -# The result MSB bits will be stuffed with signed bit ++ -# The result bit number will be minimized in MpiRightShift(). ++ ++*/ ++void ++MpiRightShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ) ++{ ++ unsigned int i; ++ unsigned long StuffBitNum; ++ unsigned char CurrentBit; ++ unsigned char SignedBit; ++ ++ ++ ++ // Determine stuff bit number according to shift bit nubmer. ++ StuffBitNum = (ShiftBitNum < MPI_VALUE_BIT_NUM_MAX) ? ShiftBitNum : MPI_VALUE_BIT_NUM_MAX; ++ ++ ++ // Copy operand bits to result with stuff bit number. ++ for(i = 0; i < (MPI_VALUE_BIT_NUM_MAX - StuffBitNum); i++) ++ { ++ MpiGetBit(Operand, i + StuffBitNum, &CurrentBit); ++ MpiSetBit(pResult, i, CurrentBit); ++ } ++ ++ ++ // Get operand signed bit. ++ MpiGetSignedBit(Operand, &SignedBit); ++ ++ ++ // Stuff result MSB bits with signed bit. ++ for(i = (MPI_VALUE_BIT_NUM_MAX - StuffBitNum); i < MPI_VALUE_BIT_NUM_MAX; i++) ++ MpiSetBit(pResult, i, SignedBit); ++ ++ ++ // Minimize result bit number. ++ MpiMinimizeBitNum(pResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Shift multiple precision signed integer toward left. ++ ++Use MpiLeftShift() to shift arbitrary precision signed integer toward left with assigned bit number. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++@param [in] ShiftBitNum Shift bit number ++ ++ ++@note ++ The result bit number will be minimized in MpiLeftShift(). ++ ++*/ ++void ++MpiLeftShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ) ++{ ++ unsigned int i; ++ unsigned long StuffBitNum; ++ unsigned char CurrentBit; ++ ++ ++ // Determine stuff bit number according to shift bit nubmer. ++ StuffBitNum = (ShiftBitNum < MPI_VALUE_BIT_NUM_MAX) ? ShiftBitNum : MPI_VALUE_BIT_NUM_MAX; ++ ++ ++ // Stuff result LSB bits with zeros ++ for(i = 0; i < StuffBitNum; i++) ++ MpiSetBit(pResult, i, 0x0); ++ ++ ++ // Copy operand bits to result with stuff bit number. ++ for(i = StuffBitNum; i < MPI_VALUE_BIT_NUM_MAX; i++) ++ { ++ MpiGetBit(Operand, i - StuffBitNum, &CurrentBit); ++ MpiSetBit(pResult, i, CurrentBit); ++ } ++ ++ ++ // Minimize result bit number. ++ MpiMinimizeBitNum(pResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Compare multiple precision signed integes with equal-to criterion. ++ ++Use MpiEqualTo() to compare multiple precision signed integes with equal-to criterion. ++ ++ ++@param [in] MpiLeft Left MPI ++@param [in] MpiRight Right MPI ++ ++ ++@retval MPI_NO "Left MPI == Right MPI" is false. ++@retval MPI_YES "Left MPI == Right MPI" is true. ++ ++ ++@note ++ The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration. ++ ++*/ ++int ++MpiEqualTo( ++ MPI MpiLeft, ++ MPI MpiRight ++ ) ++{ ++ unsigned int i; ++ ++ ++ ++ // Check not-equal-to condition. ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ { ++ if(MpiLeft.Value[i] != MpiRight.Value[i]) ++ goto condition_others; ++ } ++ ++ ++ // Right MPI is greater than left MPI. ++ return MPI_YES; ++ ++ ++condition_others: ++ ++ ++ // Other conditions. ++ return MPI_NO; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Compare multiple precision signed integes with greater-than criterion. ++ ++Use MpiGreaterThan() to compare multiple precision signed integes with greater-than criterion. ++ ++ ++@param [in] MpiLeft Left MPI ++@param [in] MpiRight Right MPI ++ ++ ++@retval MPI_NO "Left MPI > Right MPI" is false. ++@retval MPI_YES "Left MPI > Right MPI" is true. ++ ++ ++@note ++ The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration. ++ ++*/ ++int ++MpiGreaterThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ) ++{ ++ MPI MiddleResult; ++ unsigned char SignedBit; ++ ++ ++ ++ // Check equal-to condition. ++ if(MpiEqualTo(MpiLeft, MpiRight) == MPI_YES) ++ goto condition_others; ++ ++ ++ // Subtract right MPI form left MPI. ++ MpiSub(&MiddleResult, MpiLeft, MpiRight); ++ ++ ++ // Check less-than condition. ++ MpiGetSignedBit(MiddleResult, &SignedBit); ++ ++ if(SignedBit == 0x1) ++ goto condition_others; ++ ++ ++ // Right MPI is greater than left MPI. ++ return MPI_YES; ++ ++ ++condition_others: ++ ++ ++ // Other conditions. ++ return MPI_NO; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Compare multiple precision signed integes with less-than criterion. ++ ++Use MpiLessThan() to compare multiple precision signed integes with less-than criterion. ++ ++ ++@param [in] MpiLeft Left MPI ++@param [in] MpiRight Right MPI ++ ++ ++@retval MPI_NO "Left MPI < Right MPI" is false. ++@retval MPI_YES "Left MPI < Right MPI" is true. ++ ++ ++@note ++ The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration. ++ ++*/ ++int ++MpiLessThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ) ++{ ++ MPI MiddleResult; ++ unsigned char SignedBit; ++ ++ ++ ++ // Check equal-to condition. ++ if(MpiEqualTo(MpiLeft, MpiRight) == MPI_YES) ++ goto condition_others; ++ ++ ++ // Subtract right MPI form left MPI. ++ MpiSub(&MiddleResult, MpiLeft, MpiRight); ++ ++ ++ // Check greater-than condition. ++ MpiGetSignedBit(MiddleResult, &SignedBit); ++ ++ if(SignedBit == 0x0) ++ goto condition_others; ++ ++ ++ // Right MPI is less than left MPI. ++ return MPI_YES; ++ ++ ++condition_others: ++ ++ ++ // Other conditions. ++ return MPI_NO; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Minimize multiple precision signed integer bit number. ++ ++Use MpiMinimizeBitNum() to minimize multiple precision signed integer MPI bit number. ++ ++ ++@param [in] pMpiVar Pointer to an allocated memory for storing result ++ ++*/ ++void ++MpiMinimizeBitNum( ++ MPI *pMpiVar ++ ) ++{ ++ int i; ++ unsigned char SignedBit; ++ unsigned char BitValue; ++ ++ ++ ++ // Get signed bit form MPI; ++ MpiGetSignedBit(*pMpiVar, &SignedBit); ++ ++ ++ // Find MPI MSB position. ++ // Note: The MSB of signed integer is the rightest signed bit. ++ for(i = (MPI_VALUE_BIT_NUM_MAX - 2); i > -1; i--) ++ { ++ // Get current bit value. ++ MpiGetBit(*pMpiVar, i, &BitValue); ++ ++ // Compare current bit with signed bit. ++ if(BitValue != SignedBit) ++ break; ++ } ++ ++ ++ // Set MPI bit number. ++ // Note: MPI bit number must be greater than one. ++ pMpiVar->BitNum = (i == -1) ? 2 : (i + 2); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++/** ++ ++@brief Calculate multiple precision signed integer logarithm with base 2. ++ ++Use MpiMinimizeBitNum() to calculate multiple precision signed integer logarithm with base 2. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result (unit: pow(2, - ResultFracBitNum)) ++@param [in] MpiVar MPI variable for calculating ++@param [in] ResultFracBitNum Result fraction bit number ++ ++ ++@note ++ -# MPI variable bit number must be minimized. ++ -# MPI variable bit number must be less than (MPI_VALUE_BIT_NUM_MAX / 2 + 1). ++ -# MPI variable must be greater than zero. ++ -# If MPI variable is zero, the result is zero in MpiLog2(). ++ -# The result bit number will be minimized in MpiLog2(). ++ ++*/ ++void ++MpiLog2( ++ MPI *pResult, ++ MPI MpiVar, ++ unsigned long ResultFracBitNum ++ ) ++{ ++ unsigned int i; ++ MPI MiddleResult; ++ unsigned char BitValue; ++ ++ ++ ++ // Get integer part of MPI logarithm result with base 2. ++ MpiSetValue(pResult, (long)(MpiVar.BitNum - 2)); ++ ++ ++ // Get fraction part of MPI logarithm result with base 2 by logarithm algorithm. ++ // Note: Take middle result format as follows: ++ // x x . x x ~ x ++ // (integer part 2 bits) . (fraction part MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM bits) ++ ++ // Set middle result with initial value. ++ MpiLeftShift(&MiddleResult, MpiVar, (MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM - MpiVar.BitNum + 2)); ++ ++ // Calculate result fraction bits. ++ for(i = 0; i < ResultFracBitNum; i++) ++ { ++ // Shift result toward left with one bit. ++ // Note: MpiLeftShift() will minimize result bit number. ++ MpiLeftShift(pResult, *pResult, 1); ++ ++ // Square middle result. ++ MpiMul(&MiddleResult, MiddleResult, MiddleResult); ++ ++ // Shift middle result toward right with fraction bit num. ++ MpiRightShift(&MiddleResult, MiddleResult, MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM); ++ ++ // Get middle result integer part bit 1. ++ MpiGetBit(MiddleResult, MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM + 1, &BitValue); ++ ++ // If middle result integer part bit 1 is equal to 0x1, ++ // shift middle result with one bit toward right and set result LSB with one. ++ if(BitValue == 0x1) ++ { ++ MpiRightShift(&MiddleResult, MiddleResult, 1); ++ MpiSetBit(pResult, 0, 0x1); ++ } ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/math_mpi.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/math_mpi.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/math_mpi.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/math_mpi.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,201 @@ ++#ifndef __MATH_MPI_H ++#define __MATH_MPI_H ++ ++/** ++ ++@file ++ ++@brief Mutliple precision integer (MPI) arithmetic declaration ++ ++One can use to mutliple precision arithmetic to manipulate large signed integers. ++ ++*/ ++ ++ ++ ++ ++ ++// Constant ++#define MPI_BYTE_BIT_NUM 8 ++#define MPI_LONG_BYTE_NUM 4 ++#define MPI_LONG_BIT_NUM 32 ++ ++ ++ ++// Mask and shift ++#define MPI_BYTE_MASK 0xff ++#define MPI_BYTE_SHIFT 8 ++ ++#define MPI_BIT_0_MASK 0x1 ++#define MPI_BIT_7_SHIFT 7 ++ ++ ++ ++// Multiple precision integer definition ++#define MPI_VALUE_BYTE_NUM_MAX 10 ///< Maximum MPI value byte number ++#define MPI_VALUE_BIT_NUM_MAX (MPI_VALUE_BYTE_NUM_MAX * MPI_BYTE_BIT_NUM) ///< Maximum MPI value bit number ++ ++/// Multiple precision integer structure ++typedef struct ++{ ++ unsigned long BitNum; ++ unsigned char Value[MPI_VALUE_BYTE_NUM_MAX]; ++} ++MPI; ++ ++ ++ ++/// MPI yes/no status ++enum MPI_YES_NO_STATUS ++{ ++ MPI_NO, ///< No ++ MPI_YES, ///< Yes ++}; ++ ++ ++ ++// Logarithm with base 2 ++#define MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM (MPI_VALUE_BIT_NUM_MAX / 2 - 2) ++ ++ ++ ++ ++ ++// MPI access ++void ++MpiSetValue( ++ MPI *pMpiVar, ++ long Value ++ ); ++ ++void ++MpiGetValue( ++ MPI MpiVar, ++ long *pValue ++ ); ++ ++void ++MpiSetBit( ++ MPI *pMpiVar, ++ unsigned long BitPosition, ++ unsigned char BitValue ++ ); ++ ++void ++MpiGetBit( ++ MPI MpiVar, ++ unsigned long BitPosition, ++ unsigned char *pBitValue ++ ); ++ ++void ++MpiGetSignedBit( ++ MPI MpiVar, ++ unsigned char *pSignedBit ++ ); ++ ++ ++ ++// MPI operator ++void ++MpiAssign( ++ MPI *pResult, ++ MPI Operand ++ ); ++ ++void ++MpiUnaryMinus( ++ MPI *pResult, ++ MPI Operand ++ ); ++ ++void ++MpiAdd( ++ MPI *pSum, ++ MPI Augend, ++ MPI Addend ++ ); ++ ++void ++MpiSub( ++ MPI *pDifference, ++ MPI Minuend, ++ MPI Subtrahend ++ ); ++ ++void ++MpiMul( ++ MPI *pProduct, ++ MPI Multiplicand, ++ MPI Multiplicator ++ ); ++ ++void ++MpiDiv( ++ MPI *pQuotient, ++ MPI *pRemainder, ++ MPI Dividend, ++ MPI Divisor ++ ); ++ ++void ++MpiRightShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ); ++ ++void ++MpiLeftShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ); ++ ++int ++MpiEqualTo( ++ MPI MpiLeft, ++ MPI MpiRight ++ ); ++ ++int ++MpiGreaterThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ); ++ ++int ++MpiLessThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ); ++ ++void ++MpiMinimizeBitNum( ++ MPI *pMpiVar ++ ); ++ ++ ++ ++// MPI special function ++void ++MpiLog2( ++ MPI *pResult, ++ MPI MpiVar, ++ unsigned long ResultFracBitNum ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,370 @@ ++/** ++ ++@file ++ ++@brief RTL2836 MxL5007T NIM module definition ++ ++One can manipulate RTL2836 MxL5007T NIM through RTL2836 MxL5007T NIM module. ++RTL2836 MxL5007T NIM module is derived from DTMB NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2836_mxl5007t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2836 MxL5007T NIM module builder ++ ++Use BuildRtl2836Mxl5007tModule() to build RTL2836 MxL5007T NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2836 MxL5007T NIM module pointer ++@param [in] pDtmbNimModuleMemory Pointer to an allocated DTMB NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] pRtl2836ExtraModuleMemory Pointer to an allocated RTL2836 extra module memory ++@param [in] DemodDeviceAddr RTL2836 I2C device address ++@param [in] DemodCrystalFreqHz RTL2836 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2836 TS interface mode ++@param [in] DemodUpdateFuncRefPeriodMs RTL2836 update function reference period in millisecond ++@param [in] DemodIsFunc1Enabled RTL2836 Function 1 enabling status for setting ++@param [in] pMxl5007tExtraModuleMemory Pointer to an allocated MxL5007T extra module memory ++@param [in] TunerDeviceAddr MxL5007T I2C device address ++@param [in] TunerCrystalFreqHz MxL5007T crystal frequency in Hz ++@param [in] TunerLoopThroughMode MxL5007T loop-through mode ++@param [in] TunerClkOutMode MxL5007T clock output mode ++@param [in] TunerClkOutAmpMode MxL5007T clock output amplitude mode ++ ++ ++@note ++ -# One should call BuildRtl2836Mxl5007tModule() to build RTL2836 MxL5007T NIM module before using it. ++ ++*/ ++void ++BuildRtl2836Mxl5007tModule( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned char I2cReadingByteNumMax, // Base interface dependence ++ unsigned char I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ RTL2836_EXTRA_MODULE *pRtl2836ExtraModuleMemory, // Demod dependence ++ unsigned char DemodDeviceAddr, ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ MXL5007T_EXTRA_MODULE *pMxl5007tExtraModuleMemory, // Tuner dependence ++ unsigned char TunerDeviceAddr, ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ) ++{ ++ DTMB_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDtmbNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Set NIM extra module pointer. ++ pNim->pExtra = INVALID_POINTER_VALUE; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DTMB_NIM_RTL2836_MXL5007T; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2836 demod module. ++ BuildRtl2836Module( ++ &pNim->pDemod, ++ &pNim->DtmbDemodModuleMemory, ++ pRtl2836ExtraModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build MxL5007T tuner module. ++ BuildMxl5007tModule( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ pMxl5007tExtraModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2836_MXL5007T_STANDARD_MODE_DEFAULT, ++ RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT, ++ RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT, ++ TunerLoopThroughMode, ++ TunerClkOutMode, ++ TunerClkOutAmpMode, ++ RTL2836_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT ++ ); ++ ++ ++ // Set NIM module variables. ++ pNim->DemodTsInterfaceMode = DemodTsInterfaceMode; ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dtmb_nim_default_GetNimType; ++ pNim->GetParameters = dtmb_nim_default_GetParameters; ++ pNim->IsSignalPresent = dtmb_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dtmb_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dtmb_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dtmb_nim_default_GetSignalQuality; ++ pNim->GetBer = dtmb_nim_default_GetBer; ++ pNim->GetPer = dtmb_nim_default_GetPer; ++ pNim->GetSnrDb = dtmb_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dtmb_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dtmb_nim_default_GetCrOffsetHz; ++ pNim->GetSignalInfo = dtmb_nim_default_GetSignalInfo; ++ pNim->UpdateFunction = dtmb_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2836_mxl5007t_Initialize; ++ pNim->SetParameters = rtl2836_mxl5007t_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2836_mxl5007t_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DTMB_TARGET_VAL, 0x38 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra; ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner bandwidth mode with 8 MHz. ++ if(pTunerExtra->SetBandwidthMode(pTuner, MXL5007T_BANDWIDTH_8000000HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Set TS interface according to TS interface mode. ++ switch(pNim->DemodTsInterfaceMode) ++ { ++ case TS_INTERFACE_PARALLEL: ++ ++ // Set demod TS interface with parallel mode. ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_SERIAL, 0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_CDIV_PH0, 15) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_CDIV_PH1, 15) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ ++ ++ default: ++ case TS_INTERFACE_SERIAL: ++ ++ // Set demod TS interface with serial mode. ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_SERIAL, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_CDIV_PH0, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_CDIV_PH1, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2836_mxl5007t_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra; ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, MXL5007T_BANDWIDTH_8000000HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,798 @@ ++/** ++ ++@file ++ ++@brief RTL2832 E4000 NIM module definition ++ ++One can manipulate RTL2832 E4000 NIM through RTL2832 E4000 NIM module. ++RTL2832 E4000 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_e4000.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 E4000 NIM module builder ++ ++Use BuildRtl2832E4000Module() to build RTL2832 E4000 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 E4000 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr E4000 I2C device address ++@param [in] TunerCrystalFreqHz E4000 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832E4000Module() to build RTL2832 E4000 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832E4000Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_E4000; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build E4000 tuner module. ++ BuildE4000Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_e4000_Initialize; ++ pNim->SetParameters = rtl2832_e4000_SetParameters; ++ pNim->UpdateFunction = rtl2832_e4000_UpdateFunction; ++ ++ ++ // Initialize NIM extra module variables. ++ pNimExtra->TunerModeUpdateWaitTimeMax = ++ DivideWithCeiling(RTL2832_E4000_TUNER_MODE_UPDATE_WAIT_TIME_MS, DemodUpdateFuncRefPeriodMs); ++ pNimExtra->TunerModeUpdateWaitTime = 0; ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_e4000_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x18 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x8 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x18 }, ++ ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x14 }, ++ {DVBT_THD_DW1, 0xec }, ++ ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++ ++ {DVBT_REG_GPE, 0x1 }, ++ {DVBT_REG_GPO, 0x1 }, ++ {DVBT_REG_MONSEL, 0x1 }, ++ {DVBT_REG_MON, 0x1 }, ++ {DVBT_REG_4MSEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_e4000_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ E4000_EXTRA_MODULE *pTunerExtra; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long TunerBandwidthHz; ++ ++ int RfFreqKhz; ++ int BandwidthKhz; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.E4000); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthHz according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthHz = E4000_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthHz = E4000_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthHz = E4000_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth Hz with TunerBandwidthHz. ++ if(pTunerExtra->SetBandwidthHz(pTuner, TunerBandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner gain mode with normal condition for update procedure. ++ RfFreqKhz = (int)((RfFreqHz + 500) / 1000); ++ BandwidthKhz = (int)((TunerBandwidthHz + 500) / 1000); ++ ++// if(E4000_nominal(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ if(E4000_sensitivity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++// if(E4000_linearity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_e4000_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Increase tuner mode update waiting time. ++ pNimExtra->TunerModeUpdateWaitTime += 1; ++ ++ ++ // Check if need to update tuner mode according to update waiting time. ++ if(pNimExtra->TunerModeUpdateWaitTime == pNimExtra->TunerModeUpdateWaitTimeMax) ++ { ++ // Reset update waiting time. ++ pNimExtra->TunerModeUpdateWaitTime = 0; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Update tuner mode. ++ if(rtl2832_e4000_UpdateTunerMode(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update tuner mode. ++ ++One can use rtl2832_e4000_UpdateTunerMode() to update tuner mode. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update tuner mode successfully. ++@retval FUNCTION_ERROR Update tuner mode unsuccessfully. ++ ++*/ ++int ++rtl2832_e4000_UpdateTunerMode( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ static const long LnaGainTable[RTL2832_E4000_LNA_GAIN_TABLE_LEN][RTL2832_E4000_LNA_GAIN_BAND_NUM] = ++ { ++ // VHF Gain, UHF Gain, ReadingByte ++ {-50, -50 }, // 0x0 ++ {-25, -25 }, // 0x1 ++ {-50, -50 }, // 0x2 ++ {-25, -25 }, // 0x3 ++ {0, 0 }, // 0x4 ++ {25, 25 }, // 0x5 ++ {50, 50 }, // 0x6 ++ {75, 75 }, // 0x7 ++ {100, 100 }, // 0x8 ++ {125, 125 }, // 0x9 ++ {150, 150 }, // 0xa ++ {175, 175 }, // 0xb ++ {200, 200 }, // 0xc ++ {225, 250 }, // 0xd ++ {250, 280 }, // 0xe ++ {250, 280 }, // 0xf ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long LnaGainAddTable[RTL2832_E4000_LNA_GAIN_ADD_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ NO_USE, // 0x0 ++ NO_USE, // 0x1 ++ NO_USE, // 0x2 ++ 0, // 0x3 ++ NO_USE, // 0x4 ++ 20, // 0x5 ++ NO_USE, // 0x6 ++ 70, // 0x7 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long MixerGainTable[RTL2832_E4000_MIXER_GAIN_TABLE_LEN][RTL2832_E4000_MIXER_GAIN_BAND_NUM] = ++ { ++ // VHF Gain, UHF Gain, ReadingByte ++ {90, 40 }, // 0x0 ++ {170, 120 }, // 0x1 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage1GainTable[RTL2832_E4000_IF_STAGE_1_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ -30, // 0x0 ++ 60, // 0x1 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage2GainTable[RTL2832_E4000_IF_STAGE_2_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage3GainTable[RTL2832_E4000_IF_STAGE_3_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage4GainTable[RTL2832_E4000_IF_STAGE_4_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 10, // 0x1 ++ 20, // 0x2 ++ 20, // 0x3 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage5GainTable[RTL2832_E4000_IF_STAGE_5_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ 120, // 0x4 ++ 120, // 0x5 ++ 120, // 0x6 ++ 120, // 0x7 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage6GainTable[RTL2832_E4000_IF_STAGE_6_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ 120, // 0x4 ++ 120, // 0x5 ++ 120, // 0x6 ++ 120, // 0x7 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ E4000_EXTRA_MODULE *pTunerExtra; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long RfFreqHz; ++ int RfFreqKhz; ++ unsigned long BandwidthHz; ++ int BandwidthKhz; ++ ++ unsigned char ReadingByte; ++ int BandIndex; ++ ++ unsigned char TunerBitsLna, TunerBitsLnaAdd, TunerBitsMixer; ++ unsigned char TunerBitsIfStage1, TunerBitsIfStage2, TunerBitsIfStage3, TunerBitsIfStage4; ++ unsigned char TunerBitsIfStage5, TunerBitsIfStage6; ++ ++ long TunerGainLna, TunerGainLnaAdd, TunerGainMixer; ++ long TunerGainIfStage1, TunerGainIfStage2, TunerGainIfStage3, TunerGainIfStage4; ++ long TunerGainIfStage5, TunerGainIfStage6; ++ ++ long TunerGainTotal; ++ long TunerInputPower; ++ ++ ++ // Get tuner module. ++ pTuner = pNim->pTuner; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.E4000); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Get tuner RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ if(pTuner->GetRfFreqHz(pTuner, &RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ RfFreqKhz = (int)((RfFreqHz + 500) / 1000); ++ ++ // Get tuner bandwidth in KHz. ++ // Note: BandwidthKhz = round(BandwidthHz / 1000) ++ if(pTunerExtra->GetBandwidthHz(pTuner, &BandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ BandwidthKhz = (int)((BandwidthHz + 500) / 1000); ++ ++ ++ // Determine band index. ++ BandIndex = (RfFreqHz < RTL2832_E4000_RF_BAND_BOUNDARY_HZ) ? 0 : 1; ++ ++ ++ // Get tuner LNA gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_LNA_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsLna = (ReadingByte & RTL2832_E4000_LNA_GAIN_MASK) >> RTL2832_E4000_LNA_GAIN_SHIFT; ++ TunerGainLna = LnaGainTable[TunerBitsLna][BandIndex]; ++ ++ ++ // Get tuner LNA additional gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_LNA_GAIN_ADD_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsLnaAdd = (ReadingByte & RTL2832_E4000_LNA_GAIN_ADD_MASK) >> RTL2832_E4000_LNA_GAIN_ADD_SHIFT; ++ TunerGainLnaAdd = LnaGainAddTable[TunerBitsLnaAdd]; ++ ++ ++ // Get tuner mixer gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_MIXER_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsMixer = (ReadingByte & RTL2832_E4000_MIXER_GAIN_MASK) >> RTL2832_E4000_LNA_GAIN_ADD_SHIFT; ++ TunerGainMixer = MixerGainTable[TunerBitsMixer][BandIndex]; ++ ++ ++ // Get tuner IF stage 1 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_1_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage1 = (ReadingByte & RTL2832_E4000_IF_STAGE_1_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_1_GAIN_SHIFT; ++ TunerGainIfStage1 = IfStage1GainTable[TunerBitsIfStage1]; ++ ++ ++ // Get tuner IF stage 2 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_2_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage2 = (ReadingByte & RTL2832_E4000_IF_STAGE_2_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_2_GAIN_SHIFT; ++ TunerGainIfStage2 = IfStage2GainTable[TunerBitsIfStage2]; ++ ++ ++ // Get tuner IF stage 3 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_3_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage3 = (ReadingByte & RTL2832_E4000_IF_STAGE_3_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_3_GAIN_SHIFT; ++ TunerGainIfStage3 = IfStage3GainTable[TunerBitsIfStage3]; ++ ++ ++ // Get tuner IF stage 4 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_4_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage4 = (ReadingByte & RTL2832_E4000_IF_STAGE_4_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_4_GAIN_SHIFT; ++ TunerGainIfStage4 = IfStage4GainTable[TunerBitsIfStage4]; ++ ++ ++ // Get tuner IF stage 5 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_5_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage5 = (ReadingByte & RTL2832_E4000_IF_STAGE_5_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_5_GAIN_SHIFT; ++ TunerGainIfStage5 = IfStage5GainTable[TunerBitsIfStage5]; ++ ++ ++ // Get tuner IF stage 6 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_6_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage6 = (ReadingByte & RTL2832_E4000_IF_STAGE_6_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_6_GAIN_SHIFT; ++ TunerGainIfStage6 = IfStage6GainTable[TunerBitsIfStage6]; ++ ++ ++ // Calculate tuner total gain. ++ // Note: The unit of tuner total gain is 0.1 dB. ++ TunerGainTotal = TunerGainLna + TunerGainLnaAdd + TunerGainMixer + ++ TunerGainIfStage1 + TunerGainIfStage2 + TunerGainIfStage3 + TunerGainIfStage4 + ++ TunerGainIfStage5 + TunerGainIfStage6; ++ ++ // Calculate tuner input power. ++ // Note: The unit of tuner input power is 0.1 dBm ++ TunerInputPower = RTL2832_E4000_TUNER_OUTPUT_POWER_UNIT_0P1_DBM - TunerGainTotal; ++ ++ ++ // Determine tuner gain mode according to tuner input power. ++ // Note: The unit of tuner input power is 0.1 dBm ++ switch(pNimExtra->TunerGainMode) ++ { ++ default: ++ case RTL2832_E4000_TUNER_GAIN_SENSITIVE: ++ ++ if(TunerInputPower > -650) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_NORMAL: ++ ++ if(TunerInputPower < -750) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_SENSITIVE; ++ ++ if(TunerInputPower > -400) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_LINEAR; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_LINEAR: ++ ++ if(TunerInputPower < -500) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ break; ++ } ++ ++ ++ // Set tuner gain mode. ++ switch(pNimExtra->TunerGainMode) ++ { ++ default: ++ case RTL2832_E4000_TUNER_GAIN_SENSITIVE: ++ ++ if(E4000_sensitivity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_NORMAL: ++ ++ if(E4000_nominal(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_LINEAR: ++ ++ if(E4000_linearity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_get_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,213 @@ ++#ifndef __NIM_RTL2832_E4000 ++#define __NIM_RTL2832_E4000 ++ ++/** ++ ++@file ++ ++@brief RTL2832 E4000 NIM module declaration ++ ++One can manipulate RTL2832 E4000 NIM through RTL2832 E4000 NIM module. ++RTL2832 E4000 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_e4000.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 E4000 NIM module. ++ BuildRtl2832E4000Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc8, // The E4000 I2C device address is 0xc8 in 8-bit format. ++ CRYSTAL_FREQ_26000000HZ // The E4000 crystal frequency is 26 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_e4000.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN 34 ++ ++#define RTL2832_E4000_LNA_GAIN_TABLE_LEN 16 ++#define RTL2832_E4000_LNA_GAIN_ADD_TABLE_LEN 8 ++#define RTL2832_E4000_MIXER_GAIN_TABLE_LEN 2 ++#define RTL2832_E4000_IF_STAGE_1_GAIN_TABLE_LEN 2 ++#define RTL2832_E4000_IF_STAGE_2_GAIN_TABLE_LEN 4 ++#define RTL2832_E4000_IF_STAGE_3_GAIN_TABLE_LEN 4 ++#define RTL2832_E4000_IF_STAGE_4_GAIN_TABLE_LEN 4 ++#define RTL2832_E4000_IF_STAGE_5_GAIN_TABLE_LEN 8 ++#define RTL2832_E4000_IF_STAGE_6_GAIN_TABLE_LEN 8 ++ ++#define RTL2832_E4000_LNA_GAIN_BAND_NUM 2 ++#define RTL2832_E4000_MIXER_GAIN_BAND_NUM 2 ++ ++#define RTL2832_E4000_RF_BAND_BOUNDARY_HZ 300000000 ++ ++#define RTL2832_E4000_LNA_GAIN_ADDR 0x14 ++#define RTL2832_E4000_LNA_GAIN_MASK 0xf ++#define RTL2832_E4000_LNA_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_LNA_GAIN_ADD_ADDR 0x24 ++#define RTL2832_E4000_LNA_GAIN_ADD_MASK 0x7 ++#define RTL2832_E4000_LNA_GAIN_ADD_SHIFT 0 ++ ++#define RTL2832_E4000_MIXER_GAIN_ADDR 0x15 ++#define RTL2832_E4000_MIXER_GAIN_MASK 0x1 ++#define RTL2832_E4000_MIXER_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_IF_STAGE_1_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_1_GAIN_MASK 0x1 ++#define RTL2832_E4000_IF_STAGE_1_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_IF_STAGE_2_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_2_GAIN_MASK 0x6 ++#define RTL2832_E4000_IF_STAGE_2_GAIN_SHIFT 1 ++ ++#define RTL2832_E4000_IF_STAGE_3_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_3_GAIN_MASK 0x18 ++#define RTL2832_E4000_IF_STAGE_3_GAIN_SHIFT 3 ++ ++#define RTL2832_E4000_IF_STAGE_4_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_4_GAIN_MASK 0x60 ++#define RTL2832_E4000_IF_STAGE_4_GAIN_SHIFT 5 ++ ++#define RTL2832_E4000_IF_STAGE_5_GAIN_ADDR 0x17 ++#define RTL2832_E4000_IF_STAGE_5_GAIN_MASK 0x7 ++#define RTL2832_E4000_IF_STAGE_5_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_IF_STAGE_6_GAIN_ADDR 0x17 ++#define RTL2832_E4000_IF_STAGE_6_GAIN_MASK 0x38 ++#define RTL2832_E4000_IF_STAGE_6_GAIN_SHIFT 3 ++ ++#define RTL2832_E4000_TUNER_OUTPUT_POWER_UNIT_0P1_DBM -100 ++ ++#define RTL2832_E4000_TUNER_MODE_UPDATE_WAIT_TIME_MS 1000 ++ ++ ++// Tuner gain mode ++enum RTL2832_E4000_TUNER_GAIN_MODE ++{ ++ RTL2832_E4000_TUNER_GAIN_SENSITIVE, ++ RTL2832_E4000_TUNER_GAIN_NORMAL, ++ RTL2832_E4000_TUNER_GAIN_LINEAR, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832E4000Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2832 E4000 NIM manipulaing functions ++int ++rtl2832_e4000_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_e4000_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_e4000_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_e4000_UpdateTunerMode( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,614 @@ ++/** ++ ++@file ++ ++@brief RTL2832 FC0012 NIM module definition ++ ++One can manipulate RTL2832 FC0012 NIM through RTL2832 FC0012 NIM module. ++RTL2832 FC0012 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_fc0012.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 FC0012 NIM module builder ++ ++Use BuildRtl2832Fc0012Module() to build RTL2832 FC0012 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 FC0012 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr FC0012 I2C device address ++@param [in] TunerCrystalFreqHz FC0012 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832Fc0012Module() to build RTL2832 FC0012 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Fc0012Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_FC0012; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build FC0012 tuner module. ++ BuildFc0012Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_fc0012_Initialize; ++ pNim->SetParameters = rtl2832_fc0012_SetParameters; ++ pNim->UpdateFunction = rtl2832_fc0012_UpdateFunction; ++ ++ ++ // Initialize NIM extra module variables. ++ pNimExtra->LnaUpdateWaitTimeMax = DivideWithCeiling(RTL2832_FC0012_LNA_UPDATE_WAIT_TIME_MS, DemodUpdateFuncRefPeriodMs); ++ pNimExtra->LnaUpdateWaitTime = 0; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_fc0012_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC0012_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9bf }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x11 }, ++ {DVBT_THD_DW1, 0xef }, ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++// {DVBT_REG_GPE, 0x1 }, ++// {DVBT_REG_GPO, 0x0 }, ++// {DVBT_REG_MONSEL, 0x0 }, ++// {DVBT_REG_MON, 0x3 }, ++// {DVBT_REG_4MSEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_FC0012_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Get tuner RSSI value when calibration is on. ++ // Note: Need to execute rtl2832_fc0012_GetTunerRssiCalOn() after demod AD7 is on. ++ if(rtl2832_fc0012_GetTunerRssiCalOn(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_fc0012_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_fc0012_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Increase tuner LNA_GAIN update waiting time. ++ pNimExtra->LnaUpdateWaitTime += 1; ++ ++ ++ // Check if need to update tuner LNA_GAIN according to update waiting time. ++ if(pNimExtra->LnaUpdateWaitTime == pNimExtra->LnaUpdateWaitTimeMax) ++ { ++ // Reset update waiting time. ++ pNimExtra->LnaUpdateWaitTime = 0; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Update tuner LNA gain with RSSI. ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get tuner RSSI value when calibration is on. ++ ++One can use rtl2832_fc0012_GetTunerRssiCalOn() to get tuner calibration-on RSSI value. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Get tuner calibration-on RSSI value successfully. ++@retval FUNCTION_ERROR Get tuner calibration-on RSSI value unsuccessfully. ++ ++*/ ++int ++rtl2832_fc0012_GetTunerRssiCalOn( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Set tuner EN_CAL_RSSI to 0x1. ++ if(fc0012_SetRegMaskBits(pTuner, 0x9, 4, 4, 0x1) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner LNA_POWER_DOWN to 0x1. ++ if(fc0012_SetRegMaskBits(pTuner, 0x6, 0, 0, 0x1) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Get demod RSSI_R when tuner RSSI calibration is on. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &(pNimExtra->RssiRCalOn)) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set tuner EN_CAL_RSSI to 0x0. ++ if(fc0012_SetRegMaskBits(pTuner, 0x9, 4, 4, 0x0) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner LNA_POWER_DOWN to 0x0. ++ if(fc0012_SetRegMaskBits(pTuner, 0x6, 0, 0, 0x0) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update tuner LNA_GAIN with RSSI. ++ ++One can use rtl2832_fc0012_UpdateTunerLnaGainWithRssi() to update tuner LNA_GAIN with RSSI. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update tuner LNA_GAIN with RSSI successfully. ++@retval FUNCTION_ERROR Update tuner LNA_GAIN with RSSI unsuccessfully. ++ ++*/ ++int ++rtl2832_fc0012_UpdateTunerLnaGainWithRssi( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long RssiRCalOff; ++ long RssiRDiff; ++ unsigned char LnaGain; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Get demod RSSI_R when tuner RSSI calibration in off. ++ // Note: Tuner EN_CAL_RSSI and LNA_POWER_DOWN are set to 0x0 after rtl2832_fc0012_GetTunerRssiCalOn() executing. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &RssiRCalOff) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Calculate RSSI_R difference. ++ RssiRDiff = RssiRCalOff - pNimExtra->RssiRCalOn; ++ ++ // Get tuner LNA_GAIN. ++ if(fc0012_GetRegMaskBits(pTuner, 0x13, 4, 3, &LnaGain) != FC0012_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine next LNA_GAIN according to RSSI_R difference and current LNA_GAIN. ++ switch(LnaGain) ++ { ++ default: ++ case FC0012_LNA_GAIN_LOW: ++ ++ if(RssiRDiff <= 0) ++ LnaGain = FC0012_LNA_GAIN_MIDDLE; ++ ++ break; ++ ++ ++ case FC0012_LNA_GAIN_MIDDLE: ++ ++ if(RssiRDiff >= 34) ++ LnaGain = FC0012_LNA_GAIN_LOW; ++ ++ if(RssiRDiff <= 0) ++ LnaGain = FC0012_LNA_GAIN_HIGH; ++ ++ break; ++ ++ ++ case FC0012_LNA_GAIN_HIGH: ++ ++ if(RssiRDiff >= 8) ++ LnaGain = FC0012_LNA_GAIN_MIDDLE; ++ ++ break; ++ } ++ ++ ++ // Set tuner LNA_GAIN. ++ if(fc0012_SetRegMaskBits(pTuner, 0x13, 4, 3, LnaGain) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,155 @@ ++#ifndef __NIM_RTL2832_FC0012 ++#define __NIM_RTL2832_FC0012 ++ ++/** ++ ++@file ++ ++@brief RTL2832 FC0012 NIM module declaration ++ ++One can manipulate RTL2832 FC0012 NIM through RTL2832 FC0012 NIM module. ++RTL2832 FC0012 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_fc0012.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 FC0012 NIM module. ++ BuildRtl2832Fc0012Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc6, // The FC0012 I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_36000000HZ // The FC0012 crystal frequency is 36.0 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_fc0012.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_FC0012_ADDITIONAL_INIT_REG_TABLE_LEN 29 ++#define RTL2832_FC0012_LNA_UPDATE_WAIT_TIME_MS 1000 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Fc0012Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2832 FC0012 NIM manipulaing functions ++int ++rtl2832_fc0012_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0012_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_fc0012_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0012_GetTunerRssiCalOn( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0012_UpdateTunerLnaGainWithRssi( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,343 @@ ++/** ++ ++@file ++ ++@brief RTL2832 FC2580 NIM module definition ++ ++One can manipulate RTL2832 FC2580 NIM through RTL2832 FC2580 NIM module. ++RTL2832 FC2580 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_fc2580.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 FC2580 NIM module builder ++ ++Use BuildRtl2832Fc2580Module() to build RTL2832 FC2580 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 FC2580 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr FC2580 I2C device address ++@param [in] TunerCrystalFreqHz FC2580 crystal frequency in Hz ++@param [in] TunerAgcMode FC2580 AGC mode ++ ++ ++@note ++ -# One should call BuildRtl2832Fc2580Module() to build RTL2832 FC2580 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Fc2580Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_FC2580; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build FC2580 tuner module. ++ BuildFc2580Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ TunerAgcMode ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_fc2580_Initialize; ++ pNim->SetParameters = rtl2832_fc2580_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_fc2580_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x9c }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_fc2580_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ FC2580_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = FC2580_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = FC2580_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = FC2580_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,141 @@ ++#ifndef __NIM_RTL2832_FC2580 ++#define __NIM_RTL2832_FC2580 ++ ++/** ++ ++@file ++ ++@brief RTL2832 FC2580 NIM module declaration ++ ++One can manipulate RTL2832 FC2580 NIM through RTL2832 FC2580 NIM module. ++RTL2832 FC2580 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_fc2580.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 FC2580 NIM module. ++ BuildRtl2832Fc2580Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xac, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_EXTERNAL // The FC2580 AGC mode is external AGC mode. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_fc2580.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Fc2580Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ); ++ ++ ++ ++ ++ ++// RTL2832 FC2580 NIM manipulaing functions ++int ++rtl2832_fc2580_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc2580_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,346 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MAX3543 NIM module definition ++ ++One can manipulate RTL2832 MAX3543 NIM through RTL2832 MAX3543 NIM module. ++RTL2832 MAX3543 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_max3543.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MAX3543 NIM module builder ++ ++Use BuildRtl2832Max3543Module() to build RTL2832 MAX3543 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MAX3543 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MAX3543 I2C device address ++@param [in] TunerCrystalFreqHz MAX3543 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832Max3543Module() to build RTL2832 MAX3543 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Max3543Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MAX3543; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build MAX3543 tuner module. ++ BuildMax3543Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2832_MAX3543_STANDARD_MODE_DEFAULT, ++ RTL2832_MAX3543_IF_FREQ_HZ_DEFAULT, ++ RTL2832_MAX3543_SAW_INPUT_TYPE_DEFAULT ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_max3543_Initialize; ++ pNim->SetParameters = rtl2832_max3543_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_max3543_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x4b }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_AD_EN_REG1, 0x0 }, ++ {DVBT_CKOUT_PWR_PID, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2832_MAX3543_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2832_MAX3543_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_max3543_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MAX3543_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ // Note: MAX3543 tuner only has 7 MHz and 8 MHz settings. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = MAX3543_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = MAX3543_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = MAX3543_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,145 @@ ++#ifndef __NIM_RTL2832_MAX3543 ++#define __NIM_RTL2832_MAX3543 ++ ++/** ++ ++@file ++ ++@brief RTL2832 MAX3543 NIM module declaration ++ ++One can manipulate RTL2832 MAX3543 NIM through RTL2832 MAX3543 NIM module. ++RTL2832 MAX3543 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_max3543.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MAX3543 NIM module. ++ BuildRtl2832Max3543Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_max3543.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN 23 ++ ++// Default ++#define RTL2832_MAX3543_STANDARD_MODE_DEFAULT MAX3543_STANDARD_DVBT ++#define RTL2832_MAX3543_IF_FREQ_HZ_DEFAULT IF_FREQ_36170000HZ ++#define RTL2832_MAX3543_SPECTRUM_MODE_DEFAULT SPECTRUM_INVERSE ++#define RTL2832_MAX3543_SAW_INPUT_TYPE_DEFAULT MAX3543_SAW_INPUT_SE ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Max3543Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MAX3543 NIM manipulaing functions ++int ++rtl2832_max3543_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_max3543_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,360 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MT2063 NIM module definition ++ ++One can manipulate RTL2832 MT2063 NIM through RTL2832 MT2063 NIM module. ++RTL2832 MT2063 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_mt2063.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MT2063 NIM module builder ++ ++Use BuildRtl2832Mt2063Module() to build RTL2832 MT2063 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MT2063 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MT2063 I2C device address ++@param [in] TunerAgcMode MT2063 AGC mode ++ ++ ++@note ++ -# One should call BuildRtl2832Mt2063Module() to build RTL2832 MT2063 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Mt2063Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2063); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MT2063; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build MT2063 tuner module. ++ BuildMt2063Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ MT2063_STANDARD_DVBT, ++ MT2063_VGAGC_0X3 ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_mt2063_Initialize; ++ pNim->SetParameters = rtl2832_mt2063_SetParameters; ++ ++ ++ // Set NIM extra module variables. ++ pNimExtra->IfFreqHz = NimIfFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_mt2063_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++// {DVBT_AGC_TARG_VAL_8_1, 0x32 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x19 }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ RTL2832_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2063); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner IF frequency in Hz. ++ if(pTunerExtra->SetIfFreqHz(pTuner, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency in Hz. ++ if(pDemod->SetIfFreqHz(pDemod, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_INVERSE. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_mt2063_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ unsigned long BandwidthHz; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Determine BandwidthHz according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: BandwidthHz = MT2063_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: BandwidthHz = MT2063_BANDWIDTH_7MHZ; break; ++ case DVBT_BANDWIDTH_8MHZ: BandwidthHz = MT2063_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Set tuner bandwidth in Hz with BandwidthHz. ++ // Note: Need to execute SetBandwidthHz() before SetRfFreqHz() for MT2063, ++ // because MT2063 bandwidth setting API only sets software variables. ++ if(pTunerExtra->SetBandwidthHz(pTuner, BandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,160 @@ ++#ifndef __NIM_RTL2832_MT2063 ++#define __NIM_RTL2832_MT2063 ++ ++/** ++ ++@file ++ ++@brief RTL2832 MT2063 NIM module declaration ++ ++One can manipulate RTL2832 MT2063 NIM through RTL2832 MT2063 NIM module. ++RTL2832 MT2063 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_mt2063.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MT2063 NIM module. ++ BuildRtl2832Mt2063Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2832 and MT2063 IF frequency is 36.125 MHz. ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0 // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTuner = pNim->pTuner; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ ++ // Open MT2063 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ ++ ++ ++ // Close MT2063 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_mt2063.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Mt2063Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MT2063 NIM manipulaing functions ++int ++rtl2832_mt2063_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_mt2063_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,1062 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MT2266 NIM module definition ++ ++One can manipulate RTL2832 MT2266 NIM through RTL2832 MT2266 NIM module. ++RTL2832 MT2266 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_mt2266.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MT2266 NIM module builder ++ ++Use BuildRtl2832Mt2266Module() to build RTL2832 MT2266 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MT2266 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MT2266 I2C device address ++ ++ ++@note ++ -# One should call BuildRtl2832Mt2266Module() to build RTL2832 MT2266 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Mt2266Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_MT2266_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2266); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MT2266; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build MT2266 tuner module. ++ BuildMt2266Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_mt2266_Initialize; ++ pNim->SetParameters = rtl2832_mt2266_SetParameters; ++ pNim->UpdateFunction = rtl2832_mt2266_UpdateFunction; ++ ++ ++ // Initialize NIM extra module variables. ++ pNimExtra->LnaConfig = 0xff; ++ pNimExtra->UhfSens = 0xff; ++ pNimExtra->AgcCurrentState = 0xff; ++ pNimExtra->LnaGainOld = 0xffffffff; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_mt2266_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0xc0 }, // Note: The IF_AGC_MIN value will be set again by demod_pdcontrol_reset(). ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x9c }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x1 }, ++ {DVBT_POLAR_IF_AGC, 0x1 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_mt2266_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ Handle_t Mt2266Handle; ++ unsigned long BandwidthHz; ++ ++ RTL2832_MT2266_EXTRA_MODULE *pNimExtra; ++ ++ UData_t Status; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ Mt2266Handle = pTunerExtra->DeviceHandle; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2266); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine BandwidthHz according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: BandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: BandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ case DVBT_BANDWIDTH_8MHZ: BandwidthHz = MT2266_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Set tuner bandwidth in Hz with BandwidthHz. ++ if(pTunerExtra->SetBandwidthHz(pTuner, BandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Reset MT2266 update procedure. ++ Status = demod_pdcontrol_reset(pDemod, Mt2266Handle, &pNimExtra->AgcCurrentState); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_mt2266_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ RTL2832_MT2266_EXTRA_MODULE *pNimExtra; ++ ++ Handle_t Mt2266Handle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module and tuner handle. ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ pTunerExtra->GetHandle(pTuner, &Mt2266Handle); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2266); ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Update demod and tuner register setting. ++ Status = demod_pdcontrol( ++ pDemod, ++ Mt2266Handle, ++ &pNimExtra->LnaConfig, ++ &pNimExtra->UhfSens, ++ &pNimExtra->AgcCurrentState, ++ &pNimExtra->LnaGainOld ++ ); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Additional definition for mt_control.c ++UData_t ++demod_get_pd( ++ handle_t demod_handle, ++ uint16_t *pd_value ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long RssiR; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get RSSI_R value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &RssiR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Set pd_value according to RSSI_R. ++ *pd_value = (uint16_t)RssiR; ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++UData_t ++demod_get_agc( ++ handle_t demod_handle, ++ uint16_t *rf_level, ++ uint16_t *bb_level ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long RfAgc; ++ unsigned long IfAgc; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get RF and IF AGC value. ++ if(pDemod->GetRfAgc(pDemod, &RfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert RF and IF AGC value to proper format. ++ *rf_level = (uint16_t)((RfAgc + (1 << (RTL2832_RF_AGC_REG_BIT_NUM - 1))) * ++ (1 << (MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM - RTL2832_RF_AGC_REG_BIT_NUM))); ++ ++ *bb_level = (uint16_t)((IfAgc + (1 << (RTL2832_IF_AGC_REG_BIT_NUM - 1))) * ++ (1 << (MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM - RTL2832_IF_AGC_REG_BIT_NUM))); ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++UData_t ++demod_set_bbagclim( ++ handle_t demod_handle, ++ int on_off_status ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long IfAgcMinBinary; ++ long IfAgcMinInt; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get IF_AGC_MIN binary value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, &IfAgcMinBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert IF_AGC_MIN binary value to integer. ++ IfAgcMinInt = BinToSignedInt(IfAgcMinBinary, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM); ++ ++ // Modify IF_AGC_MIN integer according to on_off_status. ++ switch(on_off_status) ++ { ++ case 1: ++ ++ IfAgcMinInt += RTL2832_MT2266_IF_AGC_MIN_INT_STEP; ++ ++ if(IfAgcMinInt > RTL2832_MT2266_IF_AGC_MIN_INT_MAX) ++ IfAgcMinInt = RTL2832_MT2266_IF_AGC_MIN_INT_MAX; ++ ++ break; ++ ++ default: ++ case 0: ++ ++ IfAgcMinInt -= RTL2832_MT2266_IF_AGC_MIN_INT_STEP; ++ ++ if(IfAgcMinInt < RTL2832_MT2266_IF_AGC_MIN_INT_MIN) ++ IfAgcMinInt = RTL2832_MT2266_IF_AGC_MIN_INT_MIN; ++ ++ break; ++ } ++ ++ // Convert modified IF_AGC_MIN integer to binary value. ++ IfAgcMinBinary = SignedIntToBin(IfAgcMinInt, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM); ++ ++ // Set IF_AGC_MIN with modified binary value. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, IfAgcMinBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_registers: ++error_status_get_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++ ++ ++UData_t ++tuner_set_bw_normal( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int DemodBandwidthMode; ++ unsigned int TunerBandwidthHz; ++ unsigned int TargetTunerBandwidthHz; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &DemodBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine tuner target bandwidth. ++ switch(DemodBandwidthMode) ++ { ++ case DVBT_BANDWIDTH_6MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ default: ++ case DVBT_BANDWIDTH_8MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Get tuner bandwidth. ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_OUTPUT_BW, &TunerBandwidthHz))) ++ goto error_status_get_tuner_bandwidth; ++ ++ // Set tuner bandwidth with normal setting according to demod bandwidth mode. ++ if(TunerBandwidthHz != TargetTunerBandwidthHz) ++ { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle, MT2266_OUTPUT_BW, TargetTunerBandwidthHz))) ++ goto error_status_set_tuner_bandwidth; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_get_tuner_bandwidth: ++error_status_execute_function: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++ ++ ++UData_t ++tuner_set_bw_narrow( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int DemodBandwidthMode; ++ unsigned long AciDetInd; ++ unsigned int TunerBandwidthHz; ++ unsigned int TargetTunerBandwidthHz; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &DemodBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod ACI_DET_IND. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_ACI_DET_IND, &AciDetInd) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Determine tuner target bandwidth according to ACI_DET_IND. ++ if(AciDetInd == 0x1) ++ { ++ // Choose narrow target bandwidth. ++ switch(DemodBandwidthMode) ++ { ++ case DVBT_BANDWIDTH_6MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_5MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ default: ++ case DVBT_BANDWIDTH_8MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ } ++ } ++ else ++ { ++ // Choose normal target bandwidth. ++ switch(DemodBandwidthMode) ++ { ++ case DVBT_BANDWIDTH_6MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ default: ++ case DVBT_BANDWIDTH_8MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_8MHZ; break; ++ } ++ } ++ ++ // Get tuner bandwidth. ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_OUTPUT_BW, &TunerBandwidthHz))) ++ goto error_status_get_tuner_bandwidth; ++ ++ // Set tuner bandwidth with normal setting according to demod bandwidth mode. ++ if(TunerBandwidthHz != TargetTunerBandwidthHz) ++ { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle, MT2266_OUTPUT_BW, TargetTunerBandwidthHz))) ++ goto error_status_set_tuner_bandwidth; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_get_tuner_bandwidth: ++error_status_get_registers: ++error_status_execute_function: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++ ++ ++// Microtune source code - mt_control.c ++ ++ ++ ++UData_t demod_pdcontrol_reset(handle_t demod_handle, handle_t tuner_handle, uint8_t *agc_current_state) { ++ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long BinaryValue; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Reset AGC current state. ++ *agc_current_state = AGC_STATE_START; ++ ++ // Calculate RTL2832_MT2266_IF_AGC_MIN_INT_MIN binary value. ++ BinaryValue = SignedIntToBin(RTL2832_MT2266_IF_AGC_MIN_INT_MIN, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM); ++ ++ // Set IF_AGC_MIN with binary value. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, BinaryValue) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner bandwidth with normal setting. ++ if(MT_IS_ERROR(tuner_set_bw_normal(tuner_handle, demod_handle))) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_set_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++UData_t demod_pdcontrol(handle_t demod_handle, handle_t tuner_handle, uint8_t* lna_config, uint8_t* uhf_sens, ++ uint8_t *agc_current_state, uint32_t *lna_gain_old) { ++ ++ uint16_t pd_value; ++ uint16_t rf_level, bb_level; ++ uint32_t lna_gain; ++ uint8_t zin=0; ++ ++// uint8_t temp[2]; ++// uint8_t agc_bb_min; ++// demod_data_t* local_data; ++ ++ ++ uint8_t band=1; /* band=0: vhf, band=1: uhf low, band=2: uhf high */ ++ uint32_t freq; ++ ++ // AGC threshold values ++ uint16_t sens_on[] = {11479, 11479, 32763}; ++ uint16_t sens_off[] = {36867, 36867, 44767}; ++ uint16_t lin_off[] = {23619, 23619, 23619}; ++ uint16_t lin_on[] = {38355, 38355, 38355}; ++ uint16_t pd_upper[] = {85, 85, 85}; ++ uint16_t pd_lower[] = {74, 74, 74}; ++ uint8_t next_state; ++ ++ // demod_data_t* local_data = (demod_data_t*)demod_handle; ++ ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_INPUT_FREQ, &freq))) goto error_status; ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_LNA_GAIN, &lna_gain))) goto error_status; ++ if(MT_IS_ERROR(MT2266_GetReg(tuner_handle,0x1e,&zin))) goto error_status; ++ ++ if (freq <= 250000000) band=0; ++ else if (freq < 660000000) band=1; ++ else band=2; ++ ++ if(MT_IS_ERROR(demod_get_pd(demod_handle, &pd_value))) goto error_status; ++ if(MT_IS_ERROR(demod_get_agc(demod_handle, &rf_level, &bb_level))) goto error_status; ++ ++ rf_level=0xffff-rf_level; ++ bb_level=0xffff-bb_level; ++ ++/* ++#ifndef _HOST_DLL ++ uart_write_nr("St:"); ++ uart_writedez(agc_current_state[num]); ++ ++ uart_write_nr(" PD: "); ++ uart_writehex16(pd_value); ++ ++ uart_write_nr(" AGC: "); ++ uart_writehex16(rf_level); ++ uart_writehex16(bb_level); ++#endif ++*/ ++ ++ next_state = *agc_current_state; ++ ++ switch (*agc_current_state) { ++ ++ case AGC_STATE_START : { ++ if ((int)lna_gain < LNAGAIN_MIN) ++ next_state=AGC_STATE_LNAGAIN_BELOW_MIN; ++ else if (lna_gain > LNAGAIN_MAX) ++ next_state=AGC_STATE_LNAGAIN_ABOVE_MAX; ++ else ++ next_state=AGC_STATE_NORMAL; ++ break; ++ } ++ ++ case AGC_STATE_LNAGAIN_BELOW_MIN : { ++ if ((int)lna_gain < LNAGAIN_MIN ) ++ next_state=AGC_STATE_LNAGAIN_BELOW_MIN; ++ else next_state=AGC_STATE_NORMAL; ++ ++ break; ++ } ++ ++ case AGC_STATE_LNAGAIN_ABOVE_MAX : { ++ if (lna_gain > LNAGAIN_MAX ) ++ next_state=AGC_STATE_LNAGAIN_ABOVE_MAX; ++ else next_state=AGC_STATE_NORMAL; ++ break; ++ } ++ ++ case AGC_STATE_NORMAL : { ++ if (rf_level > lin_on[band] ) { ++ *lna_gain_old = lna_gain; ++ next_state = AGC_STATE_MAS_GRANDE_SIGNAL; ++ } ++ else if (pd_value > pd_upper[band]) { ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ } ++ else if ( (pd_value < pd_lower[band]) && (lna_gain < LNAGAIN_MAX) ) { ++ next_state = AGC_STATE_NO_INTERFERER; ++ } ++ else if ( bb_level < sens_on[band]) { ++ next_state = AGC_STATE_SMALL_SIGNAL; ++ } ++ break; ++ } ++ ++ case AGC_STATE_NO_INTERFERER : { ++ if (pd_value > pd_lower[band] ) ++ next_state = AGC_STATE_MEDIUM_INTERFERER; ++ else if (pd_value < pd_lower[band] ) ++ next_state = AGC_STATE_NORMAL; ++ else if ( lna_gain == LNAGAIN_MAX ) ++ next_state = AGC_STATE_NORMAL; ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_INTERFERER : { ++ if (pd_value > pd_upper[band] ) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ else if (pd_value < pd_lower[band] ) ++ next_state = AGC_STATE_NO_INTERFERER; ++ break; ++ } ++ ++ ++ case AGC_STATE_GRANDE_INTERFERER : { ++ if (pd_value < pd_upper[band] ) ++ next_state = AGC_STATE_MEDIUM_INTERFERER; ++ break; ++ } ++ ++ case AGC_STATE_MAS_GRANDE_SIGNAL : { ++ if (rf_level < lin_on[band]) ++ next_state = AGC_STATE_GRANDE_SIGNAL; ++ else if (pd_value > pd_upper[band]) { ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ } ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_SIGNAL : { ++ if (rf_level > lin_off[band]) ++ next_state = AGC_STATE_GRANDE_SIGNAL; ++ else if (lna_gain >= *lna_gain_old) ++ next_state = AGC_STATE_NORMAL; ++ else if (pd_value > pd_upper[band]) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ break; ++ } ++ ++ case AGC_STATE_GRANDE_SIGNAL : { ++ if (rf_level > lin_on[band]) ++ next_state = AGC_STATE_MAS_GRANDE_SIGNAL; ++ else if (rf_level < lin_off[band]) ++ next_state = AGC_STATE_MEDIUM_SIGNAL; ++ else if (pd_value > pd_upper[band]) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ break; ++ } ++ ++ case AGC_STATE_SMALL_SIGNAL : { ++ if (pd_value > pd_upper[band] ) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ else if (bb_level > sens_off[band]) ++ next_state = AGC_STATE_NORMAL; ++ else if ( (bb_level < sens_on[band]) && (lna_gain == LNAGAIN_MAX) ) ++ next_state = AGC_STATE_MAX_SENSITIVITY; ++ break; ++ } ++ ++ case AGC_STATE_MAX_SENSITIVITY : { ++ if (bb_level > sens_off[band]) ++ next_state = AGC_STATE_SMALL_SIGNAL; ++ break; ++ } ++ ++ } ++ ++ *agc_current_state = next_state; ++ ++ ++ switch (*agc_current_state) { ++ ++ case AGC_STATE_LNAGAIN_BELOW_MIN : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_LNAGAIN_ABOVE_MAX : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_NORMAL : { ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ break; ++ } ++ ++ case AGC_STATE_NO_INTERFERER : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_INTERFERER : { ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ ++ // Additional setting ++ // Set tuner with normal bandwidth. ++ if(MT_IS_ERROR(tuner_set_bw_normal(tuner_handle, demod_handle))) goto error_status; ++ ++ break; ++ } ++ ++ case AGC_STATE_GRANDE_INTERFERER : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status; ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,1))) goto error_status; ++ ++ // Additional setting ++ // Set tuner with narrow bandwidth. ++ if(MT_IS_ERROR(tuner_set_bw_narrow(tuner_handle, demod_handle))) goto error_status; ++ ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_SIGNAL : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_GRANDE_SIGNAL : { ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_MAS_GRANDE_SIGNAL : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status; ++ if (lna_gain==0) { ++ if (zin <= 64) { ++ zin += 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ } ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_SMALL_SIGNAL : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_UHF_NORMAL,1))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ *uhf_sens=0; ++ break; ++ } ++ ++ case AGC_STATE_MAX_SENSITIVITY : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_UHF_MAXSENS,1))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ *uhf_sens=1; ++ break; ++ } ++ } ++ ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_LNA_GAIN,&lna_gain))) goto error_status; ++ ++ *lna_config=(uint8_t)lna_gain; ++ ++/* ++#ifndef _HOST_DLL ++ uart_write_nr(" LNA "); ++ uart_writedez(lna_gain); ++ uart_write_nr(" SENS "); ++ uart_writedez(*uhf_sens); ++ uart_write_nr(" Z "); ++ uart_writedez(zin); ++ uart_write(" "); ++#endif ++*/ ++ ++ ++ ++ return MT_OK; ++ ++ ++error_status: ++ return MT_COMM_ERR; ++} ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,267 @@ ++#ifndef __NIM_RTL2832_MT2266 ++#define __NIM_RTL2832_MT2266 ++ ++/** ++ ++@file ++ ++@brief RTL2832 MT2266 NIM module declaration ++ ++One can manipulate RTL2832 MT2266 NIM through RTL2832 MT2266 NIM module. ++RTL2832 MT2266 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_mt2266.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ TUNER_MODULE *pTuner; ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MT2266 NIM module. ++ BuildRtl2832Mt2266Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0 // The MT2266 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2266 tuner extra module. ++ pTuner = pNim->pTuner; ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ ++ // Open MT2266 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ ++ ++ ++ // Close MT2266 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_mt2266.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++ ++#define RTL2832_MT2266_IF_AGC_MIN_BIT_NUM 8 ++#define RTL2832_MT2266_IF_AGC_MIN_INT_MAX 36 ++#define RTL2832_MT2266_IF_AGC_MIN_INT_MIN -64 ++#define RTL2832_MT2266_IF_AGC_MIN_INT_STEP 0 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Mt2266Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MT2266 NIM manipulaing functions ++int ++rtl2832_mt2266_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_mt2266_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_mt2266_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Additional definition for mt_control.c ++//typedef unsigned char uint8_t; ++//typedef unsigned short uint16_t; ++//typedef unsigned long uint32_t; ++typedef void * handle_t; ++ ++#define MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM 16 ++ ++ ++ ++// Microtune source code - mt_control.c ++ ++ ++ ++/* $Id: mt_control.c,v 1.6 2008/01/02 12:04:39 tune\tpinz Exp $ */ ++/*! ++ * \file mt_control.c ++ * \author Thomas Pinz, Microtune GmbH&Co KG ++ * \author Marie-Curie-Str. 1, 85055 Ingolstadt ++ * \author E-Mail: thomas.pinz@microtune.com ++ */ ++ ++ ++#define LNAGAIN_MIN 0 ++#define LNAGAIN_MAX 14 ++ ++#define AGC_STATE_START 0 ++#define AGC_STATE_LNAGAIN_BELOW_MIN 1 ++#define AGC_STATE_LNAGAIN_ABOVE_MAX 2 ++#define AGC_STATE_NORMAL 3 ++#define AGC_STATE_NO_INTERFERER 4 ++#define AGC_STATE_MEDIUM_INTERFERER 5 ++#define AGC_STATE_GRANDE_INTERFERER 6 ++#define AGC_STATE_MEDIUM_SIGNAL 7 ++#define AGC_STATE_GRANDE_SIGNAL 8 ++#define AGC_STATE_MAS_GRANDE_SIGNAL 9 ++#define AGC_STATE_MAX_SENSITIVITY 10 ++#define AGC_STATE_SMALL_SIGNAL 11 ++ ++ ++UData_t ++demod_get_pd( ++ handle_t demod_handle, ++ uint16_t *pd_value ++ ); ++ ++UData_t ++demod_get_agc( ++ handle_t demod_handle, ++ uint16_t *rf_level, ++ uint16_t *bb_level ++ ); ++ ++UData_t ++demod_set_bbagclim( ++ handle_t demod_handle, ++ int on_off_status ++ ); ++ ++UData_t ++tuner_set_bw_normal( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ); ++ ++UData_t ++tuner_set_bw_narrow( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ); ++ ++UData_t ++demod_pdcontrol_reset( ++ handle_t demod_handle, ++ handle_t tuner_handle, ++ uint8_t *agc_current_state ++ ); ++ ++UData_t ++demod_pdcontrol( ++ handle_t demod_handle, ++ handle_t tuner_handle, ++ uint8_t* lna_config, ++ uint8_t* uhf_sens, ++ uint8_t *agc_current_state, ++ uint32_t *lna_gain_old ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,355 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MxL5007T NIM module definition ++ ++One can manipulate RTL2832 MxL5007T NIM through RTL2832 MxL5007T NIM module. ++RTL2832 MxL5007T NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_mxl5007t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MxL5007T NIM module builder ++ ++Use BuildRtl2832Mxl5007tModule() to build RTL2832 MxL5007T NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MxL5007T NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MxL5007T I2C device address ++@param [in] TunerCrystalFreqHz MxL5007T crystal frequency in Hz ++@param [in] TunerLoopThroughMode MxL5007T loop-through mode ++@param [in] TunerClkOutMode MxL5007T clock output mode ++@param [in] TunerClkOutAmpMode MxL5007T clock output amplitude mode ++ ++ ++@note ++ -# One should call BuildRtl2832Mxl5007tModule() to build RTL2832 MxL5007T NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Mxl5007tModule( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MXL5007T; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build Mxl5007T tuner module. ++ BuildMxl5007tModule( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2832_MXL5007T_STANDARD_MODE_DEFAULT, ++ RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT, ++ RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT, ++ TunerLoopThroughMode, ++ TunerClkOutMode, ++ TunerClkOutAmpMode, ++ RTL2832_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_mxl5007t_Initialize; ++ pNim->SetParameters = rtl2832_mxl5007t_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_mxl5007t_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x4b }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_AD_EN_REG1, 0x0 }, ++ {DVBT_CKOUT_PWR_PID, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_mxl5007t_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mxl5007t); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,151 @@ ++#ifndef __NIM_RTL2832_MXL5007T ++#define __NIM_RTL2832_MXL5007T ++ ++/** ++ ++@file ++ ++@brief RTL2832 MxL5007T NIM module declaration ++ ++One can manipulate RTL2832 MxL5007T NIM through RTL2832 MxL5007T NIM module. ++RTL2832 MxL5007T NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_mxl5007t.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MxL5007T NIM module. ++ BuildRtl2832Mxl5007tModule( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_mxl5007t.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN 23 ++ ++// Default ++#define RTL2832_MXL5007T_STANDARD_MODE_DEFAULT MXL5007T_STANDARD_DVBT ++#define RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT IF_FREQ_4570000HZ ++#define RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT SPECTRUM_NORMAL ++#define RTL2832_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT 0 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Mxl5007tModule( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MxL5007T NIM manipulaing functions ++int ++rtl2832_mxl5007t_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_mxl5007t_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,340 @@ ++/** ++ ++@file ++ ++@brief RTL2832 TUA9001 NIM module definition ++ ++One can manipulate RTL2832 TUA9001 NIM through RTL2832 TUA9001 NIM module. ++RTL2832 TUA9001 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_tua9001.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 TUA9001 NIM module builder ++ ++Use BuildRtl2832Tua9001Module() to build RTL2832 TUA9001 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 TUA9001 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr TUA9001 I2C device address ++ ++ ++@note ++ -# One should call BuildRtl2832Tua9001Module() to build RTL2832 TUA9001 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Tua9001Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_TUA9001; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build TUA9001 tuner module. ++ BuildTua9001Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_tua9001_Initialize; ++ pNim->SetParameters = rtl2832_tua9001_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_tua9001_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x9c }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ {DVBT_OPT_ADC_IQ, 0x1 }, ++ {DVBT_AD_AVI, 0x0 }, ++ {DVBT_AD_AVQ, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_tua9001_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ TUA9001_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = TUA9001_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = TUA9001_BANDWIDTH_7MHZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = TUA9001_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,137 @@ ++#ifndef __NIM_RTL2832_TUA9001 ++#define __NIM_RTL2832_TUA9001 ++ ++/** ++ ++@file ++ ++@brief RTL2832 TUA9001 NIM module declaration ++ ++One can manipulate RTL2832 TUA9001 NIM through RTL2832 TUA9001 NIM module. ++RTL2832 TUA9001 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_tua9001.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 TUA9001 NIM module. ++ BuildRtl2832Tua9001Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0 // The TUA9001 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_tua9001.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN 24 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Tua9001Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2832 TUA9001 NIM manipulaing functions ++int ++rtl2832_tua9001_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_tua9001_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,308 @@ ++/** ++ ++@file ++ ++@brief RTL2836 FC2580 NIM module definition ++ ++One can manipulate RTL2836 FC2580 NIM through RTL2836 FC2580 NIM module. ++RTL2836 FC2580 NIM module is derived from DTMB NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2836_fc2580.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2836 FC2580 NIM module builder ++ ++Use BuildRtl2836Fc2580Module() to build RTL2836 FC2580 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2836 FC2580 NIM module pointer ++@param [in] pDtmbNimModuleMemory Pointer to an allocated DTMB NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2836 I2C device address ++@param [in] DemodCrystalFreqHz RTL2836 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2836 TS interface mode ++@param [in] DemodUpdateFuncRefPeriodMs RTL2836 update function reference period in millisecond ++@param [in] DemodIsFunc1Enabled RTL2836 Function 1 enabling status for setting ++@param [in] DemodIsFunc2Enabled RTL2836 Function 2 enabling status for setting ++@param [in] TunerDeviceAddr FC2580 I2C device address ++@param [in] TunerCrystalFreqHz FC2580 crystal frequency in Hz ++@param [in] TunerAgcMode FC2580 AGC mode ++ ++ ++@note ++ -# One should call BuildRtl2836Fc2580Module() to build RTL2836 FC2580 NIM module before using it. ++ ++*/ ++void ++BuildRtl2836Fc2580Module( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ) ++{ ++ DTMB_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDtmbNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DTMB_NIM_RTL2836_FC2580; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2836 demod module. ++ BuildRtl2836Module( ++ &pNim->pDemod, ++ &pNim->DtmbDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled, ++ DemodIsFunc2Enabled ++ ); ++ ++ // Build FC2580 tuner module. ++ BuildFc2580Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ TunerAgcMode ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dtmb_nim_default_GetNimType; ++ pNim->GetParameters = dtmb_nim_default_GetParameters; ++ pNim->IsSignalPresent = dtmb_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dtmb_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dtmb_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dtmb_nim_default_GetSignalQuality; ++ pNim->GetBer = dtmb_nim_default_GetBer; ++ pNim->GetPer = dtmb_nim_default_GetPer; ++ pNim->GetSnrDb = dtmb_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dtmb_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dtmb_nim_default_GetCrOffsetHz; ++ pNim->GetSignalInfo = dtmb_nim_default_GetSignalInfo; ++ pNim->UpdateFunction = dtmb_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2836_fc2580_Initialize; ++ pNim->SetParameters = rtl2836_fc2580_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2836_fc2580_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2836_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DTMB_TARGET_VAL, 0x38 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ FC2580_EXTRA_MODULE *pTunerExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner bandwidth mode with 8 MHz. ++ if(pTunerExtra->SetBandwidthMode(pTuner, FC2580_BANDWIDTH_8000000HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2836_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2836_fc2580_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,140 @@ ++#ifndef __NIM_RTL2836_FC2580 ++#define __NIM_RTL2836_FC2580 ++ ++/** ++ ++@file ++ ++@brief RTL2836 FC2580 NIM module declaration ++ ++One can manipulate RTL2836 FC2580 NIM through RTL2836 FC2580 NIM module. ++RTL2836 FC2580 NIM module is derived from DTMB NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dtmb_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2836_fc2580.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2836 FC2580 NIM module. ++ BuildRtl2836Fc2580Module( ++ &pNim, ++ &DtmbNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x3e, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ 0xac, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is internal AGC mode. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dtmb_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2836.h" ++#include "tuner_fc2580.h" ++#include "dtmb_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2836_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN 1 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2836Fc2580Module( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ); ++ ++ ++ ++ ++ ++// RTL2836 FC2580 NIM manipulaing functions ++int ++rtl2836_fc2580_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2836_fc2580_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,319 @@ ++/** ++ ++@file ++ ++@brief RTL2836 MxL5007T NIM module definition ++ ++One can manipulate RTL2836 MxL5007T NIM through RTL2836 MxL5007T NIM module. ++RTL2836 MxL5007T NIM module is derived from DTMB NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2836_mxl5007t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2836 MxL5007T NIM module builder ++ ++Use BuildRtl2836Mxl5007tModule() to build RTL2836 MxL5007T NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2836 MxL5007T NIM module pointer ++@param [in] pDtmbNimModuleMemory Pointer to an allocated DTMB NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2836 I2C device address ++@param [in] DemodCrystalFreqHz RTL2836 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2836 TS interface mode ++@param [in] DemodUpdateFuncRefPeriodMs RTL2836 update function reference period in millisecond ++@param [in] DemodIsFunc1Enabled RTL2836 Function 1 enabling status for setting ++@param [in] DemodIsFunc2Enabled RTL2836 Function 2 enabling status for setting ++@param [in] TunerDeviceAddr MxL5007T I2C device address ++@param [in] TunerCrystalFreqHz MxL5007T crystal frequency in Hz ++@param [in] TunerLoopThroughMode MxL5007T loop-through mode ++@param [in] TunerClkOutMode MxL5007T clock output mode ++@param [in] TunerClkOutAmpMode MxL5007T clock output amplitude mode ++ ++ ++@note ++ -# One should call BuildRtl2836Mxl5007tModule() to build RTL2836 MxL5007T NIM module before using it. ++ ++*/ ++void ++BuildRtl2836Mxl5007tModule( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ) ++{ ++ DTMB_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDtmbNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DTMB_NIM_RTL2836_MXL5007T; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2836 demod module. ++ BuildRtl2836Module( ++ &pNim->pDemod, ++ &pNim->DtmbDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled, ++ DemodIsFunc2Enabled ++ ); ++ ++ // Build MxL5007T tuner module. ++ BuildMxl5007tModule( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2836_MXL5007T_STANDARD_MODE_DEFAULT, ++ RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT, ++ RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT, ++ TunerLoopThroughMode, ++ TunerClkOutMode, ++ TunerClkOutAmpMode, ++ RTL2836_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dtmb_nim_default_GetNimType; ++ pNim->GetParameters = dtmb_nim_default_GetParameters; ++ pNim->IsSignalPresent = dtmb_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dtmb_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dtmb_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dtmb_nim_default_GetSignalQuality; ++ pNim->GetBer = dtmb_nim_default_GetBer; ++ pNim->GetPer = dtmb_nim_default_GetPer; ++ pNim->GetSnrDb = dtmb_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dtmb_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dtmb_nim_default_GetCrOffsetHz; ++ pNim->GetSignalInfo = dtmb_nim_default_GetSignalInfo; ++ pNim->UpdateFunction = dtmb_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2836_mxl5007t_Initialize; ++ pNim->SetParameters = rtl2836_mxl5007t_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2836_mxl5007t_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DTMB_TARGET_VAL, 0x38 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mxl5007t); ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner bandwidth mode with 8 MHz. ++ if(pTunerExtra->SetBandwidthMode(pTuner, MXL5007T_BANDWIDTH_8000000HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2836_mxl5007t_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,150 @@ ++#ifndef __NIM_RTL2836_MXL5007T ++#define __NIM_RTL2836_MXL5007T ++ ++/** ++ ++@file ++ ++@brief RTL2836 MxL5007T NIM module declaration ++ ++One can manipulate RTL2836 MxL5007T NIM through RTL2836 MxL5007T NIM module. ++RTL2836 MxL5007T NIM module is derived from DTMB NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dtmb_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2836_mxl5007t.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2836 MxL5007T NIM module. ++ BuildRtl2836Mxl5007tModule( ++ &pNim, ++ &DtmbNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x3e, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ 0xc0, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dtmb_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2836.h" ++#include "tuner_mxl5007t.h" ++#include "dtmb_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN 1 ++ ++// Default ++#define RTL2836_MXL5007T_STANDARD_MODE_DEFAULT MXL5007T_STANDARD_DVBT ++#define RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT IF_FREQ_4570000HZ ++#define RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT SPECTRUM_NORMAL ++#define RTL2836_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT 0 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2836Mxl5007tModule( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ); ++ ++ ++ ++ ++ ++// RTL2836 MxL5007T NIM manipulaing functions ++int ++rtl2836_mxl5007t_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2836_mxl5007t_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,341 @@ ++/** ++ ++@file ++ ++@brief RTL2840 MAX3543 NIM module definition ++ ++One can manipulate RTL2840 MAX3543 NIM through RTL2840 MAX3543 NIM module. ++RTL2840 MAX3543 NIM module is derived from QAM NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2840_max3543.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2840 MAX3543 NIM module builder ++ ++Use BuildRtl2840Max3543Module() to build RTL2840 MAX3543 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2840 MAX3543 NIM module pointer ++@param [in] pQamNimModuleMemory Pointer to an allocated QAM NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2840 I2C device address ++@param [in] DemodCrystalFreqHz RTL2840 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2840 TS interface mode for setting ++@param [in] DemodEnhancementMode RTL2840 enhancement mode for setting ++@param [in] TunerDeviceAddr MAX3543 I2C device address ++@param [in] TunerCrystalFreqHz MAX3543 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2840Max3543Module() to build RTL2840 MAX3543 NIM module before using it. ++ ++*/ ++void ++BuildRtl2840Max3543Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ QAM_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pQamNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Set enhancement mode in NIM module. ++ pNim->EnhancementMode = DemodEnhancementMode; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2840 QAM demod module. ++ BuildRtl2840Module( ++ &pNim->pDemod, ++ &pNim->QamDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodEnhancementMode ++ ); ++ ++ // Build MAX3543 tuner module. ++ BuildMax3543Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2840_MAX3543_STANDARD_MODE_DEFAULT, ++ RTL2840_MAX3543_IF_FREQ_HZ_DEFAULT, ++ RTL2840_MAX3543_SAW_INPUT_TYPE_DEFAULT ++ ); ++ ++ ++ // Set NIM module manipulating function pointers. ++ pNim->Initialize = rtl2840_max3543_Initialize; ++ pNim->SetParameters = rtl2840_max3543_SetParameters; ++ ++ // Set NIM module manipulating function pointers with default. ++ pNim->GetNimType = qam_nim_default_GetNimType; ++ pNim->GetParameters = qam_nim_default_GetParameters; ++ pNim->IsSignalPresent = qam_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = qam_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = qam_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = qam_nim_default_GetSignalQuality; ++ pNim->GetErrorRate = qam_nim_default_GetErrorRate; ++ pNim->GetSnrDb = qam_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = qam_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = qam_nim_default_GetCrOffsetHz; ++ pNim->UpdateFunction = qam_nim_default_UpdateFunction; ++ ++ ++ // Set NIM type. ++ pNim->NimType = QAM_NIM_RTL2840_MAX3543; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2840_max3543_Initialize( ++ QAM_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2840_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {QAM_OPT_RF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_IF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_RF_AAGC_OEN, 0x1 }, ++ {QAM_OPT_IF_AAGC_OEN, 0x1 }, ++ {QAM_RF_AAGC_MAX, 0xff }, ++ {QAM_RF_AAGC_MIN, 0x0 }, ++ {QAM_IF_AAGC_MAX, 0xff }, ++ {QAM_IF_AAGC_MIN, 0x0 }, ++ {QAM_AAGC_MODE_SEL, 0x0 }, ++ }; ++ ++ ++ QAM_DEMOD_MODULE *pDemod; ++ TUNER_MODULE *pTuner; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ // Get demod module and tuner module. ++ pDemod = pNim->pDemod; ++ pTuner = pNim->pTuner; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency in Hz with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2840_MAX3543_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2840_MAX3543_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod AAGC registers. ++ // Note: SetParameters() will set QAM_AAGC_TARGET and QAM_VTOP according to parameters. ++ for(i = 0; i < RTL2840_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2840_max3543_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ TUNER_MODULE *pTuner; ++ ++ ++ // Get demod module and tuner module. ++ pDemod = pNim->pDemod; ++ pTuner = pNim->pTuner; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod QAM mode. ++ if(pDemod->SetQamMode(pDemod, QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod symbol rate in Hz. ++ if(pDemod->SetSymbolRateHz(pDemod, SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod alpha mode. ++ if(pDemod->SetAlphaMode(pDemod, AlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod QAM_AAGC_TARGET and QAM_VTOP according to QAM mode and enhancement mode. ++ switch(QamMode) ++ { ++ default: ++ case QAM_QAM_4: ++ case QAM_QAM_16: ++ case QAM_QAM_32: ++ case QAM_QAM_64: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_VTOP, 0x3f) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ switch(pNim->EnhancementMode) ++ { ++ case QAM_DEMOD_EN_NONE: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_AAGC_TARGET, 0x6b) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ default: ++ case QAM_DEMOD_EN_AM_HUM: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_AAGC_TARGET, 0x64) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ break; ++ ++ case QAM_QAM_128: ++ case QAM_QAM_256: ++ case QAM_QAM_512: ++ case QAM_QAM_1024: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_VTOP, 0x38) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_AAGC_TARGET, 0x6b) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,146 @@ ++#ifndef __NIM_RTL2840_MAX3543_H ++#define __NIM_RTL2840_MAX3543_H ++ ++/** ++ ++@file ++ ++@brief RTL2840 MAX3543 NIM module definition ++ ++One can manipulate RTL2840 MAX3543 NIM through RTL2840 MAX3543 NIM module. ++RTL2840 MAX3543 NIM module is derived from QAM NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in qam_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2840_max3543.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2840 MAX3543 NIM module. ++ BuildRtl2840Max3543Module( ++ &pNim, ++ &QamNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x44, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ 0xc0, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in qam_nim_base.h ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2840.h" ++#include "tuner_max3543.h" ++#include "qam_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2840_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN 9 ++ ++// Default ++#define RTL2840_MAX3543_STANDARD_MODE_DEFAULT MAX3543_STANDARD_QAM ++#define RTL2840_MAX3543_IF_FREQ_HZ_DEFAULT IF_FREQ_36170000HZ ++#define RTL2840_MAX3543_SPECTRUM_MODE_DEFAULT SPECTRUM_INVERSE ++#define RTL2840_MAX3543_SAW_INPUT_TYPE_DEFAULT MAX3543_SAW_INPUT_SE ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2840Max3543Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2840 MAX3543 NIM manipulaing functions ++int ++rtl2840_max3543_Initialize( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2840_max3543_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,307 @@ ++/** ++ ++@file ++ ++@brief RTL2840 MT2063 NIM module definition ++ ++One can manipulate RTL2840 MT2063 NIM through RTL2840 MT2063 NIM module. ++RTL2840 MT2063 NIM module is derived from QAM NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2840_mt2063.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2840 MT2063 NIM module builder ++ ++Use BuildRtl2840Mt2063Module() to build RTL2840 MT2063 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2840 MT2063 NIM module pointer ++@param [in] pQamNimModuleMemory Pointer to an allocated QAM NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2840 I2C device address ++@param [in] DemodCrystalFreqHz RTL2840 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2840 TS interface mode for setting ++@param [in] DemodEnhancementMode RTL2840 enhancement mode for setting ++@param [in] TunerDeviceAddr MT2063 I2C device address ++ ++ ++@note ++ -# One should call BuildRtl2840Mt2063Module() to build RTL2840 MT2063 NIM module before using it. ++ ++*/ ++void ++BuildRtl2840Mt2063Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ QAM_NIM_MODULE *pNim; ++ RTL2840_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pQamNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2840Mt2063); ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2840 QAM demod module. ++ BuildRtl2840Module( ++ &pNim->pDemod, ++ &pNim->QamDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodEnhancementMode ++ ); ++ ++ // Build MT2063 tuner module. ++ BuildMt2063Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++// MT2063_STANDARD_QAM, ++ MT2063_STANDARD_DVBT, ++ MT2063_VGAGC_0X1 ++ ); ++ ++ ++ // Set NIM module manipulating function pointers. ++ pNim->Initialize = rtl2840_mt2063_Initialize; ++ pNim->SetParameters = rtl2840_mt2063_SetParameters; ++ ++ // Set NIM module manipulating function pointers with default. ++ pNim->GetNimType = qam_nim_default_GetNimType; ++ pNim->GetParameters = qam_nim_default_GetParameters; ++ pNim->IsSignalPresent = qam_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = qam_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = qam_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = qam_nim_default_GetSignalQuality; ++ pNim->GetErrorRate = qam_nim_default_GetErrorRate; ++ pNim->GetSnrDb = qam_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = qam_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = qam_nim_default_GetCrOffsetHz; ++ pNim->UpdateFunction = qam_nim_default_UpdateFunction; ++ ++ ++ // Set NIM type. ++ pNim->NimType = QAM_NIM_RTL2840_MT2063; ++ ++ // Set enhancement mode in NIM module. ++ pNim->EnhancementMode = DemodEnhancementMode; ++ ++ // Set IF frequency variable in NIM extra module. ++ pNimExtra->IfFreqHz = NimIfFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2840_mt2063_Initialize( ++ QAM_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2840_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {QAM_OPT_RF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_IF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_RF_AAGC_OEN, 0x1 }, ++ {QAM_OPT_IF_AAGC_OEN, 0x1 }, ++ {QAM_RF_AAGC_MAX, 0x80 }, ++ {QAM_RF_AAGC_MIN, 0x80 }, ++ {QAM_IF_AAGC_MAX, 0xff }, ++ {QAM_IF_AAGC_MIN, 0x0 }, ++ {QAM_AAGC_MODE_SEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ RTL2840_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ // Get modules. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ pNimExtra = &(pNim->Extra.Rtl2840Mt2063); ++ ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner IF frequency in Hz. ++ if(pTunerExtra->SetIfFreqHz(pTuner, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency in Hz. ++ if(pDemod->SetIfFreqHz(pDemod, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_INVERSE. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod AAGC registers. ++ // Note: SetParameters() will set QAM_AAGC_TARGET and QAM_VTOP according to parameters. ++ for(i = 0; i < RTL2840_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2840_mt2063_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module and tuner module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod QAM mode. ++ if(pDemod->SetQamMode(pDemod, QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod symbol rate in Hz. ++ if(pDemod->SetSymbolRateHz(pDemod, SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod alpha mode. ++ if(pDemod->SetAlphaMode(pDemod, AlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,163 @@ ++#ifndef __NIM_RTL2840_MT2063_H ++#define __NIM_RTL2840_MT2063_H ++ ++/** ++ ++@file ++ ++@brief RTL2840 MT2063 NIM module definition ++ ++One can manipulate RTL2840 MT2063 NIM through RTL2840 MT2063 NIM module. ++RTL2840 MT2063 NIM module is derived from QAM NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in qam_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2840_mt2063.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ TUNER_MODULE *pTuner; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ ++ ... ++ ++ ++ ++ // Build RTL2840 MT2063 NIM module. ++ BuildRtl2840Mt2063Module( ++ &pNim, ++ &QamNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2840 and MT2063 IF frequency is 36.125 MHz. ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x44, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ 0xc0 // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTuner = pNim->pTuner; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ ++ // Open MT2063 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // See the example for other NIM functions in qam_nim_base.h ++ ... ++ ++ ++ ++ ++ ++ // Close MT2063 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2840.h" ++#include "tuner_mt2063.h" ++#include "qam_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2840_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN 9 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2840Mt2063Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2840 MT2063 NIM manipulaing functions ++int ++rtl2840_mt2063_Initialize( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2840_mt2063_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_demod_base.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_demod_base.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_demod_base.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_demod_base.c 2010-10-27 08:17:26.000000000 +0200 +@@ -0,0 +1,1289 @@ ++/** ++ ++@file ++ ++@brief QAM demod default function definition ++ ++QAM demod default functions. ++ ++*/ ++ ++#include "qam_demod_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegPage( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register page with page number. ++ // Note: The I2C format of demod register page setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + QAM_DEMOD_PAGE_REG_ADDR + PageNo + stop_bit ++ WritingBytes[0] = QAM_DEMOD_PAGE_REG_ADDR; ++ WritingBytes[1] = (unsigned char)PageNo; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ if( mutex_lock_interruptible(&d->usb_mutex) ) goto error; ++ ++ pDemod->CurrentPageNo = PageNo; ++ ++ mutex_unlock(&d->usb_mutex); ++ ++ return FUNCTION_SUCCESS; ++ ++error: ++ ++ return FUNCTION_ERROR; ++ ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + ++ // stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned char WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ unsigned long PageNo=0; ++ ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ PageNo=pDemod->CurrentPageNo; ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(write_demod_register(d, DeviceAddr, PageNo, WritingBuffer[0], WritingBuffer+1, WritingByteNum)) ++ goto error_status_set_demod_registers; ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned char DeviceAddr; ++ unsigned char ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ unsigned long PageNo; ++ ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ PageNo=pDemod->CurrentPageNo; ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, PageNo, RegReadingAddr, pReadingBytes, ReadingByteNum)) ++ goto error_status_get_demod_registers; ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++//error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char PageNo; ++ ++ ++ // Get register page number from base register table with register bit name key. ++ PageNo = pDemod->BaseRegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, RegBitName, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char PageNo; ++ ++ ++ // Get register page number from base register table with register bit name key. ++ PageNo = pDemod->BaseRegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_16bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned short RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddrMsb + RegWritingAddrLsb + ++ // writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = (RegWritingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegWritingAddr & BYTE_MASK; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_2_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_2_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_16bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned short RegReadingAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddrMsb + RegReadingAddrLsb + stop_bit ++ WritingBuffer[0] = (RegReadingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegReadingAddr & BYTE_MASK; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr16Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_DEMOD_TYPE ++ ++*/ ++void ++qam_demod_default_GetDemodType( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ) ++{ ++ // Get demod type from demod module. ++ *pDemodType = pDemod->DemodType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++qam_demod_default_GetDeviceAddr( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get demod I2C device address from demod module. ++ *pDeviceAddr = pDemod->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ ++ ++*/ ++void ++qam_demod_default_GetCrystalFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ) ++{ ++ // Get demod crystal frequency in Hz from demod module. ++ *pCrystalFreqHz = pDemod->CrystalFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_QAM_MODE ++ ++*/ ++int ++qam_demod_default_GetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ) ++{ ++ // Get demod QAM mode from demod module. ++ if(pDemod->IsQamModeSet != YES) ++ goto error_status_get_demod_qam_mode; ++ ++ *pQamMode = pDemod->QamMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_qam_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ ++ ++*/ ++int ++qam_demod_default_GetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSymbolRateHz ++ ) ++{ ++ // Get demod symbol rate in Hz from demod module. ++ if(pDemod->IsSymbolRateHzSet != YES) ++ goto error_status_get_demod_symbol_rate; ++ ++ *pSymbolRateHz = pDemod->SymbolRateHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_symbol_rate: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_ALPHA_MODE ++ ++*/ ++int ++qam_demod_default_GetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAlphaMode ++ ) ++{ ++ // Get demod alpha mode from demod module. ++ if(pDemod->IsAlphaModeSet != YES) ++ goto error_status_get_demod_alpha_mode; ++ ++ *pAlphaMode = pDemod->AlphaMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_alpha_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_IF_FREQ_HZ ++ ++*/ ++int ++qam_demod_default_GetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ // Get demod IF frequency in Hz from demod module. ++ if(pDemod->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pDemod->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SPECTRUM_MODE ++ ++*/ ++int ++qam_demod_default_GetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ) ++{ ++ // Get demod spectrum mode from demod module. ++ if(pDemod->IsSpectrumModeSet != YES) ++ goto error_status_get_demod_spectrum_mode; ++ ++ *pSpectrumMode = pDemod->SpectrumMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_spectrum_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_demod_base.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_demod_base.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_demod_base.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_demod_base.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,2829 @@ ++#ifndef __QAM_DEMOD_BASE_H ++#define __QAM_DEMOD_BASE_H ++ ++/** ++ ++@file ++ ++@brief QAM demod base module definition ++ ++QAM demod base module definitions contains demod module structure, demod funciton pointers, and demod definitions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_xxx.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ int QamMode; ++ unsigned long SymbolRateHz; ++ int AlphaMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ ++ long RfAgc, IfAgc; ++ unsigned long DiAgc; ++ ++ int Answer; ++ long TrOffsetPpm, CrOffsetHz; ++ unsigned long BerNum, BerDen, PerNum, PerDen; ++ double Ber, Per; ++ long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ unsigned long SignalStrength, SignalQuality; ++ ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, // Set maximum I2C reading byte number with 9. ++ 8, // Set maximum I2C writing byte number with 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ); ++ ++ ++ // Build QAM demod XXX module. ++ BuildXxxModule( ++ &pDemod, ++ &QamDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x44, // Demod I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Demod crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // Demod TS interface mode is serial. ++ ... // Other arguments by each demod module ++ ); ++ ++ ++ ++ ++ ++ // ==== Initialize QAM demod and set its parameters ===== ++ ++ // Initialize demod. ++ pDemod->Initialize(pDemod); ++ ++ ++ // Set demod parameters. (QAM mode, symbol rate, alpha mode, IF frequency, spectrum mode) ++ // Note: In the example: ++ // 1. QAM is 64. ++ // 2. Symbol rate is 6.952 MHz. ++ // 3. Alpha is 0.15. ++ // 4. IF frequency is 36 MHz. ++ // 5. Spectrum mode is SPECTRUM_INVERSE. ++ QamMode = QAM_QAM_64; ++ SymbolRateHz = 6952000; ++ AlphaMode = QAM_ALPHA_0P15; ++ IfFreqHz = IF_FREQ_36000000HZ; ++ SpectrumMode = SPECTRUM_INVERSE; ++ ++ pDemod->SetQamMode(pDemod, QamMode); ++ pDemod->SetSymbolRateHz(pDemod, SymbolRateHz); ++ pDemod->SetAlphaMode(pDemod, AlphaMode); ++ pDemod->SetIfFreqHz(pDemod, IfFreqHz); ++ pDemod->SetSpectrumMode(pDemod, SpectrumMode); ++ ++ ++ // Need to set tuner before demod software reset. ++ // The order to set demod and tuner is not important. ++ // Note: One can use "pDemod->SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1);" ++ // for tuner I2C command forwarding. ++ ++ ++ // Reset demod by software reset. ++ pDemod->SoftwareReset(pDemod); ++ ++ ++ // Wait maximum 1000 ms for demod converge. ++ for(i = 0; i < 25; i++) ++ { ++ // Wait 40 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 40); ++ ++ // Check signal lock status through frame lock. ++ // Note: If Answer is YES, frame is locked. ++ // If Answer is NO, frame is not locked. ++ pDemod->IsFrameLocked(pDemod, &Answer); ++ ++ if(Answer == YES) ++ { ++ // Signal is locked. ++ break; ++ } ++ } ++ ++ ++ ++ ++ ++ // ==== Get QAM demod information ===== ++ ++ // Get demod type. ++ // Note: One can find demod type in MODULE_TYPE enumeration. ++ pDemod->GetDemodType(pDemod, &DemodType); ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Ask demod if it is connected to I2C bus. ++ // Note: If Answer is YES, demod is connected to I2C bus. ++ // If Answer is NO, demod is not connected to I2C bus. ++ pDemod->IsConnectedToI2c(pDemod, &Answer); ++ ++ ++ // Get demod parameters. (QAM mode, symbol rate, alpha mode, IF frequency, spectrum mode) ++ pDemod->GetQamMode(pDemod, &QamMode); ++ pDemod->GetSymbolRateHz(pDemod, &SymbolRateHz); ++ pDemod->GetAlphaMode(pDemod, &AlphaMode); ++ pDemod->GetIfFreqHz(pDemod, &IfFreqHz); ++ pDemod->GetSpectrumMode(pDemod, &SpectrumMode); ++ ++ ++ // Get demod AGC value. ++ // Note: The range of RF AGC and IF AGC value is -1024 ~ 1023. ++ // The range of digital AGC value is 0 ~ 134217727. ++ pDemod->GetRfAgc(pDemod, &RfAgc); ++ pDemod->GetIfAgc(pDemod, &IfAgc); ++ pDemod->GetDiAgc(pDemod, &DiAgc); ++ ++ ++ // Get demod lock status. ++ // Note: If Answer is YES, it is locked. ++ // If Answer is NO, it is not locked. ++ pDemod->IsAagcLocked(pDemod, &Answer); ++ pDemod->IsEqLocked(pDemod, &Answer); ++ pDemod->IsFrameLocked(pDemod, &Answer); ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz); ++ ++ ++ // Get BER and PER. ++ // Note: Test packet number = pow(2, (2 * 5 + 4)) = 16384 ++ // Maximum wait time = 1000 ms = 1 second ++ pDemod->GetErrorRate(pDemod, 5, 1000, &BerNum, &BerDen, &PerNum, &PerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pDemod->GetSignalStrength(pDemod, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pDemod->GetSignalQuality(pDemod, &SignalQuality); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Page register address ++#define QAM_DEMOD_PAGE_REG_ADDR 0x0 ++ ++ ++/// QAM QAM modes ++enum QAM_QAM_MODE ++{ ++ QAM_QAM_4, ///< QPSK ++ QAM_QAM_16, ///< 16 QAM ++ QAM_QAM_32, ///< 32 QAM ++ QAM_QAM_64, ///< 64 QAM ++ QAM_QAM_128, ///< 128 QAM ++ QAM_QAM_256, ///< 256 QAM ++ QAM_QAM_512, ///< 512 QAM ++ QAM_QAM_1024, ///< 1024 QAM ++}; ++#define QAM_QAM_MODE_NUM 8 ++ ++ ++/// QAM alpha modes ++enum QAM_ALPHA_MODE ++{ ++ QAM_ALPHA_0P12, ///< Alpha = 0.12 ++ QAM_ALPHA_0P13, ///< Alpha = 0.13 ++ QAM_ALPHA_0P15, ///< Alpha = 0.15 ++ QAM_ALPHA_0P18, ///< Alpha = 0.18 ++ QAM_ALPHA_0P20, ///< Alpha = 0.20 ++}; ++#define QAM_ALPHA_MODE_NUM 5 ++ ++ ++/// QAM demod enhancement modes ++enum QAM_DEMOD_EN_MODE ++{ ++ QAM_DEMOD_EN_NONE, ///< None demod enhancement ++ QAM_DEMOD_EN_AM_HUM, ///< AM-hum demod enhancement ++}; ++#define QAM_DEMOD_EN_MODE_NUM 2 ++ ++ ++/// QAM demod configuration mode ++enum QAM_DEMOD_CONFIG_MODE ++{ ++ QAM_DEMOD_CONFIG_OC, ///< OpenCable demod configuration ++ QAM_DEMOD_CONFIG_DVBC, ///< DVB-C demod configuration ++}; ++#define QAM_DEMOD_CONFIG_MODE_NUM 2 ++ ++ ++ ++ ++ ++// Register entry definitions ++ ++// Base register entry for 8-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_BASE_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Primary base register entry for 8-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_PRIMARY_BASE_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Monitor register entry for 8-bit address ++#define QAM_MONITOR_REG_INFO_TABLE_LEN 2 ++typedef struct ++{ ++ int IsAvailable; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned char SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_MONITOR_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Primary monitor register entry for 8-bit address ++typedef struct ++{ ++ int MonitorRegBitName; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned char SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_PRIMARY_MONITOR_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Base register entry for 16-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_BASE_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Primary base register entry for 16-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_PRIMARY_BASE_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Monitor register entry for 16-bit address ++#define QAM_MONITOR_REG_INFO_TABLE_LEN 2 ++typedef struct ++{ ++ int IsAvailable; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned short SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_MONITOR_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Primary monitor register entry for 16-bit address ++typedef struct ++{ ++ int MonitorRegBitName; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned short SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_PRIMARY_MONITOR_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++ ++ ++// Register bit name definitions ++ ++/// Base register bit name ++enum QAM_REG_BIT_NAME ++{ ++ // Generality ++ QAM_SYS_VERSION, ++ QAM_OPT_I2C_RELAY, ++ QAM_I2CT_EN_CTRL, // for RTL2836B DVB-C only ++ QAM_SOFT_RESET, ++ QAM_SOFT_RESET_FF, ++ ++ // Miscellany ++ QAM_OPT_I2C_DRIVE_CURRENT, ++ QAM_GPIO2_OEN, ++ QAM_GPIO3_OEN, ++ QAM_GPIO2_O, ++ QAM_GPIO3_O, ++ QAM_GPIO2_I, ++ QAM_GPIO3_I, ++ QAM_INNER_DATA_STROBE, ++ QAM_INNER_DATA_SEL1, ++ QAM_INNER_DATA_SEL2, ++ QAM_INNER_DATA1, ++ QAM_INNER_DATA2, ++ ++ // QAM mode ++ QAM_QAM_MODE, ++ ++ // AD ++ QAM_AD_AV, // for RTL2840 only ++ ++ // AAGC ++ QAM_OPT_RF_AAGC_DRIVE_CURRENT, // for RTL2840, RTD2885 QAM only ++ QAM_OPT_IF_AAGC_DRIVE_CURRENT, // for RTL2840, RTD2885 QAM only ++ QAM_AGC_DRIVE_LV, // for RTL2836B DVB-C only ++ QAM_OPT_RF_AAGC_DRIVE, ++ QAM_OPT_IF_AAGC_DRIVE, ++ QAM_OPT_RF_AAGC_OEN, // for RTL2840 only ++ QAM_OPT_IF_AAGC_OEN, // for RTL2840 only ++ QAM_PAR_RF_SD_IB, ++ QAM_PAR_IF_SD_IB, ++ QAM_AAGC_FZ_OPTION, ++ QAM_AAGC_TARGET, ++ QAM_RF_AAGC_MAX, ++ QAM_RF_AAGC_MIN, ++ QAM_IF_AAGC_MAX, ++ QAM_IF_AAGC_MIN, ++ QAM_VTOP, ++ QAM_KRF, // for RTD2885 QAM only ++ QAM_KRF_MSB, ++ QAM_KRF_LSB, ++ QAM_AAGC_MODE_SEL, ++ QAM_AAGC_LD, ++ QAM_OPT_RF_AAGC_OE, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_OPT_IF_AAGC_OE, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_IF_AGC_DRIVING, // for RTL2820 OpenCable only ++ QAM_RF_AGC_DRIVING, // for RTL2820 OpenCable only ++ QAM_AAGC_INIT_LEVEL, ++ ++ // DDC ++ QAM_DDC_FREQ, ++ QAM_SPEC_INV, ++ ++ // Timing recovery ++ QAM_TR_DECI_RATIO, ++ ++ // Carrier recovery ++ QAM_CR_LD, ++ ++ // Equalizer ++ QAM_EQ_LD, ++ QAM_MSE, ++ ++ // Frame sync. indicator ++ QAM_SYNCLOST, // for RTL2840, RTD2885 QAM only ++ QAM_FS_SYNC_STROBE, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_FS_SYNC_LOST, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_OC_MPEG_SYNC_MODE, ++ ++ ++ // BER ++ QAM_BER_RD_STROBE, ++ QAM_BERT_EN, ++ QAM_BERT_HOLD, ++ QAM_DIS_AUTO_MODE, ++ QAM_TEST_VOLUME, ++ QAM_BER_REG0, ++ QAM_BER_REG1, ++ QAM_BER_REG2_15_0, ++ QAM_BER_REG2_18_16, ++ ++ QAM_OC_BER_RD_STROBE, // for RTD2885 QAM only ++ QAM_OC_BERT_EN, // for RTD2885 QAM only ++ QAM_OC_BERT_HOLD, // for RTD2885 QAM only ++ QAM_OC_DIS_AUTO_MODE, // for RTD2885 QAM only ++ QAM_OC_TEST_VOLUME, // for RTD2885 QAM only ++ QAM_OC_BER_REG0, // for RTD2885 QAM only ++ QAM_OC_BER_REG1, // for RTD2885 QAM only ++ QAM_OC_BER_REG2_15_0, // for RTD2885 QAM only ++ QAM_OC_BER_REG2_18_16, // for RTD2885 QAM only ++ ++ QAM_DVBC_BER_RD_STROBE, // for RTD2885 QAM only ++ QAM_DVBC_BERT_EN, // for RTD2885 QAM only ++ QAM_DVBC_BERT_HOLD, // for RTD2885 QAM only ++ QAM_DVBC_DIS_AUTO_MODE, // for RTD2885 QAM only ++ QAM_DVBC_TEST_VOLUME, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG0, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG1, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG2_15_0, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG2_18_16, // for RTD2885 QAM only ++ ++ ++ // MPEG TS output interface ++ QAM_CKOUTPAR, ++ QAM_CKOUT_PWR, ++ QAM_CDIV_PH0, ++ QAM_CDIV_PH1, ++ QAM_MPEG_OUT_EN, // for RTL2840 only ++ QAM_OPT_MPEG_DRIVE_CURRENT, // for RTL2840 only ++ QAM_NO_REINVERT, // for RTL2840 only ++ QAM_FIX_TEI, // for RTL2840 only ++ QAM_SERIAL, // for RTL2840 only ++ QAM_OPT_MPEG_IO, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_OPT_M_OEN, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_REPLA_SD_EN, // for RTL2820 OpenCable only ++ QAM_TEI_SD_ERR_EN, // for RTL2820 OpenCable only ++ QAM_TEI_RS_ERR_EN, // for RTL2820 OpenCable only ++ QAM_SET_MPEG_ERR, // for RTL2820 OpenCable only ++ ++ QAM_OC_CKOUTPAR, // for RTD2885 QAM only ++ QAM_OC_CKOUT_PWR, // for RTD2885 QAM only ++ QAM_OC_CDIV_PH0, // for RTD2885 QAM only ++ QAM_OC_CDIV_PH1, // for RTD2885 QAM only ++ QAM_OC_SERIAL, // for RTD2885 QAM only ++ ++ QAM_DVBC_CKOUTPAR, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_CKOUT_PWR, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_CDIV_PH0, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_CDIV_PH1, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_NO_REINVERT, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_FIX_TEI, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_SERIAL, // for RTD2885 QAM, RTL2836B DVB-C only ++ ++ ++ // Monitor ++ QAM_ADC_CLIP_CNT_REC, ++ QAM_DAGC_LEVEL_26_11, ++ QAM_DAGC_LEVEL_10_0, ++ QAM_RF_AAGC_SD_IN, ++ QAM_IF_AAGC_SD_IN, ++ QAM_KI_TR_OUT_30_15, ++ QAM_KI_TR_OUT_14_0, ++ QAM_KI_CR_OUT_15_0, ++ QAM_KI_CR_OUT_31_16, ++ ++ // Specific register ++ QAM_SPEC_SIGNAL_INDICATOR, ++ QAM_SPEC_ALPHA_STROBE, ++ QAM_SPEC_ALPHA_SEL, ++ QAM_SPEC_ALPHA_VAL, ++ QAM_SPEC_SYMBOL_RATE_REG_0, ++ QAM_SPEC_SYMBOL_RATE_STROBE, ++ QAM_SPEC_SYMBOL_RATE_SEL, ++ QAM_SPEC_SYMBOL_RATE_VAL, ++ QAM_SPEC_REG_0_STROBE, ++ QAM_SPEC_REG_0_SEL, ++ QAM_SPEC_INIT_A0, // for RTL2840 only ++ QAM_SPEC_INIT_A1, // for RTL2840 only ++ QAM_SPEC_INIT_A2, // for RTL2840 only ++ QAM_SPEC_INIT_B0, // for RTL2820 OpenCable only ++ QAM_SPEC_INIT_C1, // for RTL2820 OpenCable only ++ QAM_SPEC_INIT_C2, // for RTL2820 OpenCable only ++ QAM_SPEC_INIT_C3, // for RTL2820 OpenCable only ++ ++ // GPIO ++ QAM_OPT_GPIOA_OE, // for RTL2836B DVB-C only ++ ++ // Pseudo register for test only ++ QAM_TEST_REG_0, ++ QAM_TEST_REG_1, ++ QAM_TEST_REG_2, ++ QAM_TEST_REG_3, ++ ++ ++ // Item terminator ++ QAM_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++/// Monitor register bit name ++enum QAM_MONITOR_REG_BIT_NAME ++{ ++ // Generality ++ QAM_ADC_CLIP_CNT, ++ QAM_DAGC_VALUE, ++ QAM_RF_AGC_VALUE, ++ QAM_IF_AGC_VALUE, ++ QAM_TR_OFFSET, ++ QAM_CR_OFFSET, ++ ++ // Specific monitor register ++ QAM_SPEC_MONITER_INIT_0, ++ ++ // Item terminator ++ QAM_MONITOR_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++ ++// Register table length definitions ++#define QAM_BASE_REG_TABLE_LEN_MAX QAM_REG_BIT_NAME_ITEM_TERMINATOR ++#define QAM_MONITOR_REG_TABLE_LEN_MAX QAM_MONITOR_REG_BIT_NAME_ITEM_TERMINATOR ++ ++ ++ ++ ++ ++/// QAM demod module pre-definition ++typedef struct QAM_DEMOD_MODULE_TAG QAM_DEMOD_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++ ++@brief QAM demod register page setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_PAGE() to set demod register page. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] PageNo Page number ++ ++ ++@retval FUNCTION_SUCCESS Set register page successfully with page number. ++@retval FUNCTION_ERROR Set register page unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_PAGE() with the corresponding function. ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register page with page number 2. ++ pDemod->SetRegPage(pDemod, 2); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register byte setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_BYTES() to set demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bytes successfully with writing bytes. ++@retval FUNCTION_ERROR Set demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_SET_REG_BYTES(). ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_GET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char WritingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bytes (page 1, address 0x17 ~ 0x1b) with 5 writing bytes. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBytes(pDemod, 0x17, WritingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register byte getting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_BYTES() to get demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bytes successfully with reading byte number. ++@retval FUNCTION_ERROR Get demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_GET_REG_BYTES(). ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_SET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char ReadingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bytes (page 1, address 0x17 ~ 0x1b) with reading byte number 5. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBytes(pDemod, 0x17, ReadingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register mask bits setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_MASK_BITS() to set demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register mask bits successfully with writing value. ++@retval FUNCTION_ERROR Set demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_SET_REG_MASK_BITS(). ++ -# The constraints of QAM_DEMOD_FP_SET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_GET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits (page 1, address {0x18, 0x17} [12:5]) with writing value 0x1d. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegMaskBits(pDemod, 0x17, 12, 5, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register mask bits getting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_MASK_BITS() to get demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register mask bits successfully. ++@retval FUNCTION_ERROR Get demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_GET_REG_MASK_BITS(). ++ -# The constraints of QAM_DEMOD_FP_GET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_SET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits (page 1, address {0x18, 0x17} [12:5]). ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegMaskBits(pDemod, 0x17, 12, 5, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_BITS() to set demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using QAM_DEMOD_FP_SET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_GET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBits(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits getting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_BITS() to get demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using QAM_DEMOD_FP_GET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_SET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBits(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits setting function pointer (with page setting) ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE() to set demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name, page setting, and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits getting function pointer (with page setting) ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE() to get demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and page setting. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->GetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// Demod register access for 8-bit address ++typedef struct ++{ ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE SetRegPage; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES SetRegBytes; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES GetRegBytes; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS SetRegBits; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS GetRegBits; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE SetRegBitsWithPage; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE GetRegBitsWithPage; ++} ++QAM_DEMOD_REG_ACCESS_ADDR_8BIT; ++ ++ ++ ++ ++ ++// Demod register access for 16-bit address ++typedef struct ++{ ++ QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES SetRegBytes; ++ QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES GetRegBytes; ++ QAM_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BITS SetRegBits; ++ QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BITS GetRegBits; ++} ++QAM_DEMOD_REG_ACCESS_ADDR_16BIT; ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod type getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_DEMOD_TYPE() to get QAM demod type. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDemodType Pointer to an allocated memory for storing demod type ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_DEMOD_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_GET_DEMOD_TYPE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod I2C device address getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_DEVICE_ADDR() to get QAM demod I2C device address. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing demod I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get demod device address successfully. ++@retval FUNCTION_ERROR Get demod device address unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_GET_DEVICE_ADDR)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod crystal frequency getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() to get QAM demod crystal frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrystalFreqHz Pointer to an allocated memory for storing demod crystal frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod crystal frequency successfully. ++@retval FUNCTION_ERROR Get demod crystal frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod I2C bus connection asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_CONNECTED_TO_I2C() to ask QAM demod if it is connected to I2C bus. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_CONNECTED_TO_I2C() with the corresponding function. ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_IS_CONNECTED_TO_I2C)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod software resetting function pointer ++ ++One can use QAM_DEMOD_FP_SOFTWARE_RESET() to reset QAM demod by software reset. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod by software reset successfully. ++@retval FUNCTION_ERROR Reset demod by software reset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SOFTWARE_RESET() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SOFTWARE_RESET)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod initializing function pointer ++ ++One can use QAM_DEMOD_FP_INITIALIZE() to initialie QAM demod. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize demod successfully. ++@retval FUNCTION_ERROR Initialize demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_INITIALIZE)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod QAM mode setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_QAM_MODE() to set QAM demod QAM mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] QamMode QAM mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod QAM mode successfully. ++@retval FUNCTION_ERROR Set demod QAM mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_QAM_MODE() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_QAM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod symbol rate setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ() to set QAM demod symbol rate in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SymbolRateHz Symbol rate in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod symbol rate successfully. ++@retval FUNCTION_ERROR Set demod symbol rate unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long SymbolRateHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod alpha mode setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_ALPHA_MODE() to set QAM demod alpha mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] AlphaMode Alpha mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod alpha mode successfully. ++@retval FUNCTION_ERROR Set demod alpha mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_ALPHA_MODE() with the corresponding function. ++ ++ ++@see QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_ALPHA_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod IF frequency setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_IF_FREQ_HZ() to set QAM demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] IfFreqHz IF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod IF frequency successfully. ++@retval FUNCTION_ERROR Set demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_IF_FREQ_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod spectrum mode setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_SPECTRUM_MODE() to set QAM demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SpectrumMode Spectrum mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod spectrum mode successfully. ++@retval FUNCTION_ERROR Set demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_SPECTRUM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod QAM mode getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_QAM_MODE() to get QAM demod QAM mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pQamMode Pointer to an allocated memory for storing demod QAM mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod QAM mode successfully. ++@retval FUNCTION_ERROR Get demod QAM mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_QAM_MODE() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_QAM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod symbol rate getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ() to get QAM demod symbol rate in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSymbolRateHz Pointer to an allocated memory for storing demod symbol rate in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod symbol rate successfully. ++@retval FUNCTION_ERROR Get demod symbol rate unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSymbolRateHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod alpha mode getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_ALPHA_MODE() to get QAM demod alpha mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAlphaMode Pointer to an allocated memory for storing demod alpha mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod alpha mode successfully. ++@retval FUNCTION_ERROR Get demod alpha mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_ALPHA_MODE() with the corresponding function. ++ ++ ++@see QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_ALPHA_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod IF frequency getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_IF_FREQ_HZ() to get QAM demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfFreqHz Pointer to an allocated memory for storing demod IF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF frequency successfully. ++@retval FUNCTION_ERROR Get demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_IF_FREQ_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod spectrum mode getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SPECTRUM_MODE() to get QAM demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSpectrumMode Pointer to an allocated memory for storing demod spectrum mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod spectrum mode successfully. ++@retval FUNCTION_ERROR Get demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SPECTRUM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod RF AGC getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_RF_AGC() to get QAM demod RF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pRfAgc Pointer to an allocated memory for storing RF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod RF AGC value successfully. ++@retval FUNCTION_ERROR Get demod RF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_RF_AGC() with the corresponding function. ++ -# The range of RF AGC value is (-pow(2, 10)) ~ (pow(2, 10) - 1). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_RF_AGC)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod IF AGC getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_IF_AGC() to get QAM demod IF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfAgc Pointer to an allocated memory for storing IF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF AGC value successfully. ++@retval FUNCTION_ERROR Get demod IF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_IF_AGC() with the corresponding function. ++ -# The range of IF AGC value is (-pow(2, 10)) ~ (pow(2, 10) - 1). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_IF_AGC)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod digital AGC getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_DI_AGC() to get QAM demod digital AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDiAgc Pointer to an allocated memory for storing digital AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod digital AGC value successfully. ++@retval FUNCTION_ERROR Get demod digital AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_DI_AGC() with the corresponding function. ++ -# The range of digital AGC value is 0 ~ (pow(2, 27) - 1). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_DI_AGC)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod TR offset getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get demod TR offset successfully. ++@retval FUNCTION_ERROR Get demod TR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_TR_OFFSET_PPM)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod CR offset getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod CR offset successfully. ++@retval FUNCTION_ERROR Get demod CR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_CR_OFFSET_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod AAGC lock asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_AAGC_LOCKED() to ask QAM demod if it is AAGC-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform AAGC lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform AAGC lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_AAGC_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_IS_AAGC_LOCKED)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod EQ lock asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_EQ_LOCKED() to ask QAM demod if it is EQ-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform EQ lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform EQ lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_EQ_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_IS_EQ_LOCKED)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod frame lock asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_FRAME_LOCKED() to ask QAM demod if it is frame-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform frame lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform frame lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_FRAME_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_IS_FRAME_LOCKED)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod error rate value getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_ERROR_RATE() to get error rate value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] TestVolume Test volume for setting ++@param [in] WaitTimeMsMax Maximum waiting time in ms ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_ERROR_RATE() with the corresponding function. ++ -# The error test packet number is pow(2, (2 * TestVolume + 4)). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_ERROR_RATE)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod SNR getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod SNR successfully. ++@retval FUNCTION_ERROR Get demod SNR unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SNR_DB)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod signal strength getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal strength successfully. ++@retval FUNCTION_ERROR Get demod signal strength unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SIGNAL_STRENGTH)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod signal quality getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal quality successfully. ++@retval FUNCTION_ERROR Get demod signal quality unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SIGNAL_QUALITY)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod updating function pointer ++ ++One can use QAM_DEMOD_FP_UPDATE_FUNCTION() to update demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod setting successfully. ++@retval FUNCTION_ERROR Update demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &QamDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_UPDATE_FUNCTION)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod reseting function pointer ++ ++One can use QAM_DEMOD_FP_RESET_FUNCTION() to reset demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod setting successfully. ++@retval FUNCTION_ERROR Reset demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_RESET_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &QamDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_RESET_FUNCTION)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/// RTD2885 QAM extra module ++typedef struct RTD2885_QAM_EXTRA_MODULE_TAG RTD2885_QAM_EXTRA_MODULE; ++ ++// RTD2885 QAM extra manipulaing functions ++typedef void ++(*RTD2885_QAM_FP_GET_CONFIG_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pConfigMode ++ ); ++ ++// RTD2885 QAM extra module ++struct RTD2885_QAM_EXTRA_MODULE_TAG ++{ ++ // Variables ++ int ConfigMode; ++ unsigned char Func1TickNum; ++ ++ // Functions ++ RTD2885_QAM_FP_GET_CONFIG_MODE GetConfigMode; ++}; ++ ++ ++ ++ ++ ++/// RTD2840B QAM extra module ++typedef struct RTD2840B_QAM_EXTRA_MODULE_TAG RTD2840B_QAM_EXTRA_MODULE; ++ ++// RTD2840B QAM extra manipulaing functions ++typedef void ++(*RTD2840B_QAM_FP_GET_CONFIG_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pConfigMode ++ ); ++ ++// RTD2840B QAM extra module ++struct RTD2840B_QAM_EXTRA_MODULE_TAG ++{ ++ // Variables ++ int ConfigMode; ++ unsigned char Func1TickNum; ++ ++ // Functions ++ RTD2840B_QAM_FP_GET_CONFIG_MODE GetConfigMode; ++}; ++ ++ ++ ++ ++ ++/// RTD2932 QAM extra module alias ++typedef struct RTD2932_QAM_EXTRA_MODULE_TAG RTD2932_QAM_EXTRA_MODULE; ++ ++// RTD2932 QAM extra manipulaing functions ++typedef void ++(*RTD2932_QAM_FP_GET_CONFIG_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pConfigMode ++ ); ++ ++// RTD2932 QAM extra module ++struct RTD2932_QAM_EXTRA_MODULE_TAG ++{ ++ // Variables ++ int ConfigMode; ++ unsigned char Func1TickNum; ++ ++ // Functions ++ RTD2932_QAM_FP_GET_CONFIG_MODE GetConfigMode; ++}; ++ ++ ++ ++ ++ ++ ++/// RTL2820 OpenCable extra module alias ++typedef struct RTL2820_OC_EXTRA_MODULE_TAG RTL2820_OC_EXTRA_MODULE; ++ ++// RTL2820 OpenCable extra module ++struct RTL2820_OC_EXTRA_MODULE_TAG ++{ ++ // Variables ++ unsigned char Func1TickNum; ++}; ++ ++ ++ ++ ++ ++/// QAM demod module structure ++struct QAM_DEMOD_MODULE_TAG ++{ ++ unsigned long CurrentPageNo; ++ // Private variables ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ int TsInterfaceMode; ++ ++ int QamMode; ++ unsigned long SymbolRateHz; ++ int AlphaMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int IsQamModeSet; ++ int IsSymbolRateHzSet; ++ int IsAlphaModeSet; ++ int IsIfFreqHzSet; ++ int IsSpectrumModeSet; ++ ++ union ///< Demod extra module used by driving module ++ { ++ RTD2885_QAM_EXTRA_MODULE Rtd2885Qam; ++ RTD2840B_QAM_EXTRA_MODULE Rtd2840bQam; ++ RTD2932_QAM_EXTRA_MODULE Rtd2932Qam; ++ RTL2820_OC_EXTRA_MODULE Rtl2820Oc; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ // Register tables ++ union ++ { ++ QAM_BASE_REG_ENTRY_ADDR_8BIT Addr8Bit[QAM_BASE_REG_TABLE_LEN_MAX]; ++ QAM_BASE_REG_ENTRY_ADDR_16BIT Addr16Bit[QAM_BASE_REG_TABLE_LEN_MAX]; ++ } ++ BaseRegTable; ++ ++ union ++ { ++ QAM_MONITOR_REG_ENTRY_ADDR_8BIT Addr8Bit[QAM_MONITOR_REG_TABLE_LEN_MAX]; ++ QAM_MONITOR_REG_ENTRY_ADDR_16BIT Addr16Bit[QAM_MONITOR_REG_TABLE_LEN_MAX]; ++ } ++ MonitorRegTable; ++ ++ ++ // Demod I2C function pointers ++ union ++ { ++ QAM_DEMOD_REG_ACCESS_ADDR_8BIT Addr8Bit; ++ QAM_DEMOD_REG_ACCESS_ADDR_16BIT Addr16Bit; ++ } ++ RegAccess; ++ ++ ++ // Demod manipulating function pointers ++ QAM_DEMOD_FP_GET_DEMOD_TYPE GetDemodType; ++ QAM_DEMOD_FP_GET_DEVICE_ADDR GetDeviceAddr; ++ QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ GetCrystalFreqHz; ++ ++ QAM_DEMOD_FP_IS_CONNECTED_TO_I2C IsConnectedToI2c; ++ QAM_DEMOD_FP_SOFTWARE_RESET SoftwareReset; ++ ++ QAM_DEMOD_FP_INITIALIZE Initialize; ++ QAM_DEMOD_FP_SET_QAM_MODE SetQamMode; ++ QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ SetSymbolRateHz; ++ QAM_DEMOD_FP_SET_ALPHA_MODE SetAlphaMode; ++ QAM_DEMOD_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ QAM_DEMOD_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ QAM_DEMOD_FP_GET_QAM_MODE GetQamMode; ++ QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ GetSymbolRateHz; ++ QAM_DEMOD_FP_GET_ALPHA_MODE GetAlphaMode; ++ QAM_DEMOD_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ QAM_DEMOD_FP_GET_SPECTRUM_MODE GetSpectrumMode; ++ ++ QAM_DEMOD_FP_GET_RF_AGC GetRfAgc; ++ QAM_DEMOD_FP_GET_IF_AGC GetIfAgc; ++ QAM_DEMOD_FP_GET_DI_AGC GetDiAgc; ++ QAM_DEMOD_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ QAM_DEMOD_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ ++ QAM_DEMOD_FP_IS_AAGC_LOCKED IsAagcLocked; ++ QAM_DEMOD_FP_IS_EQ_LOCKED IsEqLocked; ++ QAM_DEMOD_FP_IS_FRAME_LOCKED IsFrameLocked; ++ ++ QAM_DEMOD_FP_GET_ERROR_RATE GetErrorRate; ++ QAM_DEMOD_FP_GET_SNR_DB GetSnrDb; ++ ++ QAM_DEMOD_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ QAM_DEMOD_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ ++ QAM_DEMOD_FP_UPDATE_FUNCTION UpdateFunction; ++ QAM_DEMOD_FP_RESET_FUNCTION ResetFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// QAM demod default I2C functions for 8-bit address ++int ++qam_demod_addr_8bit_default_SetRegPage( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// QAM demod default I2C functions for 16-bit address ++int ++qam_demod_addr_16bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_16bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_16bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_16bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++qam_demod_addr_16bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_16bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// QAM demod default manipulating functions ++void ++qam_demod_default_GetDemodType( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++void ++qam_demod_default_GetDeviceAddr( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++void ++qam_demod_default_GetCrystalFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++int ++qam_demod_default_GetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++int ++qam_demod_default_GetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSymbolRateHz ++ ); ++ ++int ++qam_demod_default_GetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAlphaMode ++ ); ++ ++int ++qam_demod_default_GetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++qam_demod_default_GetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_nim_base.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_nim_base.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_nim_base.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_nim_base.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,496 @@ ++/** ++ ++@file ++ ++@brief QAM NIM base module definition ++ ++QAM NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++*/ ++ ++ ++#include "qam_nim_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_NIM_TYPE ++ ++*/ ++void ++qam_nim_default_GetNimType( ++ QAM_NIM_MODULE *pNim, ++ int *pNimType ++ ) ++{ ++ // Get NIM type from NIM module. ++ *pNimType = pNim->NimType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++qam_nim_default_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod QAM mode. ++ if(pDemod->SetQamMode(pDemod, QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod symbol rate in Hz. ++ if(pDemod->SetSymbolRateHz(pDemod, SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod alpha mode. ++ if(pDemod->SetAlphaMode(pDemod, AlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_PARAMETERS ++ ++*/ ++int ++qam_nim_default_GetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pQamMode, ++ unsigned long *pSymbolRateHz, ++ int *pAlphaMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Get tuner RF frequency in Hz. ++ if(pTuner->GetRfFreqHz(pTuner, pRfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod QAM mode. ++ if(pDemod->GetQamMode(pDemod, pQamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod symbol rate in Hz. ++ if(pDemod->GetSymbolRateHz(pDemod, pSymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod alpha mode. ++ if(pDemod->GetAlphaMode(pDemod, pAlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_IS_SIGNAL_PRESENT ++ ++*/ ++int ++qam_nim_default_IsSignalPresent( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ QAM_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait maximum 1000 ms for signal present check. ++ for(i = 0; i < DEFAULT_QAM_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal present status on demod. ++ // Note: If frame is locked, stop signal present check. ++ if(pDemod->IsFrameLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++qam_nim_default_IsSignalLocked( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ QAM_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait maximum 1000 ms for signal lock check. ++ for(i = 0; i < DEFAULT_QAM_NIM_SINGAL_LOCK_CHECK_TIMES_MAX; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check frame lock status on demod. ++ // Note: If frame is locked, stop signal lock check. ++ if(pDemod->IsFrameLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++qam_nim_default_GetSignalStrength( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal strength from demod. ++ if(pDemod->GetSignalStrength(pDemod, pSignalStrength) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++qam_nim_default_GetSignalQuality( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal quality from demod. ++ if(pDemod->GetSignalQuality(pDemod, pSignalQuality) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_ERROR_RATE ++ ++*/ ++int ++qam_nim_default_GetErrorRate( ++ QAM_NIM_MODULE *pNim, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get error rate from demod. ++ if(pDemod->GetErrorRate(pDemod, TestVolume, WaitTimeMsMax, pBerNum, pBerDen, pPerNum, pPerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_SNR_DB ++ ++*/ ++int ++qam_nim_default_GetSnrDb( ++ QAM_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get SNR in dB from demod. ++ if(pDemod->GetSnrDb(pDemod, pSnrDbNum, pSnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++qam_nim_default_GetTrOffsetPpm( ++ QAM_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TR offset in ppm from demod. ++ if(pDemod->GetTrOffsetPpm(pDemod, pTrOffsetPpm) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++qam_nim_default_GetCrOffsetHz( ++ QAM_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get CR offset in Hz from demod. ++ if(pDemod->GetCrOffsetHz(pDemod, pCrOffsetHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++qam_nim_default_UpdateFunction( ++ QAM_NIM_MODULE *pNim ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_nim_base.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_nim_base.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/qam_nim_base.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/qam_nim_base.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,850 @@ ++#ifndef __QAM_NIM_BASE_H ++#define __QAM_NIM_BASE_H ++ ++/** ++ ++@file ++ ++@brief QAM NIM base module definition ++ ++QAM NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ unsigned long RfFreqHz; ++ int QamMode; ++ unsigned long SymbolRateHz; ++ int AlphaMode; ++ ++ int Answer; ++ unsigned long SignalStrength, SignalQuality; ++ unsigned long BerNum, BerDen, PerNum, PerDen; ++ double Ber, Per; ++ unsigned long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ long TrOffsetPpm, CrOffsetHz; ++ ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ &pNim, ++ &QamNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ &DemodxExtraModuleMemory, // Employ Demod-X extra module. ++ 0x44, // The Demod-X I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The Demod-X crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The Demod-X TS interface mode is serial. ++ ... // Other arguments for Demod-X ++ ++ &TunerxExtraModuleMemory, // Employ Tuner-Y extra module. ++ 0xc0, // The Tuner-Y I2C device address is 0xc0 in 8-bit format. ++ ... // Other arguments for Tuner-Y ++ ); ++ ++ ++ ++ // Get NIM type. ++ // Note: NIM types are defined in the MODULE_TYPE enumeration. ++ pNim->GetNimType(pNim, &NimType); ++ ++ ++ ++ ++ ++ ++ ++ // ==== Initialize NIM and set its parameters ===== ++ ++ // Initialize NIM. ++ pNim->Initialize(pNim); ++ ++ // Set NIM parameters. (RF frequency, QAM mode, symbol rate, alpha mode) ++ // Note: In the example: ++ // 1. RF frequency is 738 MHz. ++ // 2. QAM is 64. ++ // 3. Symbol rate is 6.952 MHz. ++ // 4. Alpha is 0.15. ++ RfFreqHz = 738000000; ++ QamMode = QAM_QAM_64; ++ SymbolRateHz = 6952000; ++ AlphaMode = QAM_ALPHA_0P15; ++ pNim->SetParameters(pNim, RfFreqHz, QamMode, SymbolRateHz, AlphaMode); ++ ++ ++ ++ // Wait 1 second for demod convergence. ++ ++ ++ ++ ++ ++ // ==== Get NIM information ===== ++ ++ // Get NIM parameters. (RF frequency, QAM mode, symbol rate, alpha mode) ++ pNim->GetParameters(pNim, &RfFreqHz, &QamMode, &SymbolRateHz, &AlphaMode); ++ ++ ++ // Get signal present status. ++ // Note: 1. The argument Answer is YES when the NIM module has found QAM signal in the RF channel. ++ // 2. The argument Answer is NO when the NIM module does not find QAM signal in the RF channel. ++ // Recommendation: Use the IsSignalPresent() function for channel scan. ++ pNim->IsSignalPresent(pNim, &Answer); ++ ++ // Get signal lock status. ++ // Note: 1. The argument Answer is YES when the NIM module has locked QAM signal in the RF channel. ++ // At the same time, the NIM module sends TS packets through TS interface hardware pins. ++ // 2. The argument Answer is NO when the NIM module does not lock QAM signal in the RF channel. ++ // Recommendation: Use the IsSignalLocked() function for signal lock check. ++ pNim->IsSignalLocked(pNim, &Answer); ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pNim->GetSignalStrength(pNim, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pNim->GetSignalQuality(pNim, &SignalQuality); ++ ++ ++ // Get BER and PER. ++ // Note: Test packet number = pow(2, (2 * 4 + 4)) = 4096 ++ // Maximum wait time = 1000 ms = 1 second ++ pNim->GetErrorRate(pNim, 4, 1000, &BerNum, &BerDen, &PerNum, &PerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pNim->GetSnrDb(pNim, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pNim->GetTrOffsetPpm(pNim, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pNim->GetCrOffsetHz(pNim, &CrOffsetHz); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++#include "tuner_base.h" ++#include "qam_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define DEFAULT_QAM_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX 1 ++#define DEFAULT_QAM_NIM_SINGAL_LOCK_CHECK_TIMES_MAX 1 ++ ++ ++ ++ ++ ++/// QAM NIM module pre-definition ++typedef struct QAM_NIM_MODULE_TAG QAM_NIM_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod type getting function pointer ++ ++One can use QAM_NIM_FP_GET_NIM_TYPE() to get QAM NIM type. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pNimType Pointer to an allocated memory for storing NIM type ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_NIM_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*QAM_NIM_FP_GET_NIM_TYPE)( ++ QAM_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM initializing function pointer ++ ++One can use QAM_NIM_FP_INITIALIZE() to initialie QAM NIM. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize NIM successfully. ++@retval FUNCTION_ERROR Initialize NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_INITIALIZE)( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM parameter setting function pointer ++ ++One can use QAM_NIM_FP_SET_PARAMETERS() to set QAM NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++@param [in] QamMode QAM mode for setting ++@param [in] SymbolRateHz Symbol rate in Hz for setting ++@param [in] AlphaMode Alpha mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set NIM parameters successfully. ++@retval FUNCTION_ERROR Set NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_SET_PARAMETERS() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE, QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_NIM_FP_SET_PARAMETERS)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM parameter getting function pointer ++ ++One can use QAM_NIM_FP_GET_PARAMETERS() to get QAM NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pRfFreqHz Pointer to an allocated memory for storing NIM RF frequency in Hz ++@param [out] pQamMode Pointer to an allocated memory for storing NIM QAM mode ++@param [out] pSymbolRateHz Pointer to an allocated memory for storing NIM symbol rate in Hz ++@param [out] pAlphaMode Pointer to an allocated memory for storing NIM alpha mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM parameters successfully. ++@retval FUNCTION_ERROR Get NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_PARAMETERS() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE, QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_PARAMETERS)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pQamMode, ++ unsigned long *pSymbolRateHz, ++ int *pAlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal present asking function pointer ++ ++One can use QAM_NIM_FP_IS_SIGNAL_PRESENT() to ask QAM NIM if signal is present. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal present asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal present asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_IS_SIGNAL_PRESENT() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_IS_SIGNAL_PRESENT)( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal lock asking function pointer ++ ++One can use QAM_NIM_FP_IS_SIGNAL_LOCKED() to ask QAM NIM if signal is locked. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_IS_SIGNAL_LOCKED)( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal strength getting function pointer ++ ++One can use QAM_NIM_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal strength successfully. ++@retval FUNCTION_ERROR Get NIM signal strength unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_SIGNAL_STRENGTH)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal quality getting function pointer ++ ++One can use QAM_NIM_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal quality successfully. ++@retval FUNCTION_ERROR Get NIM signal quality unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_SIGNAL_QUALITY)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM error rate value getting function pointer ++ ++One can use QAM_NIM_FP_GET_ERROR_RATE() to get error rate value. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] TestVolume Test volume for setting ++@param [in] WaitTimeMsMax Maximum waiting time in ms ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM error rate value successfully. ++@retval FUNCTION_ERROR Get NIM error rate value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_ERROR_RATE() with the corresponding function. ++ -# The error test packet number is pow(2, (2 * TestVolume + 4)). ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_ERROR_RATE)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM SNR getting function pointer ++ ++One can use QAM_NIM_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM SNR successfully. ++@retval FUNCTION_ERROR Get NIM SNR unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_SNR_DB)( ++ QAM_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM TR offset getting function pointer ++ ++One can use QAM_NIM_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TR offset successfully. ++@retval FUNCTION_ERROR Get NIM TR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_TR_OFFSET_PPM)( ++ QAM_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM CR offset getting function pointer ++ ++One can use QAM_NIM_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get NIM CR offset successfully. ++@retval FUNCTION_ERROR Get NIM CR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_CR_OFFSET_HZ)( ++ QAM_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM updating function pointer ++ ++One can use QAM_NIM_FP_UPDATE_FUNCTION() to update NIM register setting. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update NIM setting successfully. ++@retval FUNCTION_ERROR Update NIM setting unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ ... ++ ); ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pNim->UpdateFunction(pNim); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_NIM_FP_UPDATE_FUNCTION)( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// RTL2840 MT2062 extra module ++typedef struct RTL2840_MT2062_EXTRA_MODULE_TAG RTL2840_MT2062_EXTRA_MODULE; ++struct RTL2840_MT2062_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long IfFreqHz; ++}; ++ ++ ++ ++ ++ ++// RTL2840 MT2063 extra module ++typedef struct RTL2840_MT2063_EXTRA_MODULE_TAG RTL2840_MT2063_EXTRA_MODULE; ++struct RTL2840_MT2063_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long IfFreqHz; ++}; ++ ++ ++ ++ ++ ++/// QAM NIM module structure ++struct QAM_NIM_MODULE_TAG ++{ ++ // Private variables ++ int NimType; ++ int EnhancementMode; ++ ++ union ///< NIM extra module used by driving module ++ { ++ RTL2840_MT2062_EXTRA_MODULE Rtl2840Mt2062; ++ RTL2840_MT2063_EXTRA_MODULE Rtl2840Mt2063; ++ } ++ Extra; ++ ++ ++ // Modules ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module pointer ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ///< Base interface module memory ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module pointer ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ///< I2C bridge module memory ++ ++ TUNER_MODULE *pTuner; ///< Tuner module pointer ++ TUNER_MODULE TunerModuleMemory; ///< Tuner module memory ++ ++ QAM_DEMOD_MODULE *pDemod; ///< QAM demod module pointer ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ///< QAM demod module memory ++ ++ ++ // NIM manipulating functions ++ QAM_NIM_FP_GET_NIM_TYPE GetNimType; ++ QAM_NIM_FP_INITIALIZE Initialize; ++ QAM_NIM_FP_SET_PARAMETERS SetParameters; ++ QAM_NIM_FP_GET_PARAMETERS GetParameters; ++ QAM_NIM_FP_IS_SIGNAL_PRESENT IsSignalPresent; ++ QAM_NIM_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ QAM_NIM_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ QAM_NIM_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ QAM_NIM_FP_GET_ERROR_RATE GetErrorRate; ++ QAM_NIM_FP_GET_SNR_DB GetSnrDb; ++ QAM_NIM_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ QAM_NIM_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ QAM_NIM_FP_UPDATE_FUNCTION UpdateFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// QAM NIM default manipulaing functions ++void ++qam_nim_default_GetNimType( ++ QAM_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++int ++qam_nim_default_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++int ++qam_nim_default_GetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pQamMode, ++ unsigned long *pSymbolRateHz, ++ int *pAlphaMode ++ ); ++ ++int ++qam_nim_default_IsSignalPresent( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++qam_nim_default_IsSignalLocked( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++qam_nim_default_GetSignalStrength( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++qam_nim_default_GetSignalQuality( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++qam_nim_default_GetErrorRate( ++ QAM_NIM_MODULE *pNim, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++qam_nim_default_GetSnrDb( ++ QAM_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++qam_nim_default_GetTrOffsetPpm( ++ QAM_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++int ++qam_nim_default_GetCrOffsetHz( ++ QAM_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++int ++qam_nim_default_UpdateFunction( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u.c 2011-06-15 11:43:59.668821423 +0200 +@@ -0,0 +1,1017 @@ ++ ++#include ++#include ++ ++#include "rtl2832u.h" ++#include "rtl2832u_io.h" ++ ++ ++int dvb_usb_rtl2832u_debug =0; ++module_param_named(debug,dvb_usb_rtl2832u_debug, int, 0644); ++MODULE_PARM_DESC(debug, "Set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); ++ ++ ++int demod_default_type=0; ++module_param_named(demod, demod_default_type, int, 0644); ++MODULE_PARM_DESC(demod, "Set default demod type(0=dvb-t, 1=dtmb, 2=dvb-c)"DVB_USB_DEBUG_STATUS); ++ ++int dtmb_error_packet_discard; ++module_param_named(dtmb_err_discard, dtmb_error_packet_discard, int, 0644); ++MODULE_PARM_DESC(dtmb_err_discard, "Set error packet discard type(0=not discard, 1=discard)"DVB_USB_DEBUG_STATUS); ++ ++ ++//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) ++DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ++//#endif ++ ++//enable /disable rc ++#define RTL2832U_REMOTE_CONTROL_ENABLE 0x00 ++#define RT_use_rc_protocol 0 ++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++static int rtl2832u_remote_control_protocol=RT_use_rc_protocol; ++#define RT_RC_POLLING_INTERVAL_TIME_MS 287 //rc polling interval:default 287mSec ++ ++/*static struct dvb_usb_rc_key rtl2832u_rc_keys_map_table[] = {// realtek Key map ++ { 0x0400, KEY_0 }, // 0 ++ { 0x0401, KEY_1 }, // 1 ++ { 0x0402, KEY_2 }, // 2 ++ { 0x0403, KEY_3 }, // 3 ++ { 0x0404, KEY_4 }, // 4 ++ { 0x0405, KEY_5 }, // 5 ++ { 0x0406, KEY_6 }, // 6 ++ { 0x0407, KEY_7 }, // 7 ++ { 0x0408, KEY_8 }, // 8 ++ { 0x0409, KEY_9 }, // 9 ++ { 0x040c, KEY_POWER }, // POWER ++ { 0x040e, KEY_MUTE }, // MUTE ++ { 0x0410, KEY_VOLUMEUP }, // VOL UP ++ { 0x0411, KEY_VOLUMEDOWN }, // VOL DOWN ++ { 0x0412, KEY_CHANNELUP }, // CH UP ++ { 0x0413, KEY_CHANNELDOWN }, // CH DOWN ++ { 0x0416, KEY_PLAY }, // PLAY ++ { 0x0417, KEY_RECORD }, // RECORD ++ { 0x0418, KEY_PLAYPAUSE }, // PAUSE ++ { 0x0419, KEY_STOP }, // STOP ++ { 0x041e, KEY_UP}, // UP ++ { 0x041f, KEY_DOWN}, // DOWN ++ { 0x0420, KEY_LEFT }, // LEFT ++ { 0x0421, KEY_RIGHT }, // RIGHT ++ { 0x0422, KEY_ZOOM }, // FULL SCREEN -->OK ++ { 0x0447, KEY_AUDIO }, // MY AUDIO ++ { 0x045b, KEY_MENU}, // RED ++ { 0x045c, KEY_EPG }, // GREEN ++ { 0x045d, KEY_FIRST }, // YELLOW ++ { 0x045e, KEY_LAST }, // BLUE ++ { 0x045a, KEY_TEXT }, // TEXT TV ++ { 0x0423, KEY_BACK }, // <- BACK ++ { 0x0414, KEY_FORWARD } // >> ++ };*/ ++ ++//////////////////////////////////////////////////////////////////////////////////////////////////////// ++enum rc_status_define{ ++ RC_FUNCTION_SUCCESS =0, ++ RC_FUNCTION_UNSUCCESS ++}; ++ ++static int rtl2832u_remote_control_state=0; ++static int SampleNum2TNum[] = ++{ ++ 0,0,0,0,0, ++ 1,1,1,1,1,1,1,1,1, ++ 2,2,2,2,2,2,2,2,2, ++ 3,3,3,3,3,3,3,3,3, ++ 4,4,4,4,4,4,4,4,4, ++ 5,5,5,5,5,5,5,5, ++ 6,6,6,6,6,6,6,6,6, ++ 7,7,7,7,7,7,7,7,7, ++ 8,8,8,8,8,8,8,8,8, ++ 9,9,9,9,9,9,9,9,9, ++ 10,10,10,10,10,10,10,10,10, ++ 11,11,11,11,11,11,11,11,11, ++ 12,12,12,12,12,12,12,12,12, ++ 13,13,13,13,13,13,13,13,13, ++ 14,14,14,14,14,14,14 ++}; ++//IRRC register table ++static const RT_rc_set_reg_struct p_rtl2832u_rc_initial_table[]= ++{ ++ {RTD2832U_SYS,RC_USE_DEMOD_CTL1 ,0x00,OP_AND,0xfb}, ++ {RTD2832U_SYS,RC_USE_DEMOD_CTL1 ,0x00,OP_AND,0xf7}, ++ {RTD2832U_USB,USB_CTRL ,0x00,OP_OR ,0x20}, ++ {RTD2832U_SYS,SYS_GPD ,0x00,OP_AND,0xf7}, ++ {RTD2832U_SYS,SYS_GPOE ,0x00,OP_OR ,0x08}, ++ {RTD2832U_SYS,SYS_GPO ,0x00,OP_OR ,0x08}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x20,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_BUFFER_CTRL ,0x80,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IF ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IE ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_DURATION0 ,0xd0,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_DURATION1 ,0x07,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_IDLE_LEN0 ,0xc0,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_IDLE_LEN1 ,0x00,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_GLITCH_LEN ,0x03,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CLK ,0x09,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CONFIG ,0x1c,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_H_Tolerance_LEN ,0x1e,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_L_Tolerance_LEN ,0x1e,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x80,OP_NO ,0xff} ++ ++}; ++ ++int rtl2832u_remoto_control_initial_setting(struct dvb_usb_device *d) ++{ ++ ++ ++ ++ //begin setting ++ int ret = RC_FUNCTION_SUCCESS; ++ u8 data=0,i=0,NumberOfRcInitialTable=0; ++ ++ ++ deb_rc("+rc_%s\n", __FUNCTION__); ++ ++ NumberOfRcInitialTable = sizeof(p_rtl2832u_rc_initial_table)/sizeof(RT_rc_set_reg_struct); ++ ++ ++ for (i=0;i 0) ++ { ++ ++ highestBit = (*pCode)&0x80; ++ lowBits = (*pCode) & 0x7f; ++ TNum=SampleNum2TNum[lowBits]; ++ ++ if(highestBit != 0) TNum = -TNum; ++ ++ pCode++; ++ byte_num--; ++ ++ if(TNum <= -6) state = WAITING_6T; ++ ++ if(WAITING_6T == state) ++ { ++ if(TNum <= -6) state = WAITING_2T_AFTER_6T; ++ } ++ else if(WAITING_2T_AFTER_6T == state) ++ { ++ if(2 == TNum) ++ { ++ state = WAITING_NORMAL_BITS; ++ LastTNum = 0; ++ CurrentBit = 0; ++ } ++ else state = WAITING_6T; ++ } ++ else if(WAITING_NORMAL_BITS == state) ++ { ++ if(0 == LastTNum) LastTNum = TNum; ++ else ++ { ++ if(LastTNum < 0) ucBits[CurrentBit]=1; ++ else ucBits[CurrentBit]=0; ++ ++ CurrentBit++; ++ ++ if(CurrentBit >= frt0_BITS_NUM) ++ { ++ deb_rc("Bad frame received, bits num is error\n"); ++ CurrentBit = frt0_BITS_NUM -1 ; ++ ++ } ++ if(TNum > 3) ++ { ++ for(i=0;i>24) & frt0_BITS_mask0); ++ p_uccode[1]=(u8)((scancode>>16) & frt0_BITS_mask1); ++ p_uccode[2]=(u8)((scancode>>8) & frt0_BITS_mask2); ++ p_uccode[3]=(u8)((scancode>>0) & frt0_BITS_mask3); ++ ++ deb_info("-info_%s 3::rc6:%x %x %x %x \n", __FUNCTION__,p_uccode[0],p_uccode[1],p_uccode[2],p_uccode[3]); ++ ret= RC_FUNCTION_SUCCESS; ++error: ++ ++ return ret; ++} ++ ++ ++static int frt1(u8* rt_uccode,u8 byte_num,u8 *p_uccode) ++{ ++ u8 *pCode = rt_uccode; ++ u8 ucBits[frt1_BITS_NUM]; ++ u8 i=0,CurrentBit=0,index=0; ++ u32 scancode=0; ++ int ret= RC_FUNCTION_SUCCESS; ++ ++ deb_rc("+info_%s \n", __FUNCTION__); ++ if(byte_num < frt1_para1) ++ { ++ deb_rc("Bad rt uc code received, byte_num = %d is error\n",byte_num); ++ ret = RC_FUNCTION_UNSUCCESS; ++ goto error; ++ } ++ ++ memset(ucBits,0,frt1_BITS_NUM); ++ ++ for(i = 0; i < byte_num; i++) ++ { ++ if ((pCode[i] & frt1_para2)< frt1_para3) index=frt1_para5 ; ++ else index=frt1_para6 ; ++ ++ ucBits[i]= (pCode[i] & 0x80) + index; ++ } ++ deb_rc("+rc_%s,%x %x %x [1]\n", __FUNCTION__,ucBits[0],ucBits[1],ucBits[2]); ++ if(ucBits[0] !=frt1_para_uc_1 && ucBits[0] !=frt1_para_uc_2 ) {ret= RC_FUNCTION_UNSUCCESS; goto error;} ++ ++ if(ucBits[1] !=frt1_para5 && ucBits[1] !=frt1_para6) {ret= RC_FUNCTION_UNSUCCESS;goto error;} ++ ++ if(ucBits[2] >= frt1_para_uc_1) ucBits[2] -= 0x01; ++ else {ret= RC_FUNCTION_UNSUCCESS;goto error;} ++ ++ ++ i = 0x02; ++ CurrentBit = 0x00; ++ ++ while(i < byte_num-1) ++ { ++ if(CurrentBit >= 32) break; ++ ++ if((ucBits[i] & 0x0f) == 0x0) ++ { ++ i++; ++ continue; ++ } ++ if(ucBits[i++] == 0x81) ++ { ++ if(ucBits[i] >=0x01) scancode |= 0x00 << (31 - CurrentBit++); ++ ++ ++ ++ ++ } ++ else ++ { ++ if(ucBits[i] >=0x81) scancode |= 0x01 << (31 - CurrentBit++); ++ ++ } ++ ++ ucBits[i] -= 0x01; ++ continue; ++ } ++ //mask process ++ p_uccode[3]=(u8)((scancode>>16) & frt1_BITS_mask3); ++ p_uccode[2]=(u8)((scancode>>24) & frt1_BITS_mask2); ++ p_uccode[1]=(u8)((scancode>>8) & frt1_BITS_mask1); ++ p_uccode[0]=(u8)((scancode>>0) & frt1_BITS_mask0); ++ ++ ++ deb_rc("-info_%s rc5:%x %x %x %x -->scancode =%x\n", __FUNCTION__,p_uccode[0],p_uccode[1],p_uccode[2],p_uccode[3],scancode); ++ ret= RC_FUNCTION_SUCCESS; ++error: ++ ++ ++ return ret; ++} ++ ++static int frt2(u8* rt_uccode,u8 byte_num,u8 *p_uccode) ++{ ++ u8 *pCode = rt_uccode; ++ u8 i=0; ++ u32 scancode=0; ++ u8 out_io=0; ++ ++ int ret= RC_FUNCTION_SUCCESS; ++ ++ deb_info("+info_%s \n", __FUNCTION__); ++ ++ if(byte_num < frt2_para1) goto error; ++ if(pCode[0] != frt2_para2) goto error; ++ if((pCode[1] frt2_para4)) goto error; ++ ++ ++ if( (pCode[2] frt2_para6) ) ++ { ++ ++ if( (pCode[3] frt2_para8 ) &&(pCode[4]==frt2_para9 )) scancode=0xffff; ++ else goto error; ++ ++ } ++ else if( (pCode[2] frt2_para11 ) ) ++ { ++ ++ for (i = 3; i <68; i++) ++ { ++ if ((i% 2)==1) ++ { ++ if( (pCode[i]>frt2_para7 ) || (pCode[i] >24) & frt2_BITS_mask0); ++ p_uccode[1]=(u8)((scancode>>16) & frt2_BITS_mask1); ++ p_uccode[2]=(u8)((scancode>>8) & frt2_BITS_mask2); ++ p_uccode[3]=(u8)((scancode>>0) & frt2_BITS_mask3); ++ ret= RC_FUNCTION_SUCCESS; ++error: ++ ++ return ret; ++} ++#define receiveMaskFlag1 0x80 ++#define receiveMaskFlag2 0x03 ++#define flush_step_Number 0x05 ++#define rt_code_len 0x80 ++static int rtl2832u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) ++{ ++ ++ static const RT_rc_set_reg_struct p_flush_table1[]={ ++ {RTD2832U_RC,IR_RX_CTRL ,0x20,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_BUFFER_CTRL ,0x80,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IF ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IE ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x80,OP_NO ,0xff} ++ ++ }; ++ static const RT_rc_set_reg_struct p_flush_table2[]={ ++ {RTD2832U_RC,IR_RX_IF ,0x03,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_BUFFER_CTRL ,0x80,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x80,OP_NO ,0xff} ++ ++ }; ++ ++ ++ u8 data=0,i=0,byte_count=0; ++ int ret=0; ++ u8 rt_u8_code[rt_code_len]; ++ u8 ucode[4]; ++ u16 scancode=0; ++ ++ ++ ++ ++ if(rtl2832u_remote_control_state == RC_NO_SETTING) ++ { ++ ret=rtl2832u_remoto_control_initial_setting(d); ++ ++ } ++ if ( read_rc_char_bytes( d ,RTD2832U_RC, IR_RX_IF,&data ,LEN_1) ) ++ { ++ //deb_rc("%s : rc -ir register read error! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ if (!(data & receiveMaskFlag1)) ++ { ++ ret =0 ; ++ goto error; ++ } ++ ++ if (data & receiveMaskFlag2) ++ { ++ if ( read_rc_char_bytes( d ,RTD2832U_RC,IR_RX_BC,&byte_count ,LEN_1) ) ++ { ++ //deb_rc("%s : rc -ir register read error! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ if (byte_count == 0 ) ++ { ++ //ret=0; ++ goto error; ++ } ++ ++ //deb_rc("%s : get rc code len = %d \n", __FUNCTION__,byte_count); ++ if ((byte_count%LEN_2) == 1) byte_count+=LEN_1; ++ if (byte_count > rt_code_len) byte_count=rt_code_len; ++ ++ memset(rt_u8_code,0,rt_code_len); ++ ++ if ( read_rc_char_bytes( d ,RTD2832U_RC,IR_RX_BUF,rt_u8_code ,0x80) ) ++ { ++ //deb_rc("%s : rc -ir register read error! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ ++ memset(ucode,0,4); ++ ++ ++ ret=0; ++ if (rtl2832u_remote_control_protocol == RT_RC6) ret =frt0(rt_u8_code,byte_count,ucode); ++ else if (rtl2832u_remote_control_protocol == RT_RC5) ret =frt1(rt_u8_code,byte_count,ucode); ++ else if (rtl2832u_remote_control_protocol == RT_NEC) ret =frt2(rt_u8_code,byte_count,ucode); ++ else ++ { ++ //deb_rc("%s : rc - unknow rc protocol set ! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ ++ if((ret != RC_FUNCTION_SUCCESS) || (ucode[0] ==0 && ucode[1] ==0 && ucode[2] ==0 && ucode[3] ==0)) ++ { ++ //deb_rc("%s : rc-rc is error scan code ! %x %x %x %x \n", __FUNCTION__,ucode[0],ucode[1],ucode[2],ucode[3]); ++ ret=-1; ++ goto error; ++ } ++ scancode=(ucode[2]<<8) | ucode[3] ; ++ deb_info("-%s scan code %x %x %x %x,(0x%x) -- len=%d\n", __FUNCTION__,ucode[0],ucode[1],ucode[2],ucode[3],scancode,byte_count); ++ ////////// map///////////////////////////////////////////////////////////////////////////////////////////////////// ++/* for (i = 0; i < ARRAY_SIZE(rtl2832u_rc_keys_map_table); i++) ++ { ++ if(rtl2832u_rc_keys_map_table[i].scan ==scancode ) ++ { ++ *event = rtl2832u_rc_keys_map_table[i].event; ++ *state = REMOTE_KEY_PRESSED; ++ deb_rc("%s : map number = %d \n", __FUNCTION__,i); ++ break; ++ } ++ ++ }*/ ++ ++ memset(rt_u8_code,0,rt_code_len); ++ byte_count=0; ++ //deb_info("-info_%s :2:%x %x %x %x -- LEN=%d\n", __FUNCTION__,ucode[0],ucode[1],ucode[2],ucode[3],byte_count); ++ for (i=0;i<3;i++) ++ { ++ data= p_flush_table2[i].data; ++ if ( write_rc_char_bytes( d ,RTD2832U_RC, p_flush_table2[i].address,&data,LEN_1) ) ++ { ++ deb_rc("+%s : rc -ir register write error! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ ++ } ++ ++ ret =0; ++ return ret; ++ } ++error: ++ memset(rt_u8_code,0,rt_code_len); ++ byte_count=0; ++ for (i=0;idev , RTD2832U_USB , USB_EPA_CTL , data , 2) ) goto error; ++ } ++ else ++ { ++ data[0] = 0x10; //3stall epa, set bit 4 to 1 ++ data[1] = 0x02; //3reset epa, set bit 9 to 1 ++ if ( write_usb_sys_char_bytes( adap->dev , RTD2832U_USB , USB_EPA_CTL , data , 2) ) goto error; ++ } ++ ++ return 0; ++error: ++ return -1; ++} ++ ++ ++static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) ++{ ++ adap->fe = rtl2832u_fe_attach(adap->dev); ++ return 0; ++} ++ ++ ++static void rtl2832u_usb_disconnect(struct usb_interface *intf) ++{ ++ try_module_get(THIS_MODULE); ++ dvb_usb_device_exit(intf); ++} ++ ++ ++static struct dvb_usb_device_properties rtl2832u_1st_properties; ++static struct dvb_usb_device_properties rtl2832u_2nd_properties; ++static struct dvb_usb_device_properties rtl2832u_3th_properties; ++static struct dvb_usb_device_properties rtl2832u_4th_properties; ++ ++ ++//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) ++static int rtl2832u_usb_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ if ( ( 0== dvb_usb_device_init(intf,&rtl2832u_1st_properties,THIS_MODULE,NULL,adapter_nr) )|| ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_2nd_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_3th_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_4th_properties,THIS_MODULE,NULL,adapter_nr) ) ) ++ return 0; ++ ++ return -ENODEV; ++} ++ ++static struct usb_device_id rtl2832u_usb_table [] = { ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTD2832U_WARM) }, ++ { USB_DEVICE(USB_VID_AZUREWAVE_2, USB_PID_AZUREWAVE_USB_WARM) }, ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_6) }, ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_USB_WARM) }, ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_MINIUSB_WARM) }, ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_5217_WARM) }, ++ ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTD2832U_2ND_WARM) }, ++ { USB_DEVICE(USB_VID_GOLDENBRIDGE, USB_PID_GOLDENBRIDGE_WARM) }, ++ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_WARM) }, ++ { USB_DEVICE(USB_VID_AZUREWAVE_2, USB_PID_AZUREWAVE_MINI_WARM) }, ++ { USB_DEVICE(USB_VID_AZUREWAVE_2, USB_PID_AZUREWAVE_GPS_WARM) }, ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_7) }, ++ ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_3) }, ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_8) }, ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM) }, ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2836_WARM)}, ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2836_2ND_WARM)}, ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTD2832U_3RD_WARM)}, ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTD2832U_4TH_WARM)}, ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_4)}, ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_WARM_4)}, ++ ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_A)}, ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_B)}, ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_C)}, ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_D)}, ++ { USB_DEVICE(USB_VID_THP, USB_PID_THP )}, ++ { USB_DEVICE(USB_VID_THP, USB_PID_THP2)}, ++ { 0 }, ++}; ++ ++ ++MODULE_DEVICE_TABLE(usb, rtl2832u_usb_table); ++ ++static struct dvb_usb_device_properties rtl2832u_1st_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++ } ++ }, ++ #if (RTL2832U_REMOTE_CONTROL_ENABLE == 1) ++ ++ //remote control ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++ .rc_query = rtl2832u_rc_query, //use define quary function ++ #endif ++ ++ .num_device_descs = 6, ++ .devices = { ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[0], NULL }, ++ }, ++ { .name = "DVB-T USB Dongle", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[1], NULL }, ++ }, ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[2], NULL }, ++ }, ++ { .name = "DK DVBT DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[3], NULL }, ++ }, ++ { .name = "DK mini DVBT DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[4], NULL }, ++ }, ++ { .name = "DK 5217 DVBT DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[5], NULL }, ++ }, ++ { NULL }, ++ } ++}; ++ ++ ++static struct dvb_usb_device_properties rtl2832u_2nd_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++ } ++ }, ++ #if (RTL2832U_REMOTE_CONTROL_ENABLE == 1) ++ //remote control ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++ .rc_query = rtl2832u_rc_query, //use define quary function ++ #endif ++ .num_device_descs = 6, ++ .devices = { ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[6], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[7], NULL }, ++ }, ++ { .name = "Digital TV Tuner Card", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[8], NULL }, ++ }, ++ { .name = "DVB-T FTA USB Half Minicard", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[9], NULL }, ++ }, ++ { .name = "DVB-T + GPS Minicard", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[10], NULL }, ++ }, ++ { .name = "UB450-T", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[11], NULL }, ++ }, ++ { NULL }, ++ } ++}; ++ ++ ++ ++static struct dvb_usb_device_properties rtl2832u_3th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++ } ++ }, ++ ++ ++ #if (RTL2832U_REMOTE_CONTROL_ENABLE == 1) ++ //remote control ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++ .rc_query = rtl2832u_rc_query, //use define quary function ++ #endif ++ .num_device_descs = 9, ++ .devices = { ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[12], NULL }, ++ }, ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[13], NULL }, ++ }, ++ { .name = "RT DTV 2832U", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[14], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[15], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[16], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[17], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[18], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[19], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[20], NULL }, ++ } ++ } ++}; ++ ++ ++static struct dvb_usb_device_properties rtl2832u_4th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++ } ++ }, ++ #if (RTL2832U_REMOTE_CONTROL_ENABLE == 1) ++ //remote control ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++ .rc_query = rtl2832u_rc_query, //use define quary function ++ #endif ++ .num_device_descs = 6, ++ .devices = { ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[21], NULL }, ++ }, ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[22], NULL }, ++ }, ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[23], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[24], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[25], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[26], NULL }, ++ }, ++ { NULL }, ++ } ++}; ++ ++ ++ ++static struct usb_driver rtl2832u_usb_driver = { ++ .name = "dvb_usb_rtl2832u", ++ .probe = rtl2832u_usb_probe, ++ .disconnect = rtl2832u_usb_disconnect, ++ .id_table = rtl2832u_usb_table, ++}; ++ ++ ++static int __init rtl2832u_usb_module_init(void) ++{ ++ int result =0 ; ++ ++ deb_info("+info debug open_%s\n", __FUNCTION__); ++ if ((result = usb_register(&rtl2832u_usb_driver))) { ++ err("usb_register failed. (%d)",result); ++ return result; ++ } ++ ++ return 0; ++} ++ ++static void __exit rtl2832u_usb_module_exit(void) ++{ ++ usb_deregister(&rtl2832u_usb_driver); ++ ++ return ; ++} ++ ++ ++ ++module_init(rtl2832u_usb_module_init); ++module_exit(rtl2832u_usb_module_exit); ++ ++////////////////////////////////////////////////////////////////////////////////////////////////////////// ++//Remake : base on linux kernel :2.6.32 ubuntu 10.04 Test // ++////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++MODULE_AUTHOR("Realtek"); ++MODULE_DESCRIPTION("Driver for the RTL2832U DVB-T / RTL2836 DTMB USB2.0 device"); ++MODULE_VERSION("2.0.1"); ++MODULE_LICENSE("GPL"); ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u_fe.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u_fe.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u_fe.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u_fe.c 2010-11-02 09:55:02.000000000 +0100 +@@ -0,0 +1,3383 @@ ++ ++#include "rtl2832u_fe.h" ++#include "rtl2832u_io.h" ++#include "rtl2832u.h" ++ ++extern int demod_default_type; ++extern int dtmb_error_packet_discard; ++ ++static struct rtl2832_reg_addr rtl2832_reg_map[]= { ++ /* RTD2831_RMAP_INDEX_USB_CTRL_BIT5*/ { RTD2832U_USB, USB_CTRL, 5, 5 }, ++ /* RTD2831_RMAP_INDEX_USB_STAT*/ { RTD2832U_USB, USB_STAT, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_USB_EPA_CTL*/ { RTD2832U_USB, USB_EPA_CTL, 0, 31 }, ++ /* RTD2831_RMAP_INDEX_USB_SYSCTL*/ { RTD2832U_USB, USB_SYSCTL, 0, 31 }, ++ /* RTD2831_RMAP_INDEX_USB_EPA_CFG*/ { RTD2832U_USB, USB_EPA_CFG, 0, 31 }, ++ /* RTD2831_RMAP_INDEX_USB_EPA_MAXPKT*/ { RTD2832U_USB, USB_EPA_MAXPKT, 0, 31}, ++ /* RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG*/ { RTD2832U_USB, USB_EPA_FIFO_CFG, 0, 31}, ++ ++ /* RTD2831_RMAP_INDEX_SYS_DEMOD_CTL*/ { RTD2832U_SYS, DEMOD_CTL, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL*/ { RTD2832U_SYS, GPIO_OUTPUT_VAL, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 3, 3 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3*/ { RTD2832U_SYS, GPIO_DIR, 3, 3 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67*/ { RTD2832U_SYS, GPIO_CFG0, 6, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1*/ { RTD2832U_SYS, DEMOD_CTL1, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 1, 1 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1*/ { RTD2832U_SYS, GPIO_DIR, 1, 1 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 6, 6 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6*/ { RTD2832U_SYS, GPIO_DIR, 6, 6 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT5*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 5, 5}, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT5*/ { RTD2832U_SYS, GPIO_DIR, 5, 5}, ++ ++#if 0 ++ /* RTD2831_RMAP_INDEX_SYS_GPD*/ { RTD2832U_SYS, GPD, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPOE*/ { RTD2832U_SYS, GPOE, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPO*/ { RTD2832U_SYS, GPO, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_SYS_0*/ { RTD2832U_SYS, SYS_0, 0, 7 }, ++#endif ++ ++ /* DTMB related */ ++ ++ ++}; ++ ++ ++ ++ ++static void ++custom_wait_ms( ++ BASE_INTERFACE_MODULE* pBaseInterface, ++ unsigned long WaitTimeMs) ++{ ++ platform_wait(WaitTimeMs); ++ return; ++} ++ ++ ++static int ++custom_i2c_read( ++ BASE_INTERFACE_MODULE* pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char* pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ struct dvb_usb_device *d; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ if ( read_rtl2832_stdi2c( d, DeviceAddr , pReadingBytes , ByteNum ) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++static int ++custom_i2c_write( ++ BASE_INTERFACE_MODULE* pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char* pWritingBytes, ++ unsigned long ByteNum) ++{ ++ struct dvb_usb_device *d; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ if ( write_rtl2832_stdi2c( d, DeviceAddr , (unsigned char*)pWritingBytes , ByteNum ) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++static int ++read_usb_sys_register( ++ struct rtl2832_state* p_state, ++ rtl2832_reg_map_index reg_map_index, ++ int* p_val) ++{ ++ RegType reg_type= rtl2832_reg_map[reg_map_index].reg_type; ++ unsigned short reg_addr= rtl2832_reg_map[reg_map_index].reg_addr; ++ int bit_low= rtl2832_reg_map[reg_map_index].bit_low; ++ int bit_high= rtl2832_reg_map[reg_map_index].bit_high; ++ ++ int n_byte_read=(bit_high>> 3)+ 1; ++ ++ *p_val= 0; ++ if (read_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_read, p_val)) goto error; ++ ++ *p_val= ((*p_val>> bit_low) & rtl2832_reg_mask[bit_high- bit_low]); ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++static int ++write_usb_sys_register( ++ struct rtl2832_state* p_state, ++ rtl2832_reg_map_index reg_map_index, ++ int val_write) ++{ ++ RegType reg_type= rtl2832_reg_map[reg_map_index].reg_type; ++ unsigned short reg_addr= rtl2832_reg_map[reg_map_index].reg_addr; ++ int bit_low= rtl2832_reg_map[reg_map_index].bit_low; ++ int bit_high= rtl2832_reg_map[reg_map_index].bit_high; ++ ++ int n_byte_write= (bit_high>> 3)+ 1; ++ int val_read= 0; ++ int new_val_write; ++ ++ if (read_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_write, &val_read)) goto error; ++ ++ new_val_write= (val_read & (~(rtl2832_reg_mask[bit_high- bit_low]<< bit_low))) | (val_write<< bit_low); ++ ++ if (write_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_write, new_val_write)) goto error; ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++static int ++max3543_set_power( ++ struct rtl2832_state* p_state, ++ unsigned char onoff ++ ) ++{ ++ unsigned char data; ++ unsigned char i2c_repeater; ++ ++ ++ if( p_state->tuner_type != RTL2832_TUNER_TYPE_MAX3543) return 0; ++ ++ deb_info(" %s : onoff =%d\n", __FUNCTION__, onoff); ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater |= BIT3; ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ ++ if(onoff) ++ { ++ //turn on BIT7=0 ++ read_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ data &=(~BIT_7_MASK); ++ write_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ } ++ else ++ { ++ //turn off BIT7=1 ++ read_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ data |=BIT_7_MASK; ++ write_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ } ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater &= (~BIT3); ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ ++ ++ return 0; ++ ++} ++ ++ ++static int ++set_tuner_power( ++ struct rtl2832_state* p_state, ++ unsigned char b_gpio4, ++ unsigned char onoff) ++{ ++ ++ int data; ++ ++ if(onoff==0) max3543_set_power(p_state, onoff); ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ ++ if(b_gpio4) ++ { ++ if(onoff) data &= ~(BIT4); //set bit4 to 0 ++ else data |= BIT4; //set bit4 to 1 ++ ++ } ++ else ++ { ++ if(onoff) data &= ~(BIT3); //set bit3 to 0 ++ else data |= BIT3; //set bit3 to 1 ++ } ++ ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ ++ if(onoff==1) max3543_set_power(p_state, onoff); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++ ++//3//////// Set GPIO3 "OUT" => Turn ON/OFF Tuner Power ++//3//////// Set GPIO3 "IN" => Button Wake UP (USB IF) , NO implement in rtl2832u linux driver ++ ++static int ++gpio3_out_setting( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ // GPIO3_PAD Pull-HIGH, BIT76 ++ data = 2; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67,data) ) goto error; ++ ++ // GPO_GPIO3 = 1, GPIO3 output value = 1 ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data |= BIT3; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ // GPD_GPIO3=0, GPIO3 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3,data) ) goto error; ++ ++ // GPOE_GPIO3=1, GPIO3 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3,data) ) goto error; ++ ++ //BTN_WAKEUP_DIS = 1 ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_CTRL_BIT5,data) ) goto error; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++ ++ ++ ++static int ++usb_epa_fifo_reset( ++ struct rtl2832_state* p_state) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ //3 reset epa fifo: ++ //3[9] Reset EPA FIFO ++ //3 [5] FIFO Flush,Write 1 to flush the oldest TS packet (a 188 bytes block) ++ ++ data = 0x0210; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,data) ) goto error; ++ ++ data = 0xffff; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,&data) ) goto error; ++ ++ if( (data & 0xffff) != 0x0210) ++ { ++ deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_CTL = 0x%x\n",data); ++ goto error; ++ } ++ ++ data=0x0000; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,data) ) goto error; ++ ++ data = 0xffff; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,&data) ) goto error; ++ ++ if( ( data & 0xffff) != 0x0000) ++ { ++ deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_CTL = 0x%x\n",data); ++ goto error; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++ ++static int ++usb_init_bulk_setting( ++ struct rtl2832_state* p_state) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ //3 1.FULL packer mode(for bulk) ++ //3 2.DMA enable. ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, &data) ) goto error; ++ ++ data &=0xffffff00; ++ data |= 0x09; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, data) ) goto error; ++ ++ data=0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, &data) ) goto error; ++ ++ if((data&0xff)!=0x09) ++ { ++ deb_info("Open bulk FULL packet mode error!!\n"); ++ goto error; ++ } ++ ++ //3check epa config, ++ //3[9-8]:00, 1 transaction per microframe ++ //3[7]:1, epa enable ++ //3[6-5]:10, bulk mode ++ //3[4]:1, device to host ++ //3[3:0]:0001, endpoint number ++ data = 0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CFG, &data) ) goto error; ++ if((data&0x0300)!=0x0000 || (data&0xff)!=0xd1) ++ { ++ deb_info("Open bulk EPA config error! data=0x%x \n" , data); ++ goto error; ++ } ++ ++ //3 EPA maxsize packet ++ //3 512:highspeedbulk, 64:fullspeedbulk. ++ //3 940:highspeediso, 940:fullspeediso. ++ ++ //3 get info :HIGH_SPEED or FULL_SPEED ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_STAT, &data) ) goto error; ++ if(data&0x01) ++ { ++ data = 0x00000200; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, data) ) goto error; ++ ++ data=0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, &data) ) goto error; ++ ++ if((data&0xffff)!=0x0200) ++ { ++ deb_info("Open bulk EPA max packet size error!\n"); ++ goto error; ++ } ++ ++ deb_info("HIGH SPEED\n"); ++ } ++ else ++ { ++ data = 0x00000040; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, data) ) goto error; ++ ++ data=0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, &data) ) goto error; ++ ++ if((data&0xffff)!=0x0200) ++ { ++ deb_info("Open bulk EPA max packet size error!\n"); ++ goto error; ++ } ++ ++ deb_info("FULL SPEED\n"); ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++static int ++usb_init_setting( ++ struct rtl2832_state* p_state) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if ( usb_init_bulk_setting(p_state) ) goto error; ++ ++ //3 change fifo length of EPA ++ data = 0x00000014; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, data) ) goto error; ++ data = 0xcccccccc; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, &data) ) goto error; ++ if( (data & 0xff) != 0x14) ++ { ++ deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG =0x%x\n",data); ++ goto error; ++ } ++ ++ if ( usb_epa_fifo_reset(p_state) ) goto error; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++static int ++suspend_latch_setting( ++ struct rtl2832_state* p_state, ++ unsigned char resume) ++{ ++ ++ int data; ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if (resume) ++ { ++ //3 Suspend_latch_en = 0 => Set BIT4 = 0 ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data &= (~BIT4); //set bit4 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ else ++ { ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data |= BIT4; //set bit4 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++//3////// DEMOD_CTL1 => IR Setting , IR wakeup from suspend mode ++//3////// if resume =1, resume ++//3////// if resume = 0, suspend ++ ++ ++static int ++demod_ctl1_setting( ++ struct rtl2832_state* p_state, ++ unsigned char resume) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if(resume) ++ { ++ // IR_suspend ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data &= (~BIT2); //set bit2 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ ++ //Clk_400k ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data &= (~BIT3); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ else ++ { ++ //Clk_400k ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data |= BIT3; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ ++ // IR_suspend ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data |= BIT2; //set bit2 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++ ++ ++static int ++demod_ctl_setting( ++ struct rtl2832_state* p_state, ++ unsigned char resume, ++ unsigned char on) ++{ ++ ++ int data; ++ unsigned char tmp; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if(resume) ++ { ++ // PLL setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT7; //set bit7 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ ++ //2 + Begin LOCK ++ // Demod H/W Reset ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT5); //set bit5 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT5; //set bit5 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ //3 reset page chache to 0 ++ if ( read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 0, 1, &tmp, 1 ) ) goto error; ++ //2 -End LOCK ++ ++ // delay 5ms ++ platform_wait(5); ++ ++ ++ if(on) ++ { ++ // ADC_Q setting on ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT3; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // ADC_I setting on ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT6; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ } ++ else ++ { ++ // ADC_I setting off ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT6); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // ADC_Q setting off ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT3); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ } ++ } ++ else ++ { ++ ++ // ADC_I setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT6); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // ADC_Q setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT3); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // PLL setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT7); //set bit7 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++static int ++read_tuner_id_register( ++ struct rtl2832_state* p_state, ++ unsigned char tuner_addr, ++ unsigned char tuner_offset, ++ unsigned char* id_data, ++ unsigned char length) ++{ ++ unsigned char i2c_repeater; ++ struct dvb_usb_device* d = p_state->d; ++ ++ //2 + Begin LOCK ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater |= BIT3; ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ ++ if(read_rtl2832_tuner_register(d, tuner_addr, tuner_offset, id_data, length)) goto error; ++ ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater &= (~BIT3); ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ //2 - End LOCK ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++static int ++check_mxl5007t_chip_version( ++ struct rtl2832_state* p_state, ++ unsigned char *chipversion) ++{ ++ ++ unsigned char Buffer[LEN_2_BYTE]; ++ unsigned char i2c_repeater; ++ ++ struct dvb_usb_device* d = p_state->d; ++ ++ ++ Buffer[0] = (unsigned char)MXL5007T_I2C_READING_CONST; ++ Buffer[1] = (unsigned char)MXL5007T_CHECK_ADDRESS; ++ ++ ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater |= BIT3; ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ ++ ++ write_rtl2832_stdi2c(d, MXL5007T_BASE_ADDRESS , Buffer, LEN_2_BYTE); ++ ++ read_rtl2832_stdi2c(d, MXL5007T_BASE_ADDRESS, Buffer, LEN_1_BYTE); ++ ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater &= (~BIT3); ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ ++ ++ ++ switch(Buffer[0]) ++ { ++ case MXL5007T_CHECK_VALUE: ++ *chipversion = MxL_5007T_V4; ++ break; ++ default: ++ *chipversion = MxL_UNKNOWN_ID; ++ break; ++ } ++ ++ return 0; ++ ++error: ++ ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++ ++static int ++check_tuner_type( ++ struct rtl2832_state *p_state) ++{ ++ ++ unsigned char tuner_id_data[2]; ++ unsigned char chip_version; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ if ((!read_tuner_id_register(p_state, MT2266_TUNER_ADDR, MT2266_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ( tuner_id_data[0] == MT2266_CHECK_VAL )) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MT2266; ++ ++ deb_info(" -%s : MT2266 tuner on board...\n", __FUNCTION__); ++ } ++ else if ((!read_tuner_id_register(p_state, FC2580_TUNER_ADDR, FC2580_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ((tuner_id_data[0]&(~BIT7)) == FC2580_CHECK_VAL )) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_FC2580; ++ ++ deb_info(" -%s : FC2580 tuner on board...\n", __FUNCTION__); ++ } ++ else if(( !read_tuner_id_register(p_state, MT2063_TUNER_ADDR, MT2063_CHECK_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ( tuner_id_data[0]==MT2063_CHECK_VALUE || tuner_id_data[0]==MT2063_CHECK_VALUE_2)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MT2063; ++ ++ deb_info(" -%s : MT2063 tuner on board...\n", __FUNCTION__); ++ ++ } ++ else if(( !read_tuner_id_register(p_state, MAX3543_TUNER_ADDR, MAX3543_CHECK_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ( tuner_id_data[0]==MAX3543_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MAX3543; ++ ++ deb_info(" -%s : MAX3543 tuner on board...\n", __FUNCTION__); ++ ++ } ++ else if ((!read_tuner_id_register(p_state, TUA9001_TUNER_ADDR, TUA9001_OFFSET, tuner_id_data, LEN_2_BYTE)) && ++ (((tuner_id_data[0]<<8)|tuner_id_data[1]) == TUA9001_CHECK_VAL )) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_TUA9001; ++ ++ deb_info(" -%s : TUA9001 tuner on board...\n", __FUNCTION__); ++ } ++ else if ((!check_mxl5007t_chip_version(p_state, &chip_version)) && ++ (chip_version == MXL5007T_CHECK_VALUE) ) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MXL5007T; ++ ++ deb_info(" -%s : MXL5007T tuner on board...\n", __FUNCTION__); ++ } ++ else if ((!read_tuner_id_register(p_state, FC0012_BASE_ADDRESS , FC0012_CHECK_ADDRESS, tuner_id_data, LEN_1_BYTE)) && ++ (tuner_id_data[0] == FC0012_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_FC0012; ++ ++ deb_info(" -%s : FC0012 tuner on board...\n", __FUNCTION__); ++ } ++ else if((!read_tuner_id_register(p_state, E4000_BASE_ADDRESS, E4000_CHECK_ADDRESS, tuner_id_data, LEN_1_BYTE)) && ++ (tuner_id_data[0] == E4000_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_E4000; ++ deb_info(" -%s : E4000 tuner on board...\n", __FUNCTION__); ++ } ++ else ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_UNKNOWN; ++ ++ deb_info(" -%s : Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ ++ return 0; ++error: ++ return -1; ++} ++ ++static int ++gpio1_output_enable_direction( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ // GPD_GPIO1=0, GPIO1 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1,data) ) goto error; ++ ++ // GPOE_GPIO1=1, GPIO1 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1,data) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++static int ++gpio6_output_enable_direction( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ // GPD_GPIO6=0, GPIO6 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6,data) ) goto error; ++ ++ // GPOE_GPIO6=1, GPIO6 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6,data) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++static int ++gpio5_output_enable_direction( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ // GPD_GPIO5=0, GPIO5 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT5,data) ) goto error; ++ ++ // GPOE_GPIO5=1, GPIO5 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT5,data) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++static int ++check_dvbt_reset_parameters( ++ struct rtl2832_state* p_state, ++ unsigned long frequency, ++ enum fe_bandwidth bandwidth, ++ int* reset_needed) ++{ ++ ++ int is_lock; ++ unsigned int diff_ms; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ *reset_needed = 1; //3initialize "reset_needed" ++ ++ if( (p_state->current_frequency == frequency) && (p_state->current_bandwidth == bandwidth) ) ++ { ++ if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error; ++ diff_ms = 0; ++ ++ while( !(is_lock == LOCKED || diff_ms > 200) ) ++ { ++ platform_wait(40); ++ diff_ms += 40; ++ if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error; ++ } ++ ++ if (is_lock==YES) ++ { ++ *reset_needed = 0; //3 set "reset_needed" = 0 ++ deb_info("%s : The same frequency = %d setting\n", __FUNCTION__, (int)frequency); ++ } ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ ++ *reset_needed = 1; //3 set "reset_needed" = 1 ++ return 1; ++} ++ ++ ++#if UPDATE_FUNC_ENABLE_2832 ++void ++rtl2832_update_functions(struct work_struct *work) ++{ ++ struct rtl2832_state* p_state = container_of( work, struct rtl2832_state, update2832_procedure_work.work); ++ //unsigned long ber_num, ber_dem; ++ //long snr_num = 0; ++ //long snr_dem = 0; ++ //long _snr= 0; ++ ++ if(p_state->pNim == NULL) ++ { ++ deb_info("%s error\n", __FUNCTION__); ++ goto mutex_error; ++ } ++ ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ if(!p_state->is_frequency_valid) ++ { ++ deb_info(" %s no need \n", __FUNCTION__); ++ goto advance_exit; ++ } ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ //if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ // goto advance_exit; ++ ++ // Update tuner mode ++ if( p_state->pNim->UpdateFunction(p_state->pNim)) ++ goto advance_exit; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ //if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ // goto advance_exit; ++ ++ /* p_state->pNim->UpdateFunction(p_state->pNim); ++ p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem); ++ p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ; ++ ++ _snr = snr_num / snr_dem; ++ if( _snr < 0 ) _snr = 0; ++ ++ deb_info("%s : ber = %lu, snr = %lu\n", __FUNCTION__,ber_num,_snr); ++ */ ++ ++advance_exit: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ schedule_delayed_work(&p_state->update2832_procedure_work, UPDATE_PROCEDURE_PERIOD_2832); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ ++ return; ++ ++mutex_error: ++ return; ++ ++} ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++void ++rtl2836_update_function(struct work_struct *work) ++{ ++ struct rtl2832_state* p_state; ++ unsigned long Per1, Per2; ++ long Data1,Data2; ++ unsigned char data; ++ DTMB_DEMOD_MODULE * pDtmbDemod; ++ ++ p_state = container_of(work , struct rtl2832_state , update2836_procedure_work.work); ++ if(p_state->pNim2836 == NULL) ++ { ++ deb_info("%s error\n", __FUNCTION__); ++ goto mutex_error; ++ } ++ pDtmbDemod = p_state->pNim2836->pDemod; ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ if(!p_state->is_frequency_valid) ++ { ++ deb_info(" %s no need \n", __FUNCTION__); ++ goto advance_exit; ++ } ++ ++ if(pDtmbDemod->UpdateFunction(pDtmbDemod)) ++ { ++ deb_info("%s -- UpdateFunction failed\n", __FUNCTION__); ++ } ++ ++ pDtmbDemod->GetPer(pDtmbDemod,&Per1,&Per2); ++ deb_info("%s -- ***GetPer= %d***\n", __FUNCTION__, (int)Per1); ++ ++ pDtmbDemod->GetSnrDb(pDtmbDemod,&Data1,&Data2); ++ deb_info("%s -- ***SNR = %d***\n",__FUNCTION__, (int)(Data1>>2)); ++ ++ read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_6, 0xc0, &data, LEN_1_BYTE); ++ deb_info("%s --***FSM = %d***\n", __FUNCTION__, (data&0x1f)); ++ ++advance_exit: ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ schedule_delayed_work(&p_state->update2836_procedure_work, UPDATE_PROCEDURE_PERIOD_2836); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return; ++ ++mutex_error: ++ return; ++ ++} ++#endif ++ ++static int ++rtl2832_init( ++ struct dvb_frontend* fe) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ //usb_reset_device(p_state->d->udev); ++ ++ if( usb_init_setting(p_state) ) goto error; ++ ++ if( gpio3_out_setting(p_state) ) goto error; //3Set GPIO3 OUT ++ ++ if( demod_ctl1_setting(p_state , 1) ) goto error; //3 DEMOD_CTL1, resume = 1 ++ ++ //if( set_demod_power(p_state , 1) ) goto error; //3 turn ON demod power ++ ++ if( suspend_latch_setting(p_state , 1) ) goto error; //3 suspend_latch_en = 0, resume = 1 ++ ++ if( demod_ctl_setting(p_state , 1, 1) ) goto error; //3 DEMOD_CTL, resume =1; ADC on ++ ++ if( set_tuner_power(p_state, 1, 1) ) goto error; //3 turn ON tuner power ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_TUA9001) ++ { ++ if( gpio1_output_enable_direction(p_state) ) goto error; ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 MXL5007T : Set GPIO6 OUTPUT_EN & OUTPUT_DIR & OUTPUT_VAL for YUAN ++ int data; ++ if( gpio6_output_enable_direction(p_state) ) goto error; ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data |= BIT6; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ int data; ++ if( gpio5_output_enable_direction(p_state)) goto error; ++ ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data |= BIT5; // set GPIO5 high ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data) ) goto error; ++ data &= ~(BIT5); // set GPIO5 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data) ) goto error; ++ } ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2836: ++ { ++ if ( set_demod_2836_power(p_state, 1)) goto error;//32836 on ++ ++ // RTL2832 ADC_I& ADC_Q OFF ++ if( demod_ctl_setting(p_state, 1, 0)) goto error;// ADC off ++ ++ } ++ break; ++ ++ case RTL2840: ++ { ++ if ( set_demod_2840_power(p_state, 1)) goto error;//2840 on ++ ++ // RTL2832 ADC_I& ADC_Q OFF ++ if( demod_ctl_setting(p_state, 1, 0)) goto error;//ADC off ++ } ++ break; ++ } ++ ++ //3 Nim initial ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ { ++ // Nim initialize for 2832 ++ if ( p_state->pNim->Initialize(p_state->pNim) ) goto error; ++ } ++ break; ++ ++ case RTL2836: ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ // Nim initialize for 2836 ++ if ( p_state->pNim2836->Initialize(p_state->pNim2836)) goto error; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ if(dtmb_error_packet_discard) ++ { ++ unsigned char val; ++ if(read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x21, &val, LEN_1_BYTE)) goto error; ++ val &= ~(BIT5); ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x21, &val, LEN_1_BYTE)) goto error; ++ ++ if(read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_4, 0x26, &val, LEN_1_BYTE)) goto error; ++ val &= ~(BIT0); ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_4, 0x26, &val, LEN_1_BYTE)) goto error; ++ ++ deb_info(" dtmb discard error packets\n"); ++ } ++ else ++ { ++ deb_info(" dtmb NOT discard error packets\n"); ++ } ++ } ++ break; ++ ++ case RTL2840: ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ // Nim initialize for 2840 ++ if ( p_state->pNim2840->Initialize(p_state->pNim2840)) goto error; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0)) goto error; ++ } ++ break; ++ } ++ ++ //3 RTL2832U AGC Setting, Serial Mode Switch Setting, PIP Setting based on demod_type ++ if(demod_init_setting(p_state)) goto error; ++ ++ p_state->is_initial = 1; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++#if UPDATE_FUNC_ENABLE_2840 ++ if(p_state->demod_type == RTL2840) ++ schedule_delayed_work(&(p_state->update2840_procedure_work), 0);//3 Initialize update function ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ if(p_state->demod_type == RTL2836) ++ schedule_delayed_work(&(p_state->update2836_procedure_work), 0); ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ if(p_state->demod_type == RTL2832) ++ schedule_delayed_work(&(p_state->update2832_procedure_work), 0);//3 Initialize update function ++#endif ++ ++ return 0; ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ deb_info(" -%s error end\n", __FUNCTION__); ++ ++ return -1; ++} ++ ++ ++static void ++rtl2832_release( ++ struct dvb_frontend* fe) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ MT2266_EXTRA_MODULE* p_mt2266_extra=NULL; ++ MT2063_EXTRA_MODULE* p_mt2063_extra=NULL; ++ ++ TUNER_MODULE* pTuner=NULL; ++ ++ ++ if( p_state->pNim==NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return; ++ } ++ ++ if( (p_state->is_mt2266_nim_module_built) && (p_state->demod_type==RTL2832) ) ++ { ++ pTuner = p_state->pNim->pTuner; ++ p_mt2266_extra = &(pTuner->Extra.Mt2266); ++ p_mt2266_extra->CloseHandle(pTuner); ++ p_state->is_mt2266_nim_module_built = 0; ++ } ++ ++ if( p_state->is_mt2063_nim_module_built) ++ { ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ pTuner=p_state->pNim->pTuner; ++ break; ++ ++ case RTL2840: ++ pTuner=p_state->pNim2840->pTuner; ++ break; ++ ++ } ++ p_mt2063_extra=&(pTuner->Extra.Mt2063); ++ p_mt2063_extra->CloseHandle(pTuner); ++ p_state->is_mt2063_nim_module_built = 0; ++ ++ } ++ ++ if(p_state->is_initial) ++ { ++#if UPDATE_FUNC_ENABLE_2840 ++ if(p_state->demod_type == RTL2840) ++ { ++ cancel_delayed_work( &(p_state->update2840_procedure_work) );//cancel_rearming_delayed_work ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ if(p_state->demod_type == RTL2836) ++ { ++ cancel_delayed_work( &(p_state->update2836_procedure_work)); ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ if(p_state->demod_type == RTL2832) ++ { ++ cancel_delayed_work( &(p_state->update2832_procedure_work) );//cancel_rearming_delayed_work ++ flush_scheduled_work(); ++ } ++#endif ++ p_state->is_initial = 0; ++ } ++ p_state->is_frequency_valid = 0; ++ ++ kfree(p_state); ++ ++ deb_info(" %s \n", __FUNCTION__); ++ ++ return; ++} ++ ++ ++ ++static int ++rtl2832_sleep( ++ struct dvb_frontend* fe) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ ++ //DVBT_DEMOD_MODULE *pDemod; ++ //DVBT_NIM_MODULE *pNim; ++ int data; ++ ++ ++#if 0 //For Debug ++ int page_no, addr_no; ++ unsigned char reg_value; ++#endif ++ ++ //pNim = p_state->pNim; ++ //if( pNim== NULL) ++ //{ ++ // deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ // return -1; ++ //} ++ ++ //pDemod = pNim->pDemod; ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_MAX3543) ++ { ++ //+set MAX3543_CHECK_VALUE to Default value ++ unsigned char i2c_repeater; ++ unsigned char data = MAX3543_CHECK_VALUE; ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater |= BIT3; ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ ++ write_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_CHECK_OFFSET, &data, LEN_1_BYTE); ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater &= (~BIT3); ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ //-set MAX3543_CHECK_VALUE to Default value ++ } ++ ++ ++ if( p_state->is_initial ) ++ { ++ ++#if UPDATE_FUNC_ENABLE_2840 ++ if(p_state->demod_type == RTL2840) ++ { ++ cancel_delayed_work( &(p_state->update2840_procedure_work)); ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ if(p_state->demod_type == RTL2836) ++ { ++ cancel_delayed_work( &(p_state->update2836_procedure_work)); ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ if(p_state->demod_type == RTL2832) ++ { ++ cancel_delayed_work( &(p_state->update2832_procedure_work));// cancel_rearming_delayed_work ++ flush_scheduled_work(); ++ } ++#endif ++ p_state->is_initial = 0; ++ } ++ p_state->is_frequency_valid = 0; ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++#if 0 ++ //2 For debug ++ /* for( page_no = 0; page_no < 3; page_no++ )//2832 ++ { ++ pDemod->SetRegPage(pDemod, page_no); ++ for( addr_no = 0; addr_no < 256; addr_no++ ) ++ { ++ pDemod->GetRegBytes(pDemod, addr_no, ®_value, 1); ++ printk("0x%x, 0x%x, 0x%x\n", page_no, addr_no, reg_value); ++ } ++ }*/ ++ for( page_no = 0; page_no < 10; page_no++ )//2836 ++ { ++ pDemod2836->SetRegPage(pDemod2836, page_no); ++ for( addr_no = 0; addr_no < 256; addr_no++ ) ++ { ++ pDemod2836->GetRegBytes(pDemod2836, addr_no, ®_value, 1); ++ printk("0x%x, 0x%x, 0x%x\n", page_no, addr_no, reg_value); ++ } ++ } ++#endif ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 MXL5007T : Set GPIO6 OUTPUT_VAL OFF for YUAN ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data &= (~BIT6); ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ } ++ ++ ++ if( demod_ctl1_setting(p_state , 0) ) goto error; //3 DEMOD_CTL1, resume = 0 ++ ++ if( set_tuner_power(p_state, 1, 0) ) goto error; //3 turn OFF tuner power ++ ++ if( demod_ctl_setting(p_state , 0, 0) ) goto error; //3 DEMOD_CTL, resume =0 ++ ++ set_demod_2836_power(p_state, 0); //3 RTL2836 power OFF ++ ++ set_demod_2840_power(p_state, 0); //3 RTL2840 power OFF ++ ++ //2 for H/W reason ++ //if( suspend_latch_setting(p_state , 0) ) goto error; //3 suspend_latch_en = 1, resume = 0 ++ ++ //if( set_demod_power(p_state , 0) ) goto error; //3 turn OFF demod power ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ deb_info(" -%s fail\n", __FUNCTION__); ++ return 1; ++} ++ ++ ++ ++static int ++rtl2840_set_parameters( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_parameters* param) ++{ ++ ++ struct rtl2832_state *p_state = fe->demodulator_priv; ++ struct dvb_qam_parameters *p_qam_param= ¶m->u.qam; ++ unsigned long frequency = param->frequency; ++ ++ DVBT_DEMOD_MODULE *pDemod2832; ++ int QamMode; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if(p_state->demod_type == RTL2840 && p_state->pNim2840 == NULL ) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ deb_info(" +%s Freq=%lu , Symbol rate=%u, QAM=%u\n", __FUNCTION__, frequency, p_qam_param->symbol_rate, p_qam_param->modulation); ++ ++ pDemod2832 = p_state->pNim->pDemod; ++ ++ switch(p_qam_param->modulation) ++ { ++ case QPSK : QamMode = QAM_QAM_4; break; ++ case QAM_16 : QamMode = QAM_QAM_16; break; ++ case QAM_32 : QamMode = QAM_QAM_32; break; ++ case QAM_64 : QamMode = QAM_QAM_64; break; ++ case QAM_128 : QamMode = QAM_QAM_128; break; ++ case QAM_256 : QamMode = QAM_QAM_256; break; ++ ++ case QAM_AUTO : ++ default: ++ deb_info(" XXX %s : unknown QAM \n", __FUNCTION__); ++ goto mutex_error; ++ break; ++ ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ p_state->pNim2840->SetParameters(p_state->pNim2840, frequency, QamMode, p_qam_param->symbol_rate, QAM_ALPHA_0P15); ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ ++ deb_info(" -XXX %s \n", __FUNCTION__); ++ ++ return 1; ++ ++} ++ ++ ++ ++ ++static int ++rtl2832_set_parameters( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_parameters* param) ++{ ++ struct rtl2832_state *p_state = fe->demodulator_priv; ++ struct dvb_ofdm_parameters *p_ofdm_param= ¶m->u.ofdm; ++ ++ unsigned long frequency = param->frequency; ++ int bandwidth_mode; ++ int is_signal_present; ++ int reset_needed; ++ unsigned char data; ++ ++ DTMB_DEMOD_MODULE * pDemod2836; ++ DVBT_DEMOD_MODULE * pDemod2832; ++ ++ ++ ++ if( p_state->pNim == NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if(p_state->demod_type == RTL2836 && p_state->pNim2836 == NULL ) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s frequency = %lu , bandwidth = %u\n", __FUNCTION__, frequency ,p_ofdm_param->bandwidth); ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if ( check_dvbt_reset_parameters( p_state , frequency , p_ofdm_param->bandwidth, &reset_needed) ) goto error; ++ ++ if( reset_needed == 0 ) ++ { ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ return 0; ++ } ++ ++ switch (p_ofdm_param->bandwidth) ++ { ++ case BANDWIDTH_6_MHZ: ++ bandwidth_mode = DVBT_BANDWIDTH_6MHZ; ++ break; ++ ++ case BANDWIDTH_7_MHZ: ++ bandwidth_mode = DVBT_BANDWIDTH_7MHZ; ++ break; ++ ++ case BANDWIDTH_8_MHZ: ++ default: ++ bandwidth_mode = DVBT_BANDWIDTH_8MHZ; ++ break; ++ } ++ ++ //add by Dean ++ if (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 ) ++ { ++ ++ if( gpio6_output_enable_direction(p_state) ) goto error; ++ ++ ++ if (frequency > 300000000) ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ deb_info(" %s : Tuner :FC0012 V-band (GPIO6 high)\n", __FUNCTION__); ++ } ++ else ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ deb_info(" %s : Tuner :FC0012 U-band (GPIO6 low)\n", __FUNCTION__); ++ ++ } ++ } ++ ++ ++ ++ ++ ++ if ( p_state->pNim->SetParameters( p_state->pNim, frequency , bandwidth_mode ) ) goto error; ++ ++ if ( p_state->pNim->IsSignalPresent( p_state->pNim, &is_signal_present) ) goto error; ++ deb_info(" %s : ****** Signal Present = %d ******\n", __FUNCTION__, is_signal_present); ++ ++ ++ ++ ++ p_state->is_frequency_valid = 1; ++ ++ ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ pDemod2836 = p_state->pNim2836->pDemod; ++ pDemod2832 = p_state->pNim->pDemod; ++ ++ //if ( check_dtmb_reset_parameters( p_state , frequency , &reset_needed) ) goto error; ++ //if( reset_needed == 0 ) ++ //{ ++ // mutex_unlock(&p_state->i2c_repeater_mutex); ++ // return 0; ++ //} ++ ++ deb_info(("%s: RTL2836 Hold Stage=9\n"),__FUNCTION__); ++ if(read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &data, LEN_1_BYTE)) goto error; ++ data &=(~BIT_0_MASK); //reset Reg_present ++ data &=(~BIT_1_MASK); //reset Reg_lock ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &data, LEN_1_BYTE)) goto error; ++ ++ //3 + RTL2836 Hold Stage=9 ++ data = 0x29; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4d, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xA5; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4e, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x94; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4f, &data, LEN_1_BYTE)) goto error; ++ //3 -RTL2836 Hold Stage=9 ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ if ( p_state->pNim2836->SetParameters( p_state->pNim2836, frequency)) goto error; //no bandwidth setting ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ if(pDemod2832->SoftwareReset(pDemod2832))//2832 swreset ++ goto error; ++ ++ p_state->is_frequency_valid = 1; ++ if( rtl2836_scan_procedure(p_state)) goto error; ++ } ++ ++ ++//#if(UPDATE_FUNC_ENABLE_2832 == 0) ++ //3 FC0012/E4000 update begin -- ++ if(p_state->demod_type == RTL2832 && (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 || p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)) ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ // if( p_state->pNim->UpdateFunction(p_state->pNim)) ++ // goto error; ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ ++ deb_info("%s : fc0012/e4000 update first\n", __FUNCTION__); ++ ++ msleep(50); ++ ++ // if( p_state->pNim->UpdateFunction(p_state->pNim)) goto error; ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ deb_info("%s : fc0012/e4000 update 2nd\n", __FUNCTION__); ++ } ++ //3 FC0012/E4000 update end -- ++ ++//#endif ++ ++ p_state->current_frequency = frequency; ++ p_state->current_bandwidth = p_ofdm_param->bandwidth; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ p_state->current_frequency = 0; ++ p_state->current_bandwidth = -1; ++ p_state->is_frequency_valid = 0; ++ deb_info(" -%s error end\n", __FUNCTION__); ++ ++ return -1; ++ ++} ++ ++ ++ ++static int ++rtl2832_get_parameters( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_parameters* param) ++{ ++ //struct rtl2832_state* p_state = fe->demodulator_priv; ++ return 0; ++} ++ ++ ++static int ++rtl2832_read_status( ++ struct dvb_frontend* fe, ++ fe_status_t* status) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ int is_lock; ++ unsigned long ber_num, ber_dem; ++ long snr_num, snr_dem, snr; ++ ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ *status = 0; //3initialize "status" ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ ++ if( p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem) ) goto error; ++ ++ if (p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ) goto error; ++ ++ if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error; ++ ++ if( is_lock==YES ) *status|= (FE_HAS_CARRIER| FE_HAS_VITERBI| FE_HAS_LOCK| FE_HAS_SYNC| FE_HAS_SIGNAL); ++ ++ snr = snr_num/snr_dem; ++ ++ deb_info("%s :******RTL2832 Signal Lock=%d******\n", __FUNCTION__, is_lock); ++ deb_info("%s : ber_num = %d\n", __FUNCTION__, (unsigned int)ber_num); ++ deb_info("%s : snr = %d \n", __FUNCTION__, (int)snr); ++ } ++ else if(p_state->demod_type == RTL2836)//3Need Change ? ++ { ++ unsigned char val; ++ ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) ++ goto error; ++ ++ if(val & BIT_1_MASK) is_lock = YES; ++ else is_lock = NO; ++ ++ //if(p_state->pNim2836->pDemod->IsSignalLocked(p_state->pNim2836->pDemod, &is_lock)) ++ // goto error; ++ ++ if( is_lock==YES ) *status|= (FE_HAS_CARRIER| FE_HAS_VITERBI| FE_HAS_LOCK| FE_HAS_SYNC| FE_HAS_SIGNAL); ++ ++ deb_info("%s :******RTL2836 Signal Lock=%d******\n", __FUNCTION__, is_lock); ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2840->IsSignalLocked(p_state->pNim2840, &is_lock) != FUNCTION_SUCCESS) goto error; ++ ++ if( is_lock==YES ) *status|= (FE_HAS_CARRIER| FE_HAS_VITERBI| FE_HAS_LOCK| FE_HAS_SYNC| FE_HAS_SIGNAL); ++ ++ deb_info("%s :******RTL2840 Signal Lock=%d******\n", __FUNCTION__, is_lock); ++ ++ } ++ ++ ++#if(UPDATE_FUNC_ENABLE_2832 == 0) ++ //3 FC0012 tuner update begin --- ++ if(p_state->demod_type == RTL2832) ++ { ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ //if( p_state->pNim->UpdateFunction(p_state->pNim)) goto error;//rtl2832_fc0012_UpdateFunction() ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ if( p_state->pNim->UpdateFunction(p_state->pNim))//rtl2832_fc0012_UpdateTunerLnaGainWithRssi() ++ goto error; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ }//3 FC0012 tuner update end --- ++ //3 e4000 tuner update begin --- ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner mode ++ if( p_state->pNim->UpdateFunction(p_state->pNim)) ++ goto error; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ }//3e4000 tuner update end --- ++ } ++#endif ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++static int ++rtl2832_read_ber( ++ struct dvb_frontend* fe, ++ u32* ber) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ unsigned long ber_num, ber_dem; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if( p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem) ) ++ { ++ *ber = 19616; ++ goto error; ++ } ++ *ber = ber_num; ++ deb_info(" %s : ber = 0x%x \n", __FUNCTION__, *ber); ++ } ++ else if(p_state->demod_type == RTL2836)//read PER ++ { ++ unsigned long per1, per2; ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if( p_state->pNim2836->pDemod->GetPer(p_state->pNim2836->pDemod, &per1, &per2)) ++ { ++ *ber = 19616; ++ goto error; ++ } ++ *ber = per1; ++ deb_info(" %s : RTL2836 per = 0x%x \n", __FUNCTION__, *ber); ++ } ++ else if (p_state->demod_type == RTL2840) ++ { ++ unsigned long per1, per2, ber1, ber2; ++ ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ if( p_state->pNim2840->GetErrorRate(p_state->pNim2840, 5, 1000, &ber1, &ber2, &per1, &per2)) ++ { ++ *ber = 19616; ++ goto error; ++ } ++ ++ *ber = ber1; ++ deb_info(" %s : RTL2840 ber = 0x%x \n", __FUNCTION__, *ber); ++ } ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++static int ++rtl2832_read_signal_strength( ++ struct dvb_frontend* fe, ++ u16* strength) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ unsigned long _strength; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if( p_state->pNim->GetSignalStrength( p_state->pNim , &_strength) ) ++ { ++ *strength = 0; ++ goto error; ++ } ++ ++ *strength = (_strength<<8) | _strength; ++ ++ deb_info(" %s : RTL2832 strength = 0x%x \n", __FUNCTION__, *strength); ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ if(p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2836->pDemod->GetSignalStrength( p_state->pNim2836->pDemod , &_strength))// if(p_state->pNim2836->GetSignalStrength( p_state->pNim2836 , &_strength) ) ++ { ++ *strength = 0; ++ goto error; ++ } ++ ++ *strength = (_strength<<8) | _strength; ++ ++ deb_info(" %s : RTL2836 strength = 0x%x \n", __FUNCTION__, *strength); ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ if(p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2840->pDemod->GetSignalStrength( p_state->pNim2840->pDemod , &_strength))// if(p_state->pNim2836->GetSignalStrength( p_state->pNim2836 , &_strength) ) ++ { ++ *strength = 0; ++ goto error; ++ } ++ ++ *strength = (_strength<<8) | _strength; ++ ++ deb_info(" %s : RTL2840 strength = 0x%x \n", __FUNCTION__, *strength); ++ } ++ ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++static int ++rtl2832_read_signal_quality( ++ struct dvb_frontend* fe, ++ u32* quality) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ unsigned long _quality; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if ( p_state->pNim->GetSignalQuality( p_state->pNim , &_quality) ) ++ { ++ *quality = 0; ++ goto error; ++ } ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if ( p_state->pNim2836->pDemod->GetSignalQuality( p_state->pNim2836->pDemod , &_quality) )//if ( p_state->pNim->GetSignalQuality( p_state->pNim , &_quality) ) ++ { ++ *quality = 0; ++ goto error; ++ } ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if ( p_state->pNim2840->pDemod->GetSignalQuality( p_state->pNim2840->pDemod , &_quality) )//if ( p_state->pNim->GetSignalQuality( p_state->pNim , &_quality) ) ++ { ++ *quality = 0; ++ goto error; ++ } ++ } ++ ++ *quality = _quality; ++ ++ deb_info(" %s : quality = 0x%x \n", __FUNCTION__, *quality); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++ ++static int ++rtl2832_read_snr( ++ struct dvb_frontend* fe, ++ u16* snr) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ long snr_num = 0; ++ long snr_dem = 0; ++ long _snr= 0; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if (p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ) ++ { ++ *snr = 0; ++ goto error; ++ } ++ ++ _snr = snr_num / snr_dem; ++ ++ if( _snr < 0 ) _snr = 0; ++ ++ *snr = _snr; ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2836->pDemod->GetSnrDb(p_state->pNim2836->pDemod, &snr_num, &snr_dem)) ++ { ++ *snr = 0; ++ goto error; ++ } ++ *snr = snr_num>>2; ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2840->pDemod->GetSnrDb(p_state->pNim2840->pDemod, &snr_num, &snr_dem)) ++ { ++ *snr = 0; ++ goto error; ++ } ++ *snr = snr_num/snr_dem; ++ } ++ ++ ++ deb_info(" %s : snr = %d \n", __FUNCTION__, *snr); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++ ++static int ++rtl2832_get_tune_settings( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_tune_settings* fe_tune_settings) ++{ ++ deb_info(" %s : Do Nothing\n", __FUNCTION__); ++ fe_tune_settings->min_delay_ms = 1000; ++ return 0; ++} ++ ++ ++static int ++rtl2832_ts_bus_ctrl( ++ struct dvb_frontend* fe, ++ int acquire) ++{ ++ deb_info(" %s : Do Nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++ ++ ++ ++static struct dvb_frontend_ops rtl2832_dvbt_ops; ++static struct dvb_frontend_ops rtl2840_dvbc_ops; ++static struct dvb_frontend_ops rtl2836_dtmb_ops; ++ ++ ++struct dvb_frontend* rtl2832u_fe_attach(struct dvb_usb_device *d) ++{ ++ ++ struct rtl2832_state *p_state= NULL; ++ //char tmp_set_tuner_power_gpio4; ++ ++ deb_info("+%s : chialing 0409-1\n", __FUNCTION__); ++ ++ //3 linux fe_attach necessary setting ++ /*allocate memory for the internal state */ ++ p_state = kzalloc(sizeof(struct rtl2832_state), GFP_KERNEL); ++ if (p_state == NULL) goto error; ++ memset(p_state,0,sizeof(*p_state)); ++ ++ p_state->is_mt2266_nim_module_built = 0; //initialize is_mt2266_nim_module_built ++ p_state->is_mt2063_nim_module_built = 0; //initialize is_mt2063_nim_module_built ++ ++ p_state->is_initial = 0; //initialize is_initial ++ p_state->is_frequency_valid = 0; ++ p_state->d = d; ++ ++ p_state->b_rtl2840_power_onoff_once = 0; ++ ++ if( usb_init_setting(p_state) ) goto error; ++ ++ if( gpio3_out_setting(p_state) ) goto error; //3Set GPIO3 OUT ++ ++ if( demod_ctl1_setting(p_state , 1) ) goto error; //3 DEMOD_CTL1, resume = 1 ++ ++ //if( set_demod_power(p_state , 1) ) goto error; //3 turn ON demod power ++ ++ if( suspend_latch_setting(p_state , 1) ) goto error; //3 suspend_latch_en = 0, resume = 1 ++ ++ if( demod_ctl_setting(p_state , 1, 1) ) goto error; //3 DEMOD_CTL, resume =1; ADC on ++ ++ //3 Auto detect Tuner Power Pin (GPIO3 or GPIO4) ++ if( set_tuner_power(p_state , 1 , 1) ) goto error; //3 turn ON tuner power, 1st try GPIO4 ++ ++ if( check_tuner_type(p_state) ) goto error; ++ //{ ++ //if(p_state->tuner_type == RTL2832_TUNER_TYPE_UNKNOWN) ++ //{ ++ //if( set_tuner_power(p_state , 1 , 0) ) goto error; //3recover GPIO4 setting at 1st try ++ //if( set_tuner_power(p_state , 0 , 1) ) goto error; //3 2nd try GPIO3 ++ //if( check_tuner_type(p_state) ) goto error; ++ ++ //tmp_set_tuner_power_gpio4 = 0; //4 Tuner Power Pin : GPIO3 ++ //} ++ //else ++ //{ ++ // goto error; ++ //} ++ //} ++ //else ++ //{ ++ // tmp_set_tuner_power_gpio4 = 1;//4 Tuner Power Pin : GPIO4 ++ //} ++ ++ //3 Check if support RTL2836 DTMB. ++ p_state->demod_support_type = 0; ++ check_dtmb_support(p_state); //2836 is off in the end of check_dtmb_support() ++ check_dvbc_support(p_state); ++ ++ //3Set demod_type. ++ p_state->demod_ask_type = demod_default_type; ++ if((p_state->demod_ask_type == RTL2836) && (p_state->demod_support_type & SUPPORT_DTMB_MODE)) ++ { ++ p_state->demod_type = RTL2836; ++ } ++ else if((p_state->demod_ask_type == RTL2840) && (p_state->demod_support_type & SUPPORT_DVBC_MODE)) ++ { ++ p_state->demod_type = RTL2840; ++ } ++ else ++ { ++ p_state->demod_type = RTL2832; ++ } ++ deb_info("demod_type is %d\n", p_state->demod_type); ++ ++ //3 Build Nim Module ++ build_nim_module(p_state); ++ ++ /* setup the state */ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ memcpy(&p_state->frontend.ops, &rtl2832_dvbt_ops, sizeof(struct dvb_frontend_ops)); ++ memset(&p_state->fep, 0, sizeof(struct dvb_frontend_parameters)); ++ ++ break; ++ case RTL2836: ++ memcpy(&p_state->frontend.ops, &rtl2836_dtmb_ops, sizeof(struct dvb_frontend_ops)); ++ memset(&p_state->fep, 0, sizeof(struct dvb_frontend_parameters)); ++ break; ++ ++ case RTL2840: ++ memcpy(&p_state->frontend.ops, &rtl2840_dvbc_ops, sizeof(struct dvb_frontend_ops)); ++ memset(&p_state->fep, 0, sizeof(struct dvb_frontend_parameters)); ++ break; ++ } ++ ++ ++ /* create dvb_frontend */ ++ p_state->frontend.demodulator_priv = p_state; ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ INIT_DELAYED_WORK(&(p_state->update2836_procedure_work), rtl2836_update_function); ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ INIT_DELAYED_WORK(&(p_state->update2832_procedure_work), rtl2832_update_functions); ++#endif ++ mutex_init(&p_state->i2c_repeater_mutex); ++ ++ deb_info("-%s\n", __FUNCTION__); ++ return &p_state->frontend; ++ ++error: ++ return NULL; ++ ++ ++} ++ ++ ++ ++static struct dvb_frontend_ops rtl2840_dvbc_ops = { ++ .info = { ++ .name = "Realtek DVB-C RTL2840 ", ++ .type = FE_QAM, ++ .frequency_min = 50000000, ++ .frequency_max = 862000000, ++ .frequency_stepsize = 166667, ++ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | ++ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | ++ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ ++ .init = rtl2832_init, ++ .release = rtl2832_release, ++ ++ .sleep = rtl2832_sleep, ++ ++ .set_frontend = rtl2840_set_parameters, ++ .get_frontend = rtl2832_get_parameters, ++ .get_tune_settings = rtl2832_get_tune_settings, ++ ++ .read_status = rtl2832_read_status, ++ .read_ber = rtl2832_read_ber, ++ .read_signal_strength = rtl2832_read_signal_strength, ++ .read_snr = rtl2832_read_snr, ++ .read_ucblocks = rtl2832_read_signal_quality, ++ .ts_bus_ctrl = rtl2832_ts_bus_ctrl, ++}; ++ ++ ++ ++ ++static struct dvb_frontend_ops rtl2832_dvbt_ops = { ++ .info = { ++ .name = "Realtek DVB-T RTL2832", ++ .type = FE_OFDM, ++ .frequency_min = 50000000, ++ .frequency_max = 862000000, ++ .frequency_stepsize = 166667, ++ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | ++ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | ++ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ ++ .init = rtl2832_init, ++ .release = rtl2832_release, ++ ++ .sleep = rtl2832_sleep, ++ ++ .set_frontend = rtl2832_set_parameters, ++ .get_frontend = rtl2832_get_parameters, ++ .get_tune_settings = rtl2832_get_tune_settings, ++ ++ .read_status = rtl2832_read_status, ++ .read_ber = rtl2832_read_ber, ++ .read_signal_strength = rtl2832_read_signal_strength, ++ .read_snr = rtl2832_read_snr, ++ .read_ucblocks = rtl2832_read_signal_quality, ++ .ts_bus_ctrl = rtl2832_ts_bus_ctrl, ++}; ++ ++static struct dvb_frontend_ops rtl2836_dtmb_ops = { ++ .info = { ++ .name = "Realtek DTMB RTL2836", ++ .type = FE_OFDM, ++ .frequency_min = 50000000, ++ .frequency_max = 862000000, ++ .frequency_stepsize = 166667, ++ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | ++ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | ++ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ ++ .init = rtl2832_init, ++ .release = rtl2832_release, ++ ++ .sleep = rtl2832_sleep, ++ ++ .set_frontend = rtl2832_set_parameters, ++ .get_frontend = rtl2832_get_parameters, ++ .get_tune_settings = rtl2832_get_tune_settings, ++ ++ .read_status = rtl2832_read_status, ++ .read_ber = rtl2832_read_ber, ++ .read_signal_strength = rtl2832_read_signal_strength, ++ .read_snr = rtl2832_read_snr, ++ .read_ucblocks = rtl2832_read_signal_quality, ++ .ts_bus_ctrl = rtl2832_ts_bus_ctrl, ++}; ++ ++ ++ ++/* DTMB related */ ++ ++static int ++check_dtmb_support( ++ struct rtl2832_state* p_state) ++{ ++ ++ int status; ++ unsigned char buf[LEN_2_BYTE]; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ set_demod_2836_power(p_state, 1); //on ++ ++ status = read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_5, 0x10, buf, LEN_2_BYTE); ++ ++ if(!status && ( buf[0]==0x04 ) && ( buf[1]==0x00 )) ++ { ++ p_state->demod_support_type |= SUPPORT_DTMB_MODE; ++ deb_info(" -%s RTL2836 on broad.....\n", __FUNCTION__); ++ } ++ else ++ { ++ p_state->demod_support_type &= (~SUPPORT_DTMB_MODE); ++ deb_info(" -%s RTL2836 NOT FOUND.....\n", __FUNCTION__); ++ } ++ ++ set_demod_2836_power(p_state, 0); //off ++ ++ //3 Always support DVBT ++ p_state->demod_support_type |= SUPPORT_DVBT_MODE; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++} ++ ++ ++ ++/* DVB-C related */ ++ ++static int ++check_dvbc_support( ++ struct rtl2832_state* p_state) ++{ ++ ++ int status; ++ unsigned char buf; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ set_demod_2840_power(p_state, 1); ++ ++ status = read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ ++ if(!status) ++ { ++ p_state->demod_support_type |= SUPPORT_DVBC_MODE; ++ deb_info(" -%s RTL2840 on broad.....\n", __FUNCTION__); ++ } ++ else ++ { ++ p_state->demod_support_type &= (~SUPPORT_DVBC_MODE); ++ deb_info(" -%s RTL2840 NOT FOUND.....\n", __FUNCTION__); ++ } ++ ++ set_demod_2840_power(p_state, 0); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++} ++ ++ ++ ++static int ++set_demod_2836_power( ++ struct rtl2832_state* p_state, ++ int onoff) ++{ ++ ++ int data; ++ unsigned char datachar; ++ ++ deb_info(" +%s onoff = %d\n", __FUNCTION__, onoff); ++ ++ //2 First RTL2836 Power ON ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 a. Set GPIO 0 LOW ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data &= ~(BIT0); // set GPIO0 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ ++ //3 b. Set GPIO 5 LOW ++ if( gpio5_output_enable_direction(p_state)) goto error; ++ ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data &= ~(BIT5); // set GPIO5 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data) ) goto error; ++ } ++ ++ if(onoff) ++ { ++ //3 2. RTL2836 AGC = 1 ++ if ( read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ datachar |=BIT_2_MASK; ++ datachar &=(~BIT_3_MASK); ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ } ++ else ++ { ++ ++ //3 2. RTL2836 AGC = 0 ++ ++ if ( read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ datachar &=(~BIT_2_MASK); ++ datachar &=(~BIT_3_MASK); ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ ++ ++ //3 3. RTL2836 Power OFF ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 4.a. Set GPIO 0 HIGH ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data |= BIT0; // set GPIO0 high ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ ++ //3 4.b. Set GPIO 5 HIGH ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data |= BIT5; // set GPIO5 high ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ } ++ ++ ++ deb_info(" -%s onoff = %d\n", __FUNCTION__, onoff); ++ return 0; ++ ++error: ++ deb_info(" -%s onoff = %d fail\n", __FUNCTION__, onoff); ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++ ++static int ++rtl2840_on_hwreset( ++ struct rtl2832_state* p_state) ++{ ++ unsigned char buf; ++ int data; ++ int time = 0; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT0; // set GPIO0 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ platform_wait(25); //wait 25ms ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ platform_wait(25); //wait 25ms ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT0); // set GPIO0 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ platform_wait(25); //wait 25ms ++ ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x01, &buf, LEN_1_BYTE); ++ ++ while( (buf!=0xa3) && (time<2) ) ++ { ++ ++ // Set GPIO 6 HIGH ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ // Set GPIO 0 HIGH ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT0; // set GPIO0 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ // Set GPIO 6 LOW ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ // Set GPIO 0 LOW ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT0); // set GPIO0 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x01, &buf, LEN_1_BYTE); ++ deb_info(" +%s Page 0, addr 0x01 = 0x%x\n", __FUNCTION__, buf); ++ time++; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++} ++ ++ ++ ++static int ++set_demod_2840_power( ++ struct rtl2832_state* p_state, ++ int onoff) ++{ ++ unsigned char buf; ++ int data; ++ ++ deb_info(" +%s onoff = %d\n", __FUNCTION__, onoff); ++ ++ //3 1.a RTL2840 Power ON Set GPIO 0 LOW ++ if(p_state->b_rtl2840_power_onoff_once) ++ { ++ //3 a. Set GPIO 0 LOW ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data &= ~(BIT0); // set GPIO0 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ ++ platform_wait(50); //wait 50ms ++ } ++ else ++ { ++ rtl2840_on_hwreset(p_state); ++ p_state->b_rtl2840_power_onoff_once = 1; ++ } ++ ++ if(onoff) ++ { ++ //3 2.a RTL2840 AGC = 1 ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ buf &= (~BIT_6_MASK); ++ buf |= BIT_7_MASK; ++ write_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ } ++ else ++ { ++ ++ //3 2.b RTL2840 AGC = 0 ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ buf &= (~BIT_6_MASK); ++ buf &= (~BIT_7_MASK); ++ write_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ ++ //3 3.a RTL2840 Power OFF Set GPIO 0 HIGH ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data |=BIT0; // set GPIO0 HIGH ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ ++ deb_info(" -%s onoff = %d\n", __FUNCTION__, onoff); ++ ++ return 0; ++error: ++ deb_info(" - XXX %s onoff = %d\n", __FUNCTION__, onoff); ++ return 1; ++} ++ ++ ++ ++static int ++demod_init_setting( ++ struct rtl2832_state * p_state ++ ) ++{ ++ ++ unsigned char data; ++ unsigned char buf[LEN_2_BYTE]; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ { ++ deb_info("%s for RTL2832\n", __FUNCTION__); ++ //3 1. Set IF_AGC Internal IF_AGC_MAN 0x0c ++ if(read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x0c, &data, LEN_1_BYTE)) goto error; ++ data &= (~BIT6); ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x0c, &data, LEN_1_BYTE)) goto error; ++ ++ ++ /*if(!context->DAB_AP_running) ++ { ++ //3 2. Set PID filter to reject null packet(pid = 0x1fff) ++ context->pid_filter_mode = REJECT_MODE; ++ ULONG reject_pid[1] = {0x1fff}; ++ Status = PidFilterToRejectMode(context, reject_pid, 1); ++ if(!NT_SUCCESS(Status)) goto error; ++ }*/ ++ ++ } ++ break; ++ ++ case RTL2836: ++ case RTL2840: ++ { ++ ++ deb_info("%s RTL2832P for RTL2836 and RTL2840 \n", __FUNCTION__); ++ //3 1. Set IF_AGC Manual and Set IF_AGC MAX VAL ++ buf[0]=0x5F; ++ buf[1]=0xFF; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x0c, buf, LEN_2_BYTE)) goto error; ++ ++ //3 2. PIP Setting ++ data = 0xe8; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x21, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x60; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x61, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x18; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0xbc, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x62, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x63, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x64, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x65, &data, LEN_1_BYTE)) goto error; ++ ++ //3 +PIP filter Reject = 0x1FFF ++ data = 0x01; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x22, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x1f; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x26, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xff; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x27, &data, LEN_1_BYTE)) goto error; ++ //3 -PIP filter Reject = 0x1FFF ++ ++ data = 0x7f; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x92, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xf7; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x93, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xff; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x94, &data, LEN_1_BYTE)) goto error; ++ } ++ break; ++ } ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++ ++error: ++ deb_info(" -%s error \n", __FUNCTION__); ++ return 1; ++ ++} ++ ++ ++static int ++rtl2836_scan_procedure( ++ struct rtl2832_state * p_state) ++{ ++ unsigned char val; ++ int wait_num = 0; ++ unsigned long Per1, Per2; ++ long Data1,Data2,Snr; ++ DTMB_DEMOD_MODULE *pDtmbDemod; ++ struct dvb_usb_device* dev; ++ ++ ++ pDtmbDemod = p_state->pNim2836->pDemod; ++ dev = p_state->d; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ //3 Check signal present ++ wait_num = 0; ++ msleep(50); // Wait 0.05s ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_6, 0x53, &val, LEN_1_BYTE)) goto error; ++ deb_info("%s Signel Present = 0x %x\n", __FUNCTION__, val); ++ while((wait_num<3)&& (!(val&BIT_0_MASK))) ++ { ++ msleep(50); // Wait 0.05s ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_6, 0x53, &val, LEN_1_BYTE)) goto error; ++ deb_info("%s Signel Present = 0x %x\n", __FUNCTION__, val); ++ wait_num++; ++ } ++ ++ if(val&BIT_0_MASK) ++ { ++ //3 Write signal present ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val |= BIT_0_MASK; //set Reg_present ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ ++ //3+ RTL2836 Release Stage=9 ++ val = 0x49; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4d, &val, LEN_1_BYTE)) goto error; ++ val = 0x29; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4e, &val, LEN_1_BYTE)) goto error; ++ val = 0x95; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4f, &val, LEN_1_BYTE)) goto error; ++ //3 -RTL2836 Release Stage=9 ++ deb_info("%s RTL2836 Release Stage 9\n", __FUNCTION__); ++ ++ ++ //3 Check signal lock ++ pDtmbDemod->GetPer(pDtmbDemod, &Per1, &Per2); ++ deb_info("%s --***GetPer = %d***\n", __FUNCTION__, (int)Per1); ++ ++ pDtmbDemod->GetSnrDb(pDtmbDemod, &Data1, &Data2); ++ Snr = Data1>>2; ++ deb_info("%s --***SNR= %d***\n", __FUNCTION__, (int)Snr); ++ ++ wait_num = 0; ++ while(wait_num<30 ) ++ { ++ if((Per1<1) && (Snr>0) && (Snr<40) ) ++ { ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val |= BIT_1_MASK; //set Reg_signal ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ ++ deb_info("%s Signal Lock................\n", __FUNCTION__); ++ break; ++ } ++ ++ msleep(100); // Wait 0.1s ++ pDtmbDemod->GetPer(pDtmbDemod,&Per1,&Per2); ++ deb_info("%s --***GetPer = %d***\n", __FUNCTION__, (int)Per1); ++ ++ pDtmbDemod->GetSnrDb(pDtmbDemod,&Data1,&Data2); ++ Snr = Data1>>2; ++ deb_info("%s --***SNR= %d***\n", __FUNCTION__, (int)Snr); ++ wait_num++; ++ } ++ ++ if(! ((Per1<1) && (Snr>0) && (Snr<40))) ++ { ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val &=(~BIT_1_MASK); //reset Reg_lock ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ } ++ } ++ else ++ { ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val &=(~BIT_0_MASK); //reset Reg_present ++ val &=(~BIT_1_MASK); //reset Reg_lock ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ ++ //3 + RTL2836 Release Stage=9 ++ val = 0x49; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4d, &val, LEN_1_BYTE)) goto error; ++ val = 0x29; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4e, &val, LEN_1_BYTE)) goto error; ++ val = 0x95; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4f, &val, LEN_1_BYTE)) goto error; ++ //3 -RTL2836 Release Stage=9 ++ ++ deb_info("%s RTL2836 Release Stage 9\n", __FUNCTION__); ++ } ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++error: ++ ++ deb_info(" +%s error\n", __FUNCTION__); ++ return -1; ++} ++ ++ ++static int ++build_2832_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ ++ MT2266_EXTRA_MODULE *p_mt2266_extra; ++ MT2063_EXTRA_MODULE *p_mt2063_extra; ++ TUNER_MODULE *pTuner; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ //3 Buile 2832 nim module ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MT2266) ++ { ++ //3 Build RTL2832 MT2266 NIM module. ++ ++ BuildRtl2832Mt2266Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2 ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ MT2266_TUNER_ADDR // The MT2266 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ ++ ++ // Get MT2266 tuner extra module. ++ pTuner = p_state->pNim->pTuner; ++ p_mt2266_extra = &(pTuner->Extra.Mt2266); ++ ++ // Open MT2266 handle. ++ if(p_mt2266_extra->OpenHandle(pTuner)) ++ deb_info("%s : MT2266 Open Handle Failed....\n", __FUNCTION__); ++ ++ p_state->is_mt2266_nim_module_built = 1; ++ ++ deb_info(" %s BuildRtl2832Mt2266Module\n", __FUNCTION__); ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ ++ //3Build RTL2832 FC2580 NIM module. ++ BuildRtl2832Fc2580Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 9. ++ 2, // Maximum I2C writing byte number is 8. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ FC2580_TUNER_ADDR, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is external AGC mode. ++ ); ++ deb_info(" %s BuildRtl2832Fc2580Module\n", __FUNCTION__); ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_TUA9001) ++ { ++ ++ //3Build RTL2832 TUA9001 NIM module. ++ BuildRtl2832Tua9001Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ NULL, // Employ CustomI2cRead() as basic I2C reading function. ++ NULL, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 50 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ TUA9001_TUNER_ADDR // The TUA9001 I2C device address is 0xc0 in 8-bit format. ++ ); ++ deb_info(" %s BuildRtl2832Tua9001Module\n", __FUNCTION__); ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ ++ //3Build RTL2832 MXL5007 NIM module. ++ BuildRtl2832Mxl5007tModule( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function.. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ MXL5007T_BASE_ADDRESS, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ deb_info(" %s BuildRtl2832Mxl5007tModule\n", __FUNCTION__); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ //3Build RTL2832 FC0012 NIM module. ++ BuildRtl2832Fc0012Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ FC0012_BASE_ADDRESS, // The FC0012 I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ // The FC0012 crystal frequency is 36.0 MHz. ++ ); ++ deb_info(" %s BuildRtl2832Fc0012Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ //3 Build RTL2832 E4000 NIM module ++ BuildRtl2832E4000Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 50 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ E4000_BASE_ADDRESS, // The E4000 I2C device address is 0xc8 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ // The E4000 crystal frequency is 28.8 MHz. ++ ); ++ deb_info(" %s BuildRtl2832E4000Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MT2063) ++ { ++ ++ // Build RTL2832 MT2063 NIM module. ++ BuildRtl2832Mt2063Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2832 and MT2063 IF frequency is 36.125 MHz. ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARRLLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ MT2063_TUNER_ADDR // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTuner = p_state->pNim->pTuner; ++ p_mt2063_extra = &(pTuner->Extra.Mt2063); ++ ++ // Open MT2063 handle. ++ if(p_mt2063_extra->OpenHandle(pTuner)) ++ deb_info("%s : MT2063 Open Handle Failed....\n", __FUNCTION__); ++ ++ p_state->is_mt2063_nim_module_built = 1; ++ ++ deb_info(" %s BuildRtl2832Mt2063Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MAX3543) ++ { ++ ++ // Build RTL2832 MAX3543 NIM module. ++ BuildRtl2832Max3543Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ MAX3543_TUNER_ADDR, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ ++ deb_info(" %s BuildRtl2832Max3543Module\n", __FUNCTION__); ++ ++ } ++ else ++ { ++ deb_info(" -%s : RTL 2832 Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ //Set user defined data pointer of base interface structure for custom basic functions. ++ p_state->pNim->pBaseInterface->SetUserDefinedDataPointer(p_state->pNim->pBaseInterface, p_state->d ); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++ ++static int ++build_2836_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ //3Build RTL2836 FC2580 NIM module. ++ BuildRtl2836Fc2580Module( ++ &p_state->pNim2836, ++ &p_state->DtmbNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2836_DEMOD_ADDR, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ FC2580_TUNER_ADDR, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is internal AGC mode. ++ ); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 Build RTL2836 MXL5007T NIM module ++ BuildRtl2836Mxl5007tModule( ++ &p_state->pNim2836, ++ &p_state->DtmbNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2836_DEMOD_ADDR, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ MXL5007T_BASE_ADDRESS, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ } ++ else ++ { ++ deb_info(" -%s : RTL2836 Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ ++ //Set user defined data pointer of base interface structure for custom basic functions. ++ p_state->pNim2836->pBaseInterface->SetUserDefinedDataPointer(p_state->pNim2836->pBaseInterface, p_state->d ); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++static int ++build_2840_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ ++ MT2063_EXTRA_MODULE *p_mt2063_extra; ++ TUNER_MODULE *pTuner; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MT2063) ++ { ++ ++ BuildRtl2840Mt2063Module( ++ &p_state->pNim2840, ++ &p_state->QamNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2840 and MT2063 IF frequency is 36.125 MHz. ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2840_DEMOD_ADDR, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ MT2063_TUNER_ADDR // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ // Get MT2063 tuner extra module. ++ pTuner = p_state->pNim2840->pTuner; ++ p_mt2063_extra = &(pTuner->Extra.Mt2063); ++ ++ if(p_mt2063_extra->OpenHandle(pTuner)) ++ deb_info("%s : MT2063 Open Handle Failed....\n", __FUNCTION__); ++ ++ p_state->is_mt2063_nim_module_built = 1; ++ ++ deb_info(" %s BuildRtl2840Mt2063Module\n", __FUNCTION__); ++ } ++ else if ( p_state->tuner_type == RTL2832_TUNER_TYPE_MAX3543) ++ { ++ // Build RTL2840 MAX3543 NIM module. ++ BuildRtl2840Max3543Module( ++ &p_state->pNim2840, ++ &p_state->QamNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2840_DEMOD_ADDR, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ MAX3543_TUNER_ADDR, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ deb_info(" %s BuildRtl2840Max3543Module\n", __FUNCTION__); ++ } ++ else ++ { ++ deb_info(" -%s : RTL2840 Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ ++ //Set user defined data pointer of base interface structure for custom basic functions. ++ p_state->pNim2840->pBaseInterface->SetUserDefinedDataPointer(p_state->pNim2840->pBaseInterface, p_state->d ); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++static int ++build_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ // Build 2832 nim module ++ build_2832_nim_module(p_state); ++ break; ++ ++ case RTL2836: ++ // Build 2836 nim module ++ build_2832_nim_module(p_state); ++ build_2836_nim_module(p_state); ++ break; ++ ++ case RTL2840: ++ //Build 2840 nim module ++ build_2832_nim_module(p_state); ++ build_2840_nim_module(p_state); ++ break; ++ } ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++} ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u_fe.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u_fe.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u_fe.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u_fe.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,364 @@ ++ ++#ifndef __RTL2832U_FE_H__ ++#define __RTL2832U_FE_H__ ++ ++#include "nim_rtl2832_tua9001.h" ++#include "nim_rtl2832_mt2266.h" ++#include "nim_rtl2832_fc2580.h" ++#include "nim_rtl2832_mxl5007t.h" ++#include "nim_rtl2832_fc0012.h" ++#include "nim_rtl2832_e4000.h" ++#include "nim_rtl2832_mt2063.h" ++#include "nim_rtl2832_max3543.h" ++ ++ ++#include "nim_rtl2836_fc2580.h" ++#include "nim_rtl2836_mxl5007t.h" ++ ++#include "nim_rtl2840_mt2063.h" ++#include "nim_rtl2840_max3543.h" ++ ++#include "rtl2832u_io.h" ++#include ++ ++#define UPDATE_FUNC_ENABLE_2840 0 ++#define UPDATE_FUNC_ENABLE_2836 1 ++#define UPDATE_FUNC_ENABLE_2832 1 ++ ++#define UPDATE_PROCEDURE_PERIOD_2836 (HZ/5) //200ms = jiffies*1000/HZ ++#define UPDATE_PROCEDURE_PERIOD_2832 (HZ/5) //200ms ++ ++typedef enum{ ++ RTL2832_TUNER_TYPE_MT2266 = 0, ++ RTL2832_TUNER_TYPE_FC2580, ++ RTL2832_TUNER_TYPE_TUA9001, ++ RTL2832_TUNER_TYPE_MXL5007T, ++ RTL2832_TUNER_TYPE_FC0012, ++ RTL2832_TUNER_TYPE_E4000, ++ RTL2832_TUNER_TYPE_MT2063, ++ RTL2832_TUNER_TYPE_MAX3543, ++ RTL2832_TUNER_TYPE_UNKNOWN, ++}RTL2832_TUNER_TYPE; ++ ++ ++//3 state of total device ++struct rtl2832_state { ++ struct dvb_frontend frontend; ++ struct dvb_frontend_parameters fep; ++ struct dvb_usb_device* d; ++ ++ struct mutex i2c_repeater_mutex; ++ ++ unsigned long current_frequency; ++ enum fe_bandwidth current_bandwidth; ++ ++ RTL2832_TUNER_TYPE tuner_type; ++ unsigned char is_mt2266_nim_module_built; //3 For close MT handle ++ unsigned char is_mt2063_nim_module_built; //3 For close MT handle ++ ++ ++ //3 DTMB related begin --- ++ unsigned int demod_support_type; ++ unsigned int demod_type; ++ unsigned int demod_ask_type; ++ //3 DTMB related end end --- ++ ++ ++ //3 DVBC related begin --- ++ unsigned char b_rtl2840_power_onoff_once; ++ ++ //3 DVBC related end end --- ++ ++ ++ //3if init() is called, is_initial is true ->check it to see if need to flush work queue ++ unsigned short is_initial; ++ unsigned char is_frequency_valid; ++ ++#if UPDATE_FUNC_ENABLE_2840 ++ struct delayed_work update2840_procedure_work; ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ struct delayed_work update2836_procedure_work; ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ struct delayed_work update2832_procedure_work; ++#endif ++ ++ DVBT_NIM_MODULE* pNim;//Nim of 2832 ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ RTL2832_EXTRA_MODULE Rtl2832ExtraModuleMemory; ++ MT2266_EXTRA_MODULE Mt2266ExtraModuleMemory; ++ FC2580_EXTRA_MODULE Fc2580ExtraModuleMemory; ++ TUA9001_EXTRA_MODULE TUA9001ExtraModuleMemory; ++ MXL5007T_EXTRA_MODULE MXL5007TExtraModuleMemory; ++ FC0012_EXTRA_MODULE FC0012ExtraModuleMemory; ++ E4000_EXTRA_MODULE E4000ExtraModuleMemory; ++ RTL2832_MT2266_EXTRA_MODULE Rtl2832Mt2266ExtraModuleMemory; ++ RTL2832_FC0012_EXTRA_MODULE Rtl2832FC0012ExtraModuleMemory; ++ RTL2832_E4000_EXTRA_MODULE Rtl2832E4000ExtraModuleMemory; ++ RTL2832_MT2063_EXTRA_MODULE Rtl2832Mt2063ExtraModuleMemory; ++ ++ ++ //3 DTMB related begin --- ++ DTMB_NIM_MODULE* pNim2836;//Nim of 2836 ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ RTL2836_EXTRA_MODULE Rtl2836ExtraModuleMemory; ++ //MXL5007T_EXTRA_MODULE MXL5007TExtraModuleMemoryFor2836; ++ //FC2580_EXTRA_MODULE Fc2580ExtraModuleMemory, ++ //3DTMB related end --- ++ ++ //3 DVBC related begin --- ++ QAM_NIM_MODULE* pNim2840;//Nim of 2840 ++ QAM_NIM_MODULE QamNimModuleMemory; ++ MAX3543_EXTRA_MODULE Max3543ExtraModuleMemory; ++ ++ MT2063_EXTRA_MODULE Mt2063ExtraModuleMemory; ++ ++ RTL2840_MT2063_EXTRA_MODULE Rtl2840Mt2063ExtraModuleMemory; ++ ++ //RTL2840_EXTRA_MODULE Rtl2840ExtraModuleMemory; ++ //MXL5007T_EXTRA_MODULE MXL5007TExtraModuleMemoryFor2836; ++ //FC2580_EXTRA_MODULE Fc2580ExtraModuleMemory, ++ ++ //3DVBC related end --- ++ ++}; ++ ++ ++ ++ ++#define MT2266_TUNER_ADDR 0xc0 ++#define FC2580_TUNER_ADDR 0xac ++#define TUA9001_TUNER_ADDR 0xc0 ++ ++#define MT2266_OFFSET 0x00 ++#define MT2266_CHECK_VAL 0x85 ++ ++#define FC2580_OFFSET 0x01 ++#define FC2580_CHECK_VAL 0x56 ++ ++#define TUA9001_OFFSET 0x7e ++#define TUA9001_CHECK_VAL 0x2328 ++ ++#define MXL5007T_BASE_ADDRESS 0xc0 ++#define MXL5007T_CHECK_ADDRESS 0xD9 ++#define MXL5007T_CHECK_VALUE 0x14 ++ ++#define FC0012_BASE_ADDRESS 0xc6 ++#define FC0012_CHECK_ADDRESS 0x00 ++#define FC0012_CHECK_VALUE 0xa1 ++ ++#define E4000_BASE_ADDRESS 0xc8 ++#define E4000_CHECK_ADDRESS 0x02 ++#define E4000_CHECK_VALUE 0x40 ++ ++ ++#define MT2063_TUNER_ADDR 0xc0 ++#define MT2063_CHECK_OFFSET 0x00 ++#define MT2063_CHECK_VALUE 0x9e ++#define MT2063_CHECK_VALUE_2 0x9c ++ ++ ++#define MAX3543_TUNER_ADDR 0xc0 ++#define MAX3543_CHECK_OFFSET 0x00 ++#define MAX3543_CHECK_VALUE 0x38 ++#define MAX3543_SHUTDOWN_OFFSET 0x08 ++ ++ ++ ++ ++ ++struct rtl2832_reg_addr{ ++ RegType reg_type; ++ unsigned short reg_addr; ++ int bit_low; ++ int bit_high; ++}; ++ ++ ++ ++typedef enum{ ++ RTD2831_RMAP_INDEX_USB_CTRL_BIT5 =0, ++ RTD2831_RMAP_INDEX_USB_STAT, ++ RTD2831_RMAP_INDEX_USB_EPA_CTL, ++ RTD2831_RMAP_INDEX_USB_SYSCTL, ++ RTD2831_RMAP_INDEX_USB_EPA_CFG, ++ RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, ++ RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, ++ ++ RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3, ++ RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67, ++ RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT5, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT5, ++#if 0 ++ RTD2831_RMAP_INDEX_SYS_GPD, ++ RTD2831_RMAP_INDEX_SYS_GPOE, ++ RTD2831_RMAP_INDEX_SYS_GPO, ++ RTD2831_RMAP_INDEX_SYS_SYS_0, ++#endif ++ ++} rtl2832_reg_map_index; ++ ++ ++ ++#define USB_SYSCTL 0x0000 ++#define USB_CTRL 0x0010 ++#define USB_STAT 0x0014 ++#define USB_EPA_CTL 0x0148 ++#define USB_EPA_CFG 0x0144 ++#define USB_EPA_MAXPKT 0x0158 ++#define USB_EPA_FIFO_CFG 0x0160 ++ ++#define DEMOD_CTL 0x0000 ++#define GPIO_OUTPUT_VAL 0x0001 ++#define GPIO_OUTPUT_EN 0x0003 ++#define GPIO_DIR 0x0004 ++#define GPIO_CFG0 0x0007 ++#define GPIO_CFG1 0x0008 ++#define DEMOD_CTL1 0x000b ++ ++ ++static int rtl2832_reg_mask[32]= { ++ 0x00000001, ++ 0x00000003, ++ 0x00000007, ++ 0x0000000f, ++ 0x0000001f, ++ 0x0000003f, ++ 0x0000007f, ++ 0x000000ff, ++ 0x000001ff, ++ 0x000003ff, ++ 0x000007ff, ++ 0x00000fff, ++ 0x00001fff, ++ 0x00003fff, ++ 0x00007fff, ++ 0x0000ffff, ++ 0x0001ffff, ++ 0x0003ffff, ++ 0x0007ffff, ++ 0x000fffff, ++ 0x001fffff, ++ 0x003fffff, ++ 0x007fffff, ++ 0x00ffffff, ++ 0x01ffffff, ++ 0x03ffffff, ++ 0x07ffffff, ++ 0x0fffffff, ++ 0x1fffffff, ++ 0x3fffffff, ++ 0x7fffffff, ++ 0xffffffff ++}; ++ ++ ++ ++ ++#define BIT0 0x00000001 ++#define BIT1 0x00000002 ++#define BIT2 0x00000004 ++#define BIT3 0x00000008 ++#define BIT4 0x00000010 ++#define BIT5 0x00000020 ++#define BIT6 0x00000040 ++#define BIT7 0x00000080 ++#define BIT8 0x00000100 ++#define BIT9 0x00000200 ++#define BIT10 0x00000400 ++#define BIT11 0x00000800 ++#define BIT12 0x00001000 ++#define BIT13 0x00002000 ++#define BIT14 0x00004000 ++#define BIT15 0x00008000 ++#define BIT16 0x00010000 ++#define BIT17 0x00020000 ++#define BIT18 0x00040000 ++#define BIT19 0x00080000 ++#define BIT20 0x00100000 ++#define BIT21 0x00200000 ++#define BIT22 0x00400000 ++#define BIT23 0x00800000 ++#define BIT24 0x01000000 ++#define BIT25 0x02000000 ++#define BIT26 0x04000000 ++#define BIT27 0x08000000 ++#define BIT28 0x10000000 ++#define BIT29 0x20000000 ++#define BIT30 0x40000000 ++#define BIT31 0x80000000 ++ ++ ++/* DTMB related ++ ++typedef enum { ++ PAGE_0 = 0, ++ PAGE_1 = 1, ++ PAGE_2 = 2, ++ PAGE_3 = 3, ++ PAGE_4 = 4, ++ PAGE_5 = 5, ++ PAGE_6 = 6, ++ PAGE_7 = 7, ++ PAGE_8 = 8, ++ PAGE_9 = 9, ++};*/ ++ ++ ++#define SUPPORT_DVBT_MODE 0x01 ++#define SUPPORT_DTMB_MODE 0x02 ++#define SUPPORT_DVBC_MODE 0x04 ++ ++ ++typedef enum { ++ RTL2832 = 0, ++ RTL2836, ++ RTL2840 ++}DEMOD_TYPE; ++ ++static int check_dtmb_support(struct rtl2832_state* p_state); ++ ++static int check_dvbc_support(struct rtl2832_state* p_state); ++ ++static int ++set_demod_2836_power( ++ struct rtl2832_state* p_state, ++ int onoff); ++ ++static int ++rtl2840_on_hwreset( ++ struct rtl2832_state* p_state); ++ ++ ++static int ++set_demod_2840_power( ++ struct rtl2832_state* p_state, ++ int onoff); ++ ++ ++static int ++demod_init_setting( ++ struct rtl2832_state * p_state); ++ ++static int ++build_nim_module( ++ struct rtl2832_state* p_state); ++ ++static int ++rtl2836_scan_procedure( ++ struct rtl2832_state * p_state); ++ ++#endif // __RTD2830_PRIV_H__ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u.h 2010-10-27 08:17:30.000000000 +0200 +@@ -0,0 +1,195 @@ ++ ++#ifndef _RTL2832U_H_ ++#define _RTL2832U_H_ ++ ++ ++ ++#include "dvb-usb.h" ++ ++#define USB_VID_REALTEK 0x0BDA ++#define USB_PID_RTD2832U_WARM 0x2832 ++#define USB_PID_RTD2832U_2ND_WARM 0x2838 ++#define USB_PID_RTD2832U_3RD_WARM 0x2834 ++#define USB_PID_RTD2832U_4TH_WARM 0x2837 ++#define USB_PID_RTL2836_WARM 0x2836 ++#define USB_PID_RTL2836_2ND_WARM 0x2839 ++ ++#define USB_VID_GOLDENBRIDGE 0x1680 ++#define USB_PID_GOLDENBRIDGE_WARM 0xA332 ++ ++#define USB_VID_YUAN 0x1164 ++#define USB_PID_YUAN_WARM 0x6601 ++ ++#define USB_VID_AZUREWAVE_2 0x13D3 ++#define USB_PID_AZUREWAVE_MINI_WARM 0x3234 ++#define USB_PID_AZUREWAVE_USB_WARM 0x3274 ++#define USB_PID_AZUREWAVE_GPS_WARM 0x3282 ++ ++#define USB_VID_KWORLD_1ST 0x1B80 ++#define USB_PID_KWORLD_WARM_4 0xD394 ++#define USB_PID_KWORLD_WARM_6 0xD396 ++#define USB_PID_KWORLD_WARM_3 0xD393 ++#define USB_PID_KWORLD_WARM_7 0xD397 ++#define USB_PID_KWORLD_WARM_8 0xD398 ++ ++#define USB_VID_DEXATEK 0x1D19 ++#define USB_PID_DEXATEK_USB_WARM 0x1101 ++#define USB_PID_DEXATEK_MINIUSB_WARM 0x1102 ++#define USB_PID_DEXATEK_5217_WARM 0x1103 ++#define USB_PID_DEXATEK_WARM_4 0x1104 ++ ++#define USB_VID_GTEK 0x1F4D ++#define USB_PID_GTEK_WARM 0x0837 ++#define USB_PID_GTEK_WARM_A 0xA803 ++#define USB_PID_GTEK_WARM_B 0xB803 ++#define USB_PID_GTEK_WARM_C 0xC803 ++#define USB_PID_GTEK_WARM_D 0xD803 ++ ++#define USB_VID_THP 0x1554 ++#define USB_PID_THP 0x5013 ++#define USB_PID_THP2 0x5020 ++ ++#define RTD2831_URB_SIZE 4096// 39480 ++#define RTD2831_URB_NUMBER 10 // 4 ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++// remote control ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++ ++//define rtl283u rc register address ++#define IR_RX_BUF 0xFC00 ++#define IR_RX_IE 0xFD00 ++#define IR_RX_IF 0xFD01 ++#define IR_RX_CTRL 0xFD02 ++#define IR_RX_CONFIG 0xFD03 ++#define IR_MAX_DURATION0 0xFD04 ++#define IR_MAX_DURATION1 0xFD05 ++#define IR_IDLE_LEN0 0xFD06 ++#define IR_IDLE_LEN1 0xFD07 ++#define IR_GLITCH_LEN 0xFD08 ++#define IR_RX_BUFFER_CTRL 0xFD09 ++#define IR_RX_BUFFER_DATA 0xFD0A ++#define IR_RX_BC 0xFD0B ++#define IR_RX_CLK 0xFD0C ++#define IR_RX_C_COUNT_L 0xFD0D ++#define IR_RX_C_COUNT_H 0xFD0E ++ ++#define IR_SUSPEND_CTRL 0xFD10 ++#define IR_Err_Tolerance_CTRL 0xFD11 ++#define IR_UNIT_LEN 0xFD12 ++#define IR_Err_Tolerance_LEN 0xFD13 ++#define IR_MAX_H_Tolerance_LEN 0xFD14 ++#define IR_MAX_L_Tolerance_LEN 0xFD15 ++#define IR_MASK_CTRL 0xFD16 ++#define IR_MASK_DATA 0xFD17 ++#define IR_RESUME_MASK_ADDR 0xFD18 ++#define IR_RESUME_MASK_T_LEN 0xFD19 ++ ++#define USB_CTRL 0x0010 ++#define SYS_GPD 0x0004 ++#define SYS_GPOE 0x0003 ++#define SYS_GPO 0x0001 ++#define RC_USE_DEMOD_CTL1 0x000B ++ ++//define use len ++#define LEN_1 0x01 ++#define LEN_2 0x02 ++#define LEN_3 0x03 ++#define LEN_4 0x04 ++ ++ ++ ++//function ++int rtl2832u_remoto_control_initial_setting(struct dvb_usb_device *d); ++#define USB_EPA_CTL 0x0148 ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++//decode ++#define frt0_para1 0x3c ++#define frt0_para2 0x20 ++#define frt0_para3 0x7f ++#define frt0_para4 0x05 ++#define frt0_BITS_NUM 0x80 ++#define frt0_BITS_mask 0x01 ++#define frt0_BITS_mask0 0x00 ++#define frt0_BITS_mask1 0x00 ++#define frt0_BITS_mask2 0x0f ++#define frt0_BITS_mask3 0xff ++ ++#define frt1_para1 0x12 ++#define frt1_para3 0x1a ++#define frt1_para2 0x7f ++#define frt1_para4 0x80 ++#define frt1_para5 0x01 ++#define frt1_para6 0x02 ++#define frt1_BITS_NUM 0x80 ++#define frt1_para_uc_1 0x81 ++#define frt1_para_uc_2 0x82 ++#define frt1_BITS_mask0 0x00 ++#define frt1_BITS_mask1 0x00 ++#define frt1_BITS_mask2 0x7f ++#define frt1_BITS_mask3 0xff ++ ++#define frt2_para1 0x0a ++#define frt2_para2 0xFF ++#define frt2_para3 0xb0 ++#define frt2_para4 0xc6 ++#define frt2_para5 0x30 ++#define frt2_para6 0x1b ++#define frt2_para7 0x8f ++#define frt2_para8 0x89 ++#define frt2_para9 0x7f ++#define frt2_para10 0x60 ++#define frt2_para11 0x38 ++#define frt2_para12 0x15 ++#define frt2_BITS_NUM 0x80 ++#define frt2_BITS_mask0 0x00 ++#define frt2_BITS_mask1 0x00 ++#define frt2_BITS_mask2 0xff ++#define frt2_BITS_mask3 0xff ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++// remote control ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++enum protocol_type_for_RT{ ++ RT_RC6=0, ++ RT_RC5, ++ RT_NEC, ++ RT_TEST ++}; ++// op define ++enum OP{ ++ OP_NO =0, ++ OP_AND , ++ OP_OR ++}; ++ ++typedef enum RT_UC_CODE_STATE{ ++ WAITING_6T, ++ WAITING_2T_AFTER_6T, ++ WAITING_NORMAL_BITS ++}RT_UC_CODE_STATE; ++ ++//struct define ++typedef struct RT_rc_set_reg_struct{ ++ u8 type; ++ u16 address; ++ u8 data; ++ u8 op; ++ u8 op_mask; ++}RT_rc_set_reg_struct; ++ ++enum RTL2832U_RC_STATE{ ++ RC_NO_SETTING=0, ++ RC_INSTALL_OK, ++ RC__POLLING_OK, ++ RC_STOP_OK ++}; ++//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++extern struct dvb_frontend * rtl2832u_fe_attach(struct dvb_usb_device *d); ++ ++#endif ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u_io.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u_io.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u_io.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u_io.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,913 @@ ++ ++ ++#include "rtl2832u_io.h" ++#include ++ ++#define ERROR_TRY_MAX_NUM 4 ++ ++ ++#define DUMMY_PAGE 0x0a ++#define DUMMY_ADDR 0x01 ++ ++ ++ ++void ++platform_wait( ++ unsigned long nMinDelayTime) ++{ ++ // The unit of Sleep() waiting time is millisecond. ++ unsigned long usec; ++ do { ++ usec = (nMinDelayTime > 8000) ? 8000 : nMinDelayTime; ++ msleep(usec); ++ nMinDelayTime -= usec; ++ } while (nMinDelayTime > 0); ++ ++ return; ++ ++} ++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++// remote control ++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++static int ++read_rc_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ offset, /* USB message value */ ++ 0x0201, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" error try rc read register %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++ ++ ++static int ++write_rc_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ offset, /* USB message value */ ++ 0x0211, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try rc write register = %d, %s: offset=0x%x, error code=0x%x !\n",try_num ,__FUNCTION__, offset, ret); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++error: ++ return 1; ++ } ++ ++ ++int ++read_rc_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4 && byte_num != 0x80) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if (type == RTD2832U_RC ) ++ ret = read_rc_register( dib , byte_addr , buf , byte_num); ++ else ++ { ++ deb_info("error!! %s: erroe register type \n", __FUNCTION__); ++ return 1; ++ } ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++ ++ ++int ++write_rc_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4 && byte_num !=0x80) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if (type == RTD2832U_RC ) ++ ret = write_rc_register( dib , byte_addr , buf , byte_num); ++ else ++ { ++ deb_info("error!! %s: erroe register type \n", __FUNCTION__); ++ ret=1; ++ } ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++static int ++read_usb_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ (USB_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0100, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++ ++ ++static int ++write_usb_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ (USB_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0110, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try = %d, %s: offset=0x%x, error code=0x%x !\n",try_num ,__FUNCTION__, offset, ret); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++error: ++ return 1; ++ } ++ ++ ++ ++ ++static int ++read_sys_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ (SYS_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0200, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret); ++ return 1; ++ } ++ ++ return 0; ++ ++ } ++ ++ ++static int ++write_sys_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ (SYS_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0210, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" error try= %d, %s: offset=0x%x, error code=0x%x !\n",try_num, __FUNCTION__, offset, ret); ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++error: ++ return 1; ++ } ++ ++ ++ ++ ++int ++read_demod_register( ++ struct dvb_usb_device*dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ int i; ++ unsigned char tmp; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ demod_device_addr + (offset<<8), /* USB message value */ ++ (0x0000 + page), /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ ++ usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ RTL2832_DEMOD_ADDR + (DUMMY_ADDR<<8), /* USB message value */ ++ (0x0000 + DUMMY_PAGE), /* USB message index value */ ++ &tmp, /* pointer to the receive buffer */ ++ LEN_1_BYTE, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ ++// deb_info("%s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength,page, offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data[i]); ++// deb_info(")\n"); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error!! %s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength,page, offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ goto error; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++int ++write_demod_register( ++ struct dvb_usb_device*dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char i, try_num; ++ unsigned char tmp; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ demod_device_addr + (offset<<8), /* USB message value */ ++ (0x0010 + page), /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ ++ usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ RTL2832_DEMOD_ADDR + (DUMMY_ADDR<<8), /* USB message value */ ++ (0x0000 + DUMMY_PAGE), /* USB message index value */ ++ &tmp, /* pointer to the receive buffer */ ++ LEN_1_BYTE, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++// deb_info("%s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength, page,offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data[i]); ++// deb_info(")\n"); ++ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try = %d!! %s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(",try_num , __FUNCTION__, ret, demod_device_addr, bytelength,page,offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++ } ++ ++ ++ ++ ++ ++ ++int ++read_rtl2832_tuner_register( ++ struct dvb_usb_device *dib, ++ unsigned char device_address, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ int i; ++ unsigned char data_tmp[128]; ++ ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ device_address+(offset<<8), /* USB message value */ ++ 0x0300, /* USB message index value */ ++ data_tmp, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++// deb_info("%s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength,offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data_tmp[i]); ++// deb_info(")\n"); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error!! %s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength,offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data_tmp[i]); ++ deb_info(")\n"); ++ ++ goto error; ++ } ++ ++ memcpy(data,data_tmp,bytelength); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++ ++} ++ ++int write_rtl2832_tuner_register( ++ struct dvb_usb_device *dib, ++ unsigned char device_address, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char i, try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ device_address+(offset<<8), /* USB message value */ ++ 0x0310, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++// deb_info("%s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength, offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data[i]); ++// deb_info(")\n"); ++ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(",try_num, __FUNCTION__, ret, device_address, bytelength, offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++ } ++ ++ ++ ++ ++int ++read_rtl2832_stdi2c( ++ struct dvb_usb_device* dib, ++ unsigned short dev_i2c_addr, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int i; ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ unsigned char data_tmp[128]; ++ ++ try_num = 0; ++error_write_again: ++ try_num ++; ++ ++ ++ if(bytelength >= 128) ++ { ++ deb_info("%s error bytelength >=128 \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ dev_i2c_addr, /* USB message value */ ++ 0x0600, /* USB message index value */ ++ data_tmp, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, data=(",try_num, __FUNCTION__, ret, dev_i2c_addr, bytelength); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data_tmp[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ memcpy(data,data_tmp,bytelength); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++ ++int ++write_rtl2832_stdi2c( ++ struct dvb_usb_device* dib, ++ unsigned short dev_i2c_addr, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int i; ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num ++; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ dev_i2c_addr, /* USB message value */ ++ 0x0610, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, data=(",try_num, __FUNCTION__, ret, dev_i2c_addr, bytelength); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++ ++//3for return PUCHAR value ++ ++int ++read_usb_sys_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if( type == RTD2832U_USB ) ++ { ++ ret = read_usb_register( dib , byte_addr , buf , byte_num); ++ } ++ else if ( type == RTD2832U_SYS ) ++ { ++ ret = read_sys_register( dib , byte_addr , buf , byte_num); ++ } ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++ ++ ++int ++write_usb_sys_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if( type == RTD2832U_USB ) ++ { ++ ret = write_usb_register( dib , byte_addr , buf , byte_num); ++ } ++ else if ( type == RTD2832U_SYS ) ++ { ++ ret = write_sys_register( dib , byte_addr , buf , byte_num); ++ } ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++ ++//3for return INT value ++int ++read_usb_sys_int_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned short n_bytes, ++ int* p_val) ++{ ++ int i; ++ u8 val[LEN_4_BYTE]; ++ int nbit_shift; ++ ++ *p_val= 0; ++ ++ if (read_usb_sys_char_bytes( dib, type, byte_addr, val , n_bytes)) goto error; ++ ++ for (i= 0; i< n_bytes; i++) ++ { ++ nbit_shift = i<<3 ; ++ *p_val = *p_val + (val[i]<= 0; i--) ++ { ++ nbit_shift= i << 3; ++ u8_val[i] = (val>> nbit_shift) & 0xff; ++ } ++ ++ if( write_usb_sys_char_bytes( dib , type , byte_addr, u8_val , n_bytes) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++int ++write_rtl2836_demod_register( ++ struct dvb_usb_device* dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int i; ++ unsigned char datatmp; ++ int try_num; ++ switch(page) ++ { ++ //3 R/W regitser Once R/W "ONE BYTE" ++ case PAGE_0: ++ case PAGE_1: ++ case PAGE_2: ++ case PAGE_3: ++ case PAGE_4: ++ for(i=0; i= 4) ++ goto error; ++ ++ if(read_demod_register(dib, demod_device_addr, page, offset+i, &datatmp, LEN_1_BYTE)) ++ { ++ try_num++; ++ deb_info("%s fail read\n", __FUNCTION__); ++ goto label_read; ++ } ++ ++ if(datatmp != data[i]) ++ { ++ try_num++; ++ deb_info("%s read != write\n", __FUNCTION__); ++ goto label_write; ++ } ++ } ++ break; ++ ++ default: ++ goto error; ++ break; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++int ++read_rtl2836_demod_register( ++ struct dvb_usb_device*dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ ++ int i; ++ unsigned char tmp; ++ ++ switch(page) ++ { ++ //3 R/W regitser Once R/W "ONE BYTE" ++ case PAGE_0: ++ case PAGE_1: ++ case PAGE_2: ++ case PAGE_3: ++ case PAGE_4: ++ for(i=0; iInitialize(pTuner); ++ ++ ++ // Set tuner parameters. (RF frequency) ++ // Note: In the example, RF frequency is 474 MHz. ++ RfFreqHz = 474000000; ++ ++ pTuner->SetIfFreqHz(pTuner, RfFreqHz); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ // Get tuenr type. ++ // Note: One can find tuner type in MODULE_TYPE enumeration. ++ pTuner->GetTunerType(pTuner, &TunerType); ++ ++ // Get tuner I2C device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get tuner parameters. (RF frequency) ++ pTuner->GetRfFreqHz(pTuner, &RfFreqHz); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++/// tuner module pre-definition ++typedef struct TUNER_MODULE_TAG TUNER_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner type getting function pointer ++ ++One can use TUNER_FP_GET_TUNER_TYPE() to get tuner type. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [out] pTunerType Pointer to an allocated memory for storing tuner type ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_GET_TUNER_TYPE() with the corresponding function. ++ ++ ++@see TUNER_TYPE ++ ++*/ ++typedef void ++(*TUNER_FP_GET_TUNER_TYPE)( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner I2C device address getting function pointer ++ ++One can use TUNER_FP_GET_DEVICE_ADDR() to get tuner I2C device address. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing tuner I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get tuner device address successfully. ++@retval FUNCTION_ERROR Get tuner device address unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*TUNER_FP_GET_DEVICE_ADDR)( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner initializing function pointer ++ ++One can use TUNER_FP_INITIALIZE() to initialie tuner. ++ ++ ++@param [in] pTuner The tuner module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize tuner successfully. ++@retval FUNCTION_ERROR Initialize tuner unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*TUNER_FP_INITIALIZE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner RF frequency setting function pointer ++ ++One can use TUNER_FP_SET_RF_FREQ_HZ() to set tuner RF frequency in Hz. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set tuner RF frequency successfully. ++@retval FUNCTION_ERROR Set tuner RF frequency unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_SET_RF_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*TUNER_FP_SET_RF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner RF frequency getting function pointer ++ ++One can use TUNER_FP_GET_RF_FREQ_HZ() to get tuner RF frequency in Hz. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [in] pRfFreqHz Pointer to an allocated memory for storing demod RF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get tuner RF frequency successfully. ++@retval FUNCTION_ERROR Get tuner RF frequency unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_GET_RF_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*TUNER_FP_GET_RF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// TDCG-G052D extra module ++typedef struct TDCGG052D_EXTRA_MODULE_TAG TDCGG052D_EXTRA_MODULE; ++struct TDCGG052D_EXTRA_MODULE_TAG ++{ ++ // TDCG-G052D extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++ unsigned char BandSwitch; ++ unsigned char Auxiliary; ++}; ++ ++ ++ ++ ++ ++// TDCH-G001D extra module ++typedef struct TDCHG001D_EXTRA_MODULE_TAG TDCHG001D_EXTRA_MODULE; ++struct TDCHG001D_EXTRA_MODULE_TAG ++{ ++ // TDCH-G001D extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++ unsigned char BandSwitch; ++ unsigned char Auxiliary; ++}; ++ ++ ++ ++ ++ ++// TDQE3-003A extra module ++#define TDQE3003A_CONTROL_BYTE_NUM 3 ++ ++typedef struct TDQE3003A_EXTRA_MODULE_TAG TDQE3003A_EXTRA_MODULE; ++struct TDQE3003A_EXTRA_MODULE_TAG ++{ ++ // TDQE3-003A extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control[TDQE3003A_CONTROL_BYTE_NUM]; ++}; ++ ++ ++ ++ ++ ++// DCT-7045 extra module ++typedef struct DCT7045_EXTRA_MODULE_TAG DCT7045_EXTRA_MODULE; ++struct DCT7045_EXTRA_MODULE_TAG ++{ ++ // DCT-7045 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++}; ++ ++ ++ ++ ++ ++/// MT2062 extra module ++typedef struct MT2062_EXTRA_MODULE_TAG MT2062_EXTRA_MODULE; ++ ++// MT2062 handle openning function pointer ++typedef int ++(*MT2062_FP_OPEN_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2062 handle closing function pointer ++typedef int ++(*MT2062_FP_CLOSE_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2062 handle getting function pointer ++typedef void ++(*MT2062_FP_GET_HANDLE)( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++// MT2062 IF frequency setting function pointer ++typedef int ++(*MT2062_FP_SET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ); ++ ++// MT2062 IF frequency getting function pointer ++typedef int ++(*MT2062_FP_GET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++// MT2062 extra module ++struct MT2062_EXTRA_MODULE_TAG ++{ ++ // MT2062 extra variables ++ void *DeviceHandle; ++ int LoopThroughMode; ++ ++ unsigned long IfFreqHz; ++ ++ int IsIfFreqHzSet; ++ ++ // MT2062 extra function pointers ++ MT2062_FP_OPEN_HANDLE OpenHandle; ++ MT2062_FP_CLOSE_HANDLE CloseHandle; ++ MT2062_FP_GET_HANDLE GetHandle; ++ MT2062_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ MT2062_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++}; ++ ++ ++ ++ ++ ++/// MxL5005S extra module ++#define INITCTRL_NUM 40 ++#define CHCTRL_NUM 36 ++#define MXLCTRL_NUM 189 ++#define TUNER_REGS_NUM 104 ++ ++typedef struct MXL5005S_EXTRA_MODULE_TAG MXL5005S_EXTRA_MODULE; ++ ++// MXL5005 Tuner Register Struct ++typedef struct _TunerReg_struct ++{ ++ unsigned short Reg_Num ; // Tuner Register Address ++ unsigned short Reg_Val ; // Current sofware programmed value waiting to be writen ++} TunerReg_struct ; ++ ++// MXL5005 Tuner Control Struct ++typedef struct _TunerControl_struct { ++ unsigned short Ctrl_Num ; // Control Number ++ unsigned short size ; // Number of bits to represent Value ++ unsigned short addr[25] ; // Array of Tuner Register Address for each bit position ++ unsigned short bit[25] ; // Array of bit position in Register Address for each bit position ++ unsigned short val[25] ; // Binary representation of Value ++} TunerControl_struct ; ++ ++// MXL5005 Tuner Struct ++typedef struct _Tuner_struct ++{ ++ unsigned char Mode ; // 0: Analog Mode ; 1: Digital Mode ++ unsigned char IF_Mode ; // for Analog Mode, 0: zero IF; 1: low IF ++ unsigned long Chan_Bandwidth ; // filter channel bandwidth (6, 7, 8) ++ unsigned long IF_OUT ; // Desired IF Out Frequency ++ unsigned short IF_OUT_LOAD ; // IF Out Load Resistor (200/300 Ohms) ++ unsigned long RF_IN ; // RF Input Frequency ++ unsigned long Fxtal ; // XTAL Frequency ++ unsigned char AGC_Mode ; // AGC Mode 0: Dual AGC; 1: Single AGC ++ unsigned short TOP ; // Value: take over point ++ unsigned char CLOCK_OUT ; // 0: turn off clock out; 1: turn on clock out ++ unsigned char DIV_OUT ; // 4MHz or 16MHz ++ unsigned char CAPSELECT ; // 0: disable On-Chip pulling cap; 1: enable ++ unsigned char EN_RSSI ; // 0: disable RSSI; 1: enable RSSI ++ unsigned char Mod_Type ; // Modulation Type; ++ // 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable ++ unsigned char TF_Type ; // Tracking Filter Type ++ // 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H ++ ++ // Calculated Settings ++ unsigned long RF_LO ; // Synth RF LO Frequency ++ unsigned long IF_LO ; // Synth IF LO Frequency ++ unsigned long TG_LO ; // Synth TG_LO Frequency ++ ++ // Pointers to ControlName Arrays ++ unsigned short Init_Ctrl_Num ; // Number of INIT Control Names ++ TunerControl_struct Init_Ctrl[INITCTRL_NUM] ; // INIT Control Names Array Pointer ++ unsigned short CH_Ctrl_Num ; // Number of CH Control Names ++ TunerControl_struct CH_Ctrl[CHCTRL_NUM] ; // CH Control Name Array Pointer ++ unsigned short MXL_Ctrl_Num ; // Number of MXL Control Names ++ TunerControl_struct MXL_Ctrl[MXLCTRL_NUM] ; // MXL Control Name Array Pointer ++ ++ // Pointer to Tuner Register Array ++ unsigned short TunerRegs_Num ; // Number of Tuner Registers ++ TunerReg_struct TunerRegs[TUNER_REGS_NUM] ; // Tuner Register Array Pointer ++} Tuner_struct ; ++ ++// MxL5005S register setting function pointer ++typedef int ++(*MXL5005S_FP_SET_REGS_WITH_TABLE)( ++ TUNER_MODULE *pTuner, ++ unsigned char *pAddrTable, ++ unsigned char *pByteTable, ++ int TableLen ++ ); ++ ++// MxL5005S register mask bits setting function pointer ++typedef int ++(*MXL5005S_FP_SET_REG_MASK_BITS)( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ); ++ ++// MxL5005S spectrum mode setting function pointer ++typedef int ++(*MXL5005S_FP_SET_SPECTRUM_MODE)( ++ TUNER_MODULE *pTuner, ++ int SpectrumMode ++ ); ++ ++// MxL5005S bandwidth setting function pointer ++typedef int ++(*MXL5005S_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// MxL5005S extra module ++struct MXL5005S_EXTRA_MODULE_TAG ++{ ++ // MxL5005S function pointers ++ MXL5005S_FP_SET_REGS_WITH_TABLE SetRegsWithTable; ++ MXL5005S_FP_SET_REG_MASK_BITS SetRegMaskBits; ++ MXL5005S_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ MXL5005S_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ ++ ++ // MxL5005S extra data ++ unsigned char AgcMasterByte; // Variable name in MaxLinear source code: AGC_MASTER_BYTE ++ ++ // MaxLinear defined struct ++ Tuner_struct MxlDefinedTunerStructure; ++}; ++ ++ ++ ++ ++ ++// TDVM-H715P extra module ++typedef struct TDVMH715P_EXTRA_MODULE_TAG TDVMH751P_EXTRA_MODULE; ++struct TDVMH715P_EXTRA_MODULE_TAG ++{ ++ // TDVM-H715P extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++ unsigned char BandSwitch; ++ unsigned char Auxiliary; ++}; ++ ++ ++ ++ ++ ++// UBA00AL extra module ++typedef struct UBA00AL_EXTRA_MODULE_TAG UBA00AL_EXTRA_MODULE; ++struct UBA00AL_EXTRA_MODULE_TAG ++{ ++ // UBA00AL extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char BandSwitch; ++ unsigned char Control2; ++}; ++ ++ ++ ++ ++ ++/// MT2266 extra module ++typedef struct MT2266_EXTRA_MODULE_TAG MT2266_EXTRA_MODULE; ++ ++// MT2266 handle openning function pointer ++typedef int ++(*MT2266_FP_OPEN_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2266 handle closing function pointer ++typedef int ++(*MT2266_FP_CLOSE_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2266 handle getting function pointer ++typedef void ++(*MT2266_FP_GET_HANDLE)( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++// MT2266 bandwidth setting function pointer ++typedef int ++(*MT2266_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// MT2266 bandwidth getting function pointer ++typedef int ++(*MT2266_FP_GET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++// MT2266 extra module ++struct MT2266_EXTRA_MODULE_TAG ++{ ++ // MT2266 extra variables ++ void *DeviceHandle; ++ unsigned long BandwidthHz; ++ int IsBandwidthHzSet; ++ ++ // MT2266 extra function pointers ++ MT2266_FP_OPEN_HANDLE OpenHandle; ++ MT2266_FP_CLOSE_HANDLE CloseHandle; ++ MT2266_FP_GET_HANDLE GetHandle; ++ MT2266_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ MT2266_FP_GET_BANDWIDTH_HZ GetBandwidthHz; ++}; ++ ++ ++ ++ ++ ++// FC2580 extra module ++typedef struct FC2580_EXTRA_MODULE_TAG FC2580_EXTRA_MODULE; ++ ++// FC2580 bandwidth mode setting function pointer ++typedef int ++(*FC2580_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// FC2580 bandwidth mode getting function pointer ++typedef int ++(*FC2580_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// FC2580 extra module ++struct FC2580_EXTRA_MODULE_TAG ++{ ++ // FC2580 extra variables ++ unsigned long CrystalFreqHz; ++ int AgcMode; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // FC2580 extra function pointers ++ FC2580_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ FC2580_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++/// TUA9001 extra module ++typedef struct TUA9001_EXTRA_MODULE_TAG TUA9001_EXTRA_MODULE; ++ ++// Extra manipulaing function ++typedef int ++(*TUA9001_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++typedef int ++(*TUA9001_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++typedef int ++(*TUA9001_FP_GET_REG_BYTES_WITH_REG_ADDR)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte, ++ unsigned char ByteNum ++ ); ++ ++typedef int ++(*TUA9001_FP_SET_SYS_REG_BYTE)( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char WritingByte ++ ); ++ ++typedef int ++(*TUA9001_FP_GET_SYS_REG_BYTE)( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++// TUA9001 extra module ++struct TUA9001_EXTRA_MODULE_TAG ++{ ++ // TUA9001 extra variables ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // TUA9001 extra function pointers ++ TUA9001_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ TUA9001_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ TUA9001_FP_GET_REG_BYTES_WITH_REG_ADDR GetRegBytesWithRegAddr; ++ TUA9001_FP_SET_SYS_REG_BYTE SetSysRegByte; ++ TUA9001_FP_GET_SYS_REG_BYTE GetSysRegByte; ++}; ++ ++ ++ ++ ++ ++// DTT-75300 extra module ++typedef struct DTT75300_EXTRA_MODULE_TAG DTT75300_EXTRA_MODULE; ++struct DTT75300_EXTRA_MODULE_TAG ++{ ++ // DTT-75300 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++ unsigned char Control4; ++}; ++ ++ ++ ++ ++ ++// MxL5007T extra module ++typedef struct MXL5007T_EXTRA_MODULE_TAG MXL5007T_EXTRA_MODULE; ++ ++// MxL5007 TunerConfig Struct ++typedef struct _MxL5007_TunerConfigS ++{ ++ int I2C_Addr; ++ int Mode; ++ int IF_Diff_Out_Level; ++ int Xtal_Freq; ++ int IF_Freq; ++ int IF_Spectrum; ++ int ClkOut_Setting; ++ int ClkOut_Amp; ++ int BW_MHz; ++ unsigned int RF_Freq_Hz; ++ ++ // Additional definition ++ TUNER_MODULE *pTuner; ++ ++} MxL5007_TunerConfigS; ++ ++// MxL5007T bandwidth mode setting function pointer ++typedef int ++(*MXL5007T_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// MxL5007T bandwidth mode getting function pointer ++typedef int ++(*MXL5007T_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// MxL5007T extra module ++struct MXL5007T_EXTRA_MODULE_TAG ++{ ++ // MxL5007T extra variables ++ int LoopThroughMode; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // MxL5007T MaxLinear-defined structure ++ MxL5007_TunerConfigS *pTunerConfigS; ++ MxL5007_TunerConfigS TunerConfigSMemory; ++ ++ // MxL5007T extra function pointers ++ MXL5007T_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ MXL5007T_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// VA1T1ED6093 extra module ++typedef struct VA1T1ED6093_EXTRA_MODULE_TAG VA1T1ED6093_EXTRA_MODULE; ++struct VA1T1ED6093_EXTRA_MODULE_TAG ++{ ++ // VA1T1ED6093 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++/// TUA8010 extra module ++typedef struct TUA8010_EXTRA_MODULE_TAG TUA8010_EXTRA_MODULE; ++ ++// Extra manipulaing function ++typedef int ++(*TUA8010_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++typedef int ++(*TUA8010_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++typedef int ++(*TUA8010_FP_GET_REG_BYTES_WITH_REG_ADDR)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte, ++ unsigned char ByteNum ++ ); ++ ++// TUA8010 extra module ++struct TUA8010_EXTRA_MODULE_TAG ++{ ++ // TUA8010 extra variables ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // TUA8010 extra function pointers ++ TUA8010_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ TUA8010_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ TUA8010_FP_GET_REG_BYTES_WITH_REG_ADDR GetRegBytesWithRegAddr; ++}; ++ ++ ++ ++ ++ ++// E4000 extra module ++typedef struct E4000_EXTRA_MODULE_TAG E4000_EXTRA_MODULE; ++ ++// E4000 register byte getting function pointer ++typedef int ++(*E4000_FP_GET_REG_BYTE)( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++// E4000 bandwidth Hz setting function pointer ++typedef int ++(*E4000_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// E4000 bandwidth Hz getting function pointer ++typedef int ++(*E4000_FP_GET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++// E4000 extra module ++struct E4000_EXTRA_MODULE_TAG ++{ ++ // E4000 extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthHz; ++ int IsBandwidthHzSet; ++ ++ // E4000 extra function pointers ++ E4000_FP_GET_REG_BYTE GetRegByte; ++ E4000_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ E4000_FP_GET_BANDWIDTH_HZ GetBandwidthHz; ++}; ++ ++ ++ ++ ++ ++// DCT-70704 extra module ++typedef struct DCT70704_EXTRA_MODULE_TAG DCT70704_EXTRA_MODULE; ++struct DCT70704_EXTRA_MODULE_TAG ++{ ++ // DCT-70704 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char BandSwitch; ++ unsigned char Control2; ++}; ++ ++ ++ ++ ++ ++/// MT2063 extra module ++typedef struct MT2063_EXTRA_MODULE_TAG MT2063_EXTRA_MODULE; ++ ++// MT2063 handle openning function pointer ++typedef int ++(*MT2063_FP_OPEN_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2063 handle closing function pointer ++typedef int ++(*MT2063_FP_CLOSE_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2063 handle getting function pointer ++typedef void ++(*MT2063_FP_GET_HANDLE)( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++// MT2063 IF frequency setting function pointer ++typedef int ++(*MT2063_FP_SET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ); ++ ++// MT2063 IF frequency getting function pointer ++typedef int ++(*MT2063_FP_GET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++// MT2063 bandwidth setting function pointer ++typedef int ++(*MT2063_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// MT2063 bandwidth getting function pointer ++typedef int ++(*MT2063_FP_GET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++// MT2063 extra module ++struct MT2063_EXTRA_MODULE_TAG ++{ ++ // MT2063 extra variables ++ void *DeviceHandle; ++ int StandardMode; ++ unsigned long VgaGc; ++ ++ unsigned long IfFreqHz; ++ unsigned long BandwidthHz; ++ ++ int IsIfFreqHzSet; ++ int IsBandwidthHzSet; ++ ++ // MT2063 extra function pointers ++ MT2063_FP_OPEN_HANDLE OpenHandle; ++ MT2063_FP_CLOSE_HANDLE CloseHandle; ++ MT2063_FP_GET_HANDLE GetHandle; ++ MT2063_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ MT2063_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ MT2063_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ MT2063_FP_GET_BANDWIDTH_HZ GetBandwidthHz; ++}; ++ ++ ++ ++ ++ ++// FC0012 extra module ++typedef struct FC0012_EXTRA_MODULE_TAG FC0012_EXTRA_MODULE; ++ ++// FC0012 bandwidth mode setting function pointer ++typedef int ++(*FC0012_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// FC0012 bandwidth mode getting function pointer ++typedef int ++(*FC0012_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// FC0012 extra module ++struct FC0012_EXTRA_MODULE_TAG ++{ ++ // FC0012 extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // FC0012 extra function pointers ++ FC0012_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ FC0012_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// TDAG extra module ++typedef struct TDAG_EXTRA_MODULE_TAG TDAG_EXTRA_MODULE; ++struct TDAG_EXTRA_MODULE_TAG ++{ ++ // TDAG extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// ADMTV804 extra module ++typedef struct ADMTV804_EXTRA_MODULE_TAG ADMTV804_EXTRA_MODULE; ++ ++// ADMTV804 standard bandwidth mode setting function pointer ++typedef int ++(*ADMTV804_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// ADMTV804 standard bandwidth mode getting function pointer ++typedef int ++(*ADMTV804_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// ADMTV804 extra module ++struct ADMTV804_EXTRA_MODULE_TAG ++{ ++ // ADMTV804 extra variables (from ADMTV804 source code) ++ unsigned char REV_INFO; ++ unsigned char g_curBand; ++ unsigned char pddiv3; ++ unsigned char REG24; ++ unsigned char REG2B; ++ unsigned char REG2E; ++ unsigned char REG30; ++ unsigned char REG31; ++ unsigned char REG5A; ++ ++ // ADMTV804 extra variables ++ unsigned long CrystalFreqHz; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ ++ // ADMTV804 extra function pointers ++ ADMTV804_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ ADMTV804_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// MAX3543 extra module ++typedef struct MAX3543_EXTRA_MODULE_TAG MAX3543_EXTRA_MODULE; ++ ++// MAX3543 bandwidth mode setting function pointer ++typedef int ++(*MAX3543_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// MAX3543 bandwidth mode getting function pointer ++typedef int ++(*MAX3543_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// MAX3543 extra module ++struct MAX3543_EXTRA_MODULE_TAG ++{ ++ // MAX3543 extra variables (from MAX3543 source code) ++ unsigned short TFRomCoefs[3][4]; ++ unsigned short denominator; ++ unsigned long fracscale ; ++ unsigned short regs[22]; ++ unsigned short IF_Frequency; ++ ++ int broadcast_standard; ++ int XTALSCALE; ++ int XTALREF; ++ int LOSCALE; ++ ++ ++ // MAX3543 extra variables ++ unsigned long CrystalFreqHz; ++ int StandardMode; ++ unsigned long IfFreqHz; ++ int OutputMode; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // MAX3543 extra function pointers ++ MAX3543_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ MAX3543_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// TDA18272 extra module ++typedef struct TDA18272_EXTRA_MODULE_TAG TDA18272_EXTRA_MODULE; ++ ++// TDA18272 standard bandwidth mode setting function pointer ++typedef int ++(*TDA18272_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ); ++ ++// TDA18272 standard bandwidth mode getting function pointer ++typedef int ++(*TDA18272_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ); ++ ++// TDA18272 power mode setting function pointer ++typedef int ++(*TDA18272_FP_SET_POWER_MODE)( ++ TUNER_MODULE *pTuner, ++ int PowerMode ++ ); ++ ++// TDA18272 power mode getting function pointer ++typedef int ++(*TDA18272_FP_GET_POWER_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pPowerMode ++ ); ++ ++// TDA18272 IF frequency getting function pointer ++typedef int ++(*TDA18272_FP_GET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++// TDA18272 extra module ++struct TDA18272_EXTRA_MODULE_TAG ++{ ++ // TDA18272 extra variables ++ unsigned long CrystalFreqHz; ++ int UnitNo; ++ int IfOutputVppMode; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ int PowerMode; ++ int IsPowerModeSet; ++ ++ // TDA18272 extra function pointers ++ TDA18272_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ TDA18272_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++ TDA18272_FP_SET_POWER_MODE SetPowerMode; ++ TDA18272_FP_GET_POWER_MODE GetPowerMode; ++ TDA18272_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++}; ++ ++ ++ ++ ++ ++// FC0013 extra module ++typedef struct FC0013_EXTRA_MODULE_TAG FC0013_EXTRA_MODULE; ++ ++// FC0013 bandwidth mode setting function pointer ++typedef int ++(*FC0013_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// FC0013 bandwidth mode getting function pointer ++typedef int ++(*FC0013_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// FC0013 reset IQ LPF BW ++typedef int ++(*FC0013_FP_RC_CAL_RESET)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// FC0013 increase IQ LPF BW ++typedef int ++(*FC0013_FP_RC_CAL_ADD)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// FC0013 extra module ++struct FC0013_EXTRA_MODULE_TAG ++{ ++ // FC0013 extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ int RcAddValue; ++ ++ // FC0013 extra function pointers ++ FC0013_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ FC0013_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ FC0013_FP_RC_CAL_RESET RcCalReset; ++ FC0013_FP_RC_CAL_ADD RcCalAdd; ++}; ++ ++ ++ ++ ++ ++// VA1E1ED2403 extra module ++typedef struct VA1E1ED2403_EXTRA_MODULE_TAG VA1E1ED2403_EXTRA_MODULE; ++struct VA1E1ED2403_EXTRA_MODULE_TAG ++{ ++ // VA1E1ED2403 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// Avalon extra module ++#define AVALON_RF_REG_MAX_ADDR 0x60 ++#define AVALON_BB_REG_MAX_ADDR 0x4f ++ ++typedef struct _AVALON_CONFIG_STRUCT { ++ double RFChannelMHz; ++ double dIfFrequencyMHz; ++ double f_dac_MHz; ++ int TVStandard; ++} AVALON_CONFIG_STRUCT, *PAVALON_CONFIG_STRUCT; ++ ++typedef struct AVALON_EXTRA_MODULE_TAG AVALON_EXTRA_MODULE; ++ ++// AVALON standard bandwidth mode setting function pointer ++typedef int ++(*AVALON_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ); ++ ++// AVALON standard bandwidth mode getting function pointer ++typedef int ++(*AVALON_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ); ++ ++// AVALON extra module ++struct AVALON_EXTRA_MODULE_TAG ++{ ++ // AVALON extra variables (from AVALON source code) ++ unsigned char g_avalon_rf_reg_work_table[AVALON_RF_REG_MAX_ADDR+1]; ++ unsigned char g_avalon_bb_reg_work_table[AVALON_BB_REG_MAX_ADDR+1]; ++ ++ int ++ (*g_avalon_i2c_read_handler)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBuffer, ++ unsigned short *pByteNum ++ ); ++ ++ int ++ (*g_avalon_i2c_write_handler)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char *pWritingBuffer, ++ unsigned short *pByteNum ++ ); ++ ++ AVALON_CONFIG_STRUCT AvalonConfig; ++ ++ ++ // AVALON extra variables ++ unsigned char AtvDemodDeviceAddr; ++ unsigned long CrystalFreqHz; ++ unsigned long IfFreqHz; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ ++ // AVALON extra function pointers ++ AVALON_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ AVALON_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// SutRx201 extra module ++typedef struct SUTRE201_EXTRA_MODULE_TAG SUTRE201_EXTRA_MODULE; ++ ++// SUTRE201 standard bandwidth mode setting function pointer ++typedef int ++(*SUTRE201_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ); ++ ++// SUTRE201 standard bandwidth mode getting function pointer ++typedef int ++(*SUTRE201_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ); ++ ++// SUTRE201 tuner enabling function pointer ++typedef int ++(*SUTRE201_FP_ENABLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// SUTRE201 tuner disabling function pointer ++typedef int ++(*SUTRE201_FP_DISABLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// SUTRE201 tuner IF port mode setting function pointer ++typedef int ++(*SUTRE201_FP_SET_IF_PORT_MODE)( ++ TUNER_MODULE *pTuner, ++ int IfPortMode ++ ); ++ ++// SUTRE201 extra module ++struct SUTRE201_EXTRA_MODULE_TAG ++{ ++ // SUTRE201 extra variables ++ unsigned long CrystalFreqHz; ++ unsigned long IfFreqHz; ++ int IfPortMode; ++ int CountryMode; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ ++ // SUTRE201 extra function pointers ++ SUTRE201_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ SUTRE201_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++ SUTRE201_FP_ENABLE Enable; ++ SUTRE201_FP_DISABLE Disable; ++ SUTRE201_FP_SET_IF_PORT_MODE SetIfPortMode; ++}; ++ ++ ++ ++ ++ ++// MR1300 extra module ++typedef struct MR1300_EXTRA_MODULE_TAG MR1300_EXTRA_MODULE; ++struct MR1300_EXTRA_MODULE_TAG ++{ ++ // MR1300 extra data ++ unsigned long CrystalFreqHz; ++}; ++ ++ ++ ++ ++ ++// TDAC7 extra module ++typedef struct TDAC7_EXTRA_MODULE_TAG TDAC7_EXTRA_MODULE; ++struct TDAC7_EXTRA_MODULE_TAG ++{ ++ // TDAC7 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++/// Tuner module structure ++struct TUNER_MODULE_TAG ++{ ++ // Private variables ++ int TunerType; ///< Tuner type ++ unsigned char DeviceAddr; ///< Tuner I2C device address ++ unsigned long RfFreqHz; ///< Tuner RF frequency in Hz ++ ++ int IsRfFreqHzSet; ///< Tuner RF frequency in Hz (setting status) ++ ++ union ///< Tuner extra module used by driving module ++ { ++ TDCGG052D_EXTRA_MODULE Tdcgg052d; ++ TDCHG001D_EXTRA_MODULE Tdchg001d; ++ TDQE3003A_EXTRA_MODULE Tdqe3003a; ++ DCT7045_EXTRA_MODULE Dct7045; ++ MT2062_EXTRA_MODULE Mt2062; ++ MXL5005S_EXTRA_MODULE Mxl5005s; ++ TDVMH751P_EXTRA_MODULE Tdvmh751p; ++ UBA00AL_EXTRA_MODULE Uba00al; ++ MT2266_EXTRA_MODULE Mt2266; ++ FC2580_EXTRA_MODULE Fc2580; ++ TUA9001_EXTRA_MODULE Tua9001; ++ DTT75300_EXTRA_MODULE Dtt75300; ++ MXL5007T_EXTRA_MODULE Mxl5007t; ++ VA1T1ED6093_EXTRA_MODULE Va1t1ed6093; ++ TUA8010_EXTRA_MODULE Tua8010; ++ E4000_EXTRA_MODULE E4000; ++ DCT70704_EXTRA_MODULE Dct70704; ++ MT2063_EXTRA_MODULE Mt2063; ++ FC0012_EXTRA_MODULE Fc0012; ++ TDAG_EXTRA_MODULE Tdag; ++ ADMTV804_EXTRA_MODULE Admtv804; ++ MAX3543_EXTRA_MODULE Max3543; ++ TDA18272_EXTRA_MODULE Tda18272; ++ FC0013_EXTRA_MODULE Fc0013; ++ VA1E1ED2403_EXTRA_MODULE Va1e1ed2403; ++ AVALON_EXTRA_MODULE Avalon; ++ SUTRE201_EXTRA_MODULE Sutre201; ++ MR1300_EXTRA_MODULE Mr1300; ++ TDAC7_EXTRA_MODULE Tdac7; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module ++ ++ ++ // Tuner manipulating functions ++ TUNER_FP_GET_TUNER_TYPE GetTunerType; ///< Tuner type getting function pointer ++ TUNER_FP_GET_DEVICE_ADDR GetDeviceAddr; ///< Tuner I2C device address getting function pointer ++ ++ TUNER_FP_INITIALIZE Initialize; ///< Tuner initializing function pointer ++ TUNER_FP_SET_RF_FREQ_HZ SetRfFreqHz; ///< Tuner RF frequency setting function pointer ++ TUNER_FP_GET_RF_FREQ_HZ GetRfFreqHz; ///< Tuner RF frequency getting function pointer ++}; ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_e4000.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_e4000.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_e4000.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_e4000.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,2482 @@ ++/** ++ ++@file ++ ++@brief E4000 tuner module definition ++ ++One can manipulate E4000 tuner through E4000 module. ++E4000 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_e4000.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief E4000 tuner module builder ++ ++Use BuildE4000Module() to build E4000 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to E4000 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr E4000 I2C device address ++@param [in] CrystalFreqHz E4000 crystal frequency in Hz ++@param [in] AgcMode E4000 AGC mode ++ ++ ++@note ++ -# One should call BuildE4000Module() to build E4000 module before using it. ++ ++*/ ++void ++BuildE4000Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ E4000_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_E4000; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = e4000_GetTunerType; ++ pTuner->GetDeviceAddr = e4000_GetDeviceAddr; ++ ++ pTuner->Initialize = e4000_Initialize; ++ pTuner->SetRfFreqHz = e4000_SetRfFreqHz; ++ pTuner->GetRfFreqHz = e4000_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->IsBandwidthHzSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->GetRegByte = e4000_GetRegByte; ++ pExtra->SetBandwidthHz = e4000_SetBandwidthHz; ++ pExtra->GetBandwidthHz = e4000_GetBandwidthHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++e4000_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++e4000_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++e4000_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Initialize tuner. ++ // Note: Call E4000 source code functions. ++ if(tunerreset(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Tunerclock(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Qpeak(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(DCoffloop(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(GainControlinit(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++e4000_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ int RfFreqKhz; ++ int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Set tuner RF frequency in KHz. ++ // Note: 1. RfFreqKhz = round(RfFreqHz / 1000) ++ // CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ // 2. Call E4000 source code functions. ++ RfFreqKhz = (int)((RfFreqHz + 500) / 1000); ++ CrystalFreqKhz = (int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(Gainmanual(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(E4000_gain_freq(pTuner, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(PLL(pTuner, CrystalFreqKhz, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(LNAfilter(pTuner, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(freqband(pTuner, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(DCoffLUT(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(GainControlauto(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++e4000_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get E4000 register byte. ++ ++*/ ++int ++e4000_GetRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ) ++{ ++ // Call I2CReadByte() to read tuner register. ++ if(I2CReadByte(pTuner, NO_USE, RegAddr, pReadingByte) != E4000_I2C_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set E4000 tuner bandwidth. ++ ++*/ ++int ++e4000_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ int BandwidthKhz; ++ int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Set tuner bandwidth Hz. ++ // Note: 1. BandwidthKhz = round(BandwidthHz / 1000) ++ // CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ // 2. Call E4000 source code functions. ++ BandwidthKhz = (int)((BandwidthHz + 500) / 1000); ++ CrystalFreqKhz = (int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(IFfilter(pTuner, BandwidthKhz, CrystalFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner bandwidth Hz parameter. ++ pExtra->BandwidthHz = BandwidthHz; ++ pExtra->IsBandwidthHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get E4000 tuner bandwidth. ++ ++*/ ++int ++e4000_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Get tuner bandwidth Hz from tuner module. ++ if(pExtra->IsBandwidthHzSet != YES) ++ goto error_status_get_tuner_bandwidth_hz; ++ ++ *pBandwidthHz = pExtra->BandwidthHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_hz: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Function (implemeted for E4000) ++int ++I2CReadByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, pReadingByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return E4000_I2C_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return E4000_I2C_FAIL; ++} ++ ++ ++ ++ ++ ++int ++I2CWriteByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char WritingByte ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = RegAddr; ++ WritingBuffer[1] = WritingByte; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return E4000_I2C_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return E4000_I2C_FAIL; ++} ++ ++ ++ ++ ++ ++int ++I2CWriteArray( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegStartAddr, ++ unsigned char ByteNum, ++ unsigned char *pWritingBytes ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i; ++ ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = RegStartAddr; ++ ++ for(i = 0; i < ByteNum; i++) ++ WritingBuffer[LEN_1_BYTE + i] = pWritingBytes[i]; ++ ++ ++ /// Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, ByteNum + LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return E4000_I2C_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return E4000_I2C_FAIL; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Elonics. ++ ++ ++ ++ ++ ++// Elonics source code - E4000_API_rev2_04_realtek.cpp ++ ++ ++//****************************************************************************\ ++// ++// Filename E4000_initialisation.c ++// Revision 2.04 ++// ++// Description: ++// Initialisation script for the Elonics E4000 revC tuner ++// ++// Copyright (c) Elonics Ltd ++// ++// Any software supplied free of charge for use with elonics ++// evaluation kits is supplied without warranty and for ++// evaluation purposes only. Incorporation of any of this ++// code into products for open sale is permitted but only at ++// the user's own risk. Elonics accepts no liability for the ++// integrity of this software whatsoever. ++// ++// ++//****************************************************************************/ ++//#include ++//#include ++// ++// User defined variable definitions ++// ++/* ++int Ref_clk = 26000; // Reference clock frequency(kHz). ++int Freq = 590000; // RF Frequency (kHz) ++int bandwidth = 8000; //RF channel bandwith (kHz) ++*/ ++// ++// API defined variable definitions ++//int VCO_freq; ++//unsigned char writearray[5]; ++//unsigned char read1[1]; ++//int status; ++// ++// ++// function definitions ++// ++/* ++int tunerreset (); ++int Tunerclock(); ++int filtercal(); ++int Qpeak(); ++int PLL(int Ref_clk, int Freq); ++int LNAfilter(int Freq); ++int IFfilter(int bandwidth, int Ref_clk); ++int freqband(int Freq); ++int DCoffLUT(); ++int DCoffloop(); ++int commonmode(); ++int GainControlinit(); ++*/ ++// ++//**************************************************************************** ++// --- Public functions ------------------------------------------------------ ++/****************************************************************************\ ++* Function: tunerreset ++* ++* Detailed Description: ++* The function resets the E4000 tuner. (Register 0x00). ++* ++\****************************************************************************/ ++ ++int tunerreset(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 64; ++ // For dummy I2C command, don't check executing status. ++ status=I2CWriteByte (pTuner, 200,2,writearray[0]); ++ status=I2CWriteByte (pTuner, 200,2,writearray[0]); ++ //printf("\nRegister 0=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,9,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,5,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 7; ++ status=I2CWriteByte (pTuner, 200,0,writearray[0]); ++ //printf("\nRegister 0=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: Tunerclock ++* ++* Detailed Description: ++* The function configures the E4000 clock. (Register 0x06, 0x7a). ++* Function disables the clock - values can be modified to enable if required. ++\****************************************************************************/ ++ ++int Tunerclock(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 0; ++ status=I2CWriteByte(pTuner, 200,6,writearray[0]); ++ //printf("\nRegister 6=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 150; ++ status=I2CWriteByte(pTuner, 200,122,writearray[0]); ++ //printf("\nRegister 7a=%d", writearray[0]); ++ //**Modify commands above with value required if output clock is required, ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: filtercal ++* ++* Detailed Description: ++* Instructs RC filter calibration. (Register 0x7b). ++* ++\****************************************************************************/ ++/* ++int filtercal(TUNER_MODULE *pTuner) ++{ ++ //writearray[0] = 1; ++ //I2CWriteByte (pTuner, 200,123,writearray[0]); ++ //printf("\nRegister 7b=%d", writearray[0]); ++ //return; ++ return E4000_1_SUCCESS; ++} ++*/ ++/****************************************************************************\ ++* Function: Qpeak() ++* ++* Detailed Description: ++* The function configures the E4000 gains. ++* Also sigma delta controller. (Register 0x82). ++* ++\****************************************************************************/ ++ ++int Qpeak(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 1; ++ writearray[1] = 254; ++ status=I2CWriteArray(pTuner, 200,126,2,writearray); ++ //printf("\nRegister 7e=%d", writearray[0]); ++ //printf("\nRegister 7f=%d", writearray[1]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,130,0); ++ //printf("\nRegister 82=0"); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,36,5); ++ //printf("\nRegister 24=5"); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 32; ++ writearray[1] = 1; ++ status=I2CWriteArray(pTuner, 200,135,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ //printf("\nRegister 87=%d", writearray[0]); ++ //printf("\nRegister 88=%d", writearray[1]); ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: E4000_gain_freq() ++* ++* Detailed Description: ++* The function configures the E4000 gains vs. freq ++* 0xa3 to 0xa7. Also 0x24. ++* ++\****************************************************************************/ ++int E4000_gain_freq(TUNER_MODULE *pTuner, int Freq) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ if (Freq<=350000) ++ { ++ writearray[0] = 0x10; ++ writearray[1] = 0x42; ++ writearray[2] = 0x09; ++ writearray[3] = 0x21; ++ writearray[4] = 0x94; ++ } ++ else if(Freq>=1000000) ++ { ++ writearray[0] = 0x10; ++ writearray[1] = 0x42; ++ writearray[2] = 0x09; ++ writearray[3] = 0x21; ++ writearray[4] = 0x94; ++ } ++ else ++ { ++ writearray[0] = 0x10; ++ writearray[1] = 0x42; ++ writearray[2] = 0x09; ++ writearray[3] = 0x21; ++ writearray[4] = 0x94; ++ } ++ status=I2CWriteArray(pTuner, 200,163,5,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if (Freq<=350000) ++ { ++ writearray[0] = 94; ++ writearray[1] = 6; ++ status=I2CWriteArray(pTuner, 200,159,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteArray(pTuner, 200,136,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else ++ { ++ writearray[0] = 127; ++ writearray[1] = 7; ++ status=I2CWriteArray(pTuner, 200,159,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 1; ++ status=I2CWriteArray(pTuner, 200,136,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ ++ //printf("\nRegister 9f=%d", writearray[0]); ++ //printf("\nRegister a0=%d", writearray[1]); ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: DCoffloop ++* ++* Detailed Description: ++* Populates DC offset LUT. (Registers 0x2d, 0x70, 0x71). ++* Turns on DC offset LUT and time varying DC offset. ++\****************************************************************************/ ++int DCoffloop(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ //writearray[0]=0; ++ //I2CWriteByte(pTuner, 200,115,writearray[0]); ++ //printf("\nRegister 73=%d", writearray[0]); ++ writearray[0] = 31; ++ status=I2CWriteByte(pTuner, 200,45,writearray[0]); ++ //printf("\nRegister 2d=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 1; ++ writearray[1] = 1; ++ status=I2CWriteArray(pTuner, 200,112,2,writearray); ++ //printf("\nRegister 70=%d", writearray[0]); ++ //printf("\nRegister 71=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: commonmode ++* ++* Detailed Description: ++* Configures common mode voltage. (Registers 0x2f). ++* ++\****************************************************************************/ ++/* ++int commonmode(TUNER_MODULE *pTuner) ++{ ++ //writearray[0] = 0; ++ //I2CWriteByte(Device_address,47,writearray[0]); ++ //printf("\nRegister 0x2fh = %d", writearray[0]); ++ // Sets 550mV. Modify if alternative is desired. ++ return E4000_1_SUCCESS; ++} ++*/ ++/****************************************************************************\ ++* Function: GainControlinit ++* ++* Detailed Description: ++* Configures gain control mode. (Registers 0x1d, 0x1e, 0x1f, 0x20, 0x21, ++* 0x1a, 0x74h, 0x75h). ++* User may wish to modify values depending on usage scenario. ++* Routine configures LNA: autonomous gain control ++* IF PWM gain control. ++* PWM thresholds = default ++* Mixer: switches when LNA gain =7.5dB ++* Sensitivity / Linearity mode: manual switch ++* ++\****************************************************************************/ ++int GainControlinit(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ unsigned char read1[1]; ++ int status; ++ ++ unsigned char sum=255; ++ ++ writearray[0] = 23; ++ status=I2CWriteByte(pTuner, 200,26,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ //printf("\nRegister 1a=%d", writearray[0]); ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 16; ++ writearray[1] = 4; ++ writearray[2] = 26; ++ writearray[3] = 15; ++ writearray[4] = 167; ++ status=I2CWriteArray(pTuner, 200,29,5,writearray); ++ //printf("\nRegister 1d=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 81; ++ status=I2CWriteByte(pTuner, 200,134,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ //printf("\nRegister 86=%d", writearray[0]); ++ ++ //For Realtek - gain control logic ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0]<=sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0] <= sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0] <= sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0] <= sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if (read1[0]<=sum) ++ { ++ sum=read1[0]; ++ } ++ ++ writearray[0]=sum; ++ status=I2CWriteByte(pTuner, 200,27,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ //printf("\nRegister 1b=%d", writearray[0]); ++ //printf("\nRegister 1e=%d", writearray[1]); ++ //printf("\nRegister 1f=%d", writearray[2]); ++ //printf("\nRegister 20=%d", writearray[3]); ++ //printf("\nRegister 21=%d", writearray[4]); ++ //writearray[0] = 3; ++ //writearray[1] = 252; ++ //writearray[2] = 3; ++ //writearray[3] = 252; ++ //I2CWriteArray(pTuner, 200,116,4,writearray); ++ //printf("\nRegister 74=%d", writearray[0]); ++ //printf("\nRegister 75=%d", writearray[1]); ++ //printf("\nRegister 76=%d", writearray[2]); ++ //printf("\nRegister 77=%d", writearray[3]); ++ ++ return E4000_1_SUCCESS; ++} ++ ++/****************************************************************************\ ++* Main program ++* ++* ++* ++\****************************************************************************/ ++/* ++int main() ++{ ++ tunerreset (); ++ Tunerclock(); ++ //filtercal(); ++ Qpeak(); ++ //PLL(Ref_clk, Freq); ++ //LNAfilter(Freq); ++ //IFfilter(bandwidth, Ref_clk); ++ //freqband(Freq); ++ //DCoffLUT(); ++ DCoffloop(); ++ //commonmode(); ++ GainControlinit(); ++// system("PAUSE"); ++ return(0); ++} ++*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Elonics source code - frequency_change_rev2.04_realtek.c ++ ++ ++//****************************************************************************\ ++// ++// Filename E4000_freqchangerev2.04.c ++// Revision 2.04 ++// ++// Description: ++// Frequency change script for the Elonics E4000 revB tuner ++// ++// Copyright (c) Elonics Ltd ++// ++// Any software supplied free of charge for use with elonics ++// evaluation kits is supplied without warranty and for ++// evaluation purposes only. Incorporation of any of this ++// code into products for open sale is permitted but only at ++// the user's own risk. Elonics accepts no liability for the ++// integrity of this software whatsoever. ++// ++// ++//****************************************************************************/ ++//#include ++//#include ++// ++// User defined variable definitions ++// ++/* ++int Ref_clk = 20000; // Reference clock frequency(kHz). ++int Freq = 590000; // RF Frequency (kHz) ++int bandwidth = 8; //RF channel bandwith (MHz) ++*/ ++// ++// API defined variable definitions ++//int VCO_freq; ++//unsigned char writearray[5]; ++//unsigned char read1[1]; ++//int E4000_1_SUCCESS; ++//int E4000_1_FAIL; ++//int E4000_I2C_SUCCESS; ++//int status; ++// ++// ++// function definitions ++// ++/* ++int Gainmanual(); ++int PLL(int Ref_clk, int Freq); ++int LNAfilter(int Freq); ++int IFfilter(int bandwidth, int Ref_clk); ++int freqband(int Freq); ++int DCoffLUT(); ++int GainControlauto(); ++*/ ++// ++//**************************************************************************** ++// --- Public functions ------------------------------------------------------ ++/****************************************************************************\ ++//****************************************************************************\ ++* Function: Gainmanual ++* ++* Detailed Description: ++* Sets Gain control to serial interface control. ++* ++\****************************************************************************/ ++int Gainmanual(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0]=0; ++ status=I2CWriteByte(pTuner, 200,26,writearray[0]); ++ //printf("\nRegister 1a=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,9,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,5,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++ ++/****************************************************************************\ ++* Function: PLL ++* ++* Detailed Description: ++* Configures E4000 PLL divider & sigma delta. 0x0d,0x09, 0x0a, 0x0b). ++* ++\****************************************************************************/ ++int PLL(TUNER_MODULE *pTuner, int Ref_clk, int Freq) ++{ ++ int VCO_freq; ++ unsigned char writearray[5]; ++ int status; ++ ++ unsigned char divider; ++ int intVCOfreq; ++ int SigDel; ++ int SigDel2; ++ int SigDel3; ++// int harmonic_freq; ++// int offset; ++ ++ if (Freq<=72400) ++ { ++ writearray[4] = 15; ++ VCO_freq=Freq*48; ++ } ++ else if (Freq<=81200) ++ { ++ writearray[4] = 14; ++ VCO_freq=Freq*40; ++ } ++ else if (Freq<=108300) ++ { ++ writearray[4]=13; ++ VCO_freq=Freq*32; ++ } ++ else if (Freq<=162500) ++ { ++ writearray[4]=12; ++ VCO_freq=Freq*24; ++ } ++ else if (Freq<=216600) ++ { ++ writearray[4]=11; ++ VCO_freq=Freq*16; ++ } ++ else if (Freq<=325000) ++ { ++ writearray[4]=10; ++ VCO_freq=Freq*12; ++ } ++ else if (Freq<=350000) ++ { ++ writearray[4]=9; ++ VCO_freq=Freq*8; ++ } ++ else if (Freq<=432000) ++ { ++ writearray[4]=3; ++ VCO_freq=Freq*8; ++ } ++ else if (Freq<=667000) ++ { ++ writearray[4]=2; ++ VCO_freq=Freq*6; ++ } ++ else if (Freq<=1200000) ++ { ++ writearray[4]=1; ++ VCO_freq=Freq*4; ++ } ++ else ++ { ++ writearray[4]=0; ++ VCO_freq=Freq*2; ++ } ++ ++ //printf("\nVCOfreq=%d", VCO_freq); ++// divider = VCO_freq * 1000 / Ref_clk; ++ divider = VCO_freq / Ref_clk; ++ //printf("\ndivider=%d", divider); ++ writearray[0]= divider; ++// intVCOfreq = divider * Ref_clk /1000; ++ intVCOfreq = divider * Ref_clk; ++ //printf("\ninteger VCO freq=%d", intVCOfreq); ++// SigDel=65536 * 1000 * (VCO_freq - intVCOfreq) / Ref_clk; ++ SigDel=65536 * (VCO_freq - intVCOfreq) / Ref_clk; ++ //printf("\nSigma delta=%d", SigDel); ++ if (SigDel<=1024) ++ { ++ SigDel = 1024; ++ } ++ else if (SigDel>=64512) ++ { ++ SigDel=64512; ++ } ++ SigDel2 = SigDel / 256; ++ //printf("\nSigdel2=%d", SigDel2); ++ writearray[2] = (unsigned char)SigDel2; ++ SigDel3 = SigDel - (256 * SigDel2); ++ //printf("\nSig del3=%d", SigDel3); ++ writearray[1]= (unsigned char)SigDel3; ++ writearray[3]=(unsigned char)0; ++ status=I2CWriteArray(pTuner, 200,9,5,writearray); ++ //printf("\nRegister 9=%d", writearray[0]); ++ //printf("\nRegister a=%d", writearray[1]); ++ //printf("\nRegister b=%d", writearray[2]); ++ //printf("\nRegister d=%d", writearray[4]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if (Freq<=82900) ++ { ++ writearray[0]=0; ++ writearray[2]=1; ++ } ++ else if (Freq<=89900) ++ { ++ writearray[0]=3; ++ writearray[2]=9; ++ } ++ else if (Freq<=111700) ++ { ++ writearray[0]=0; ++ writearray[2]=1; ++ } ++ else if (Freq<=118700) ++ { ++ writearray[0]=3; ++ writearray[2]=1; ++ } ++ else if (Freq<=140500) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=147500) ++ { ++ writearray[0]=3; ++ writearray[2]=11; ++ } ++ else if (Freq<=169300) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=176300) ++ { ++ writearray[0]=3; ++ writearray[2]=11; ++ } ++ else if (Freq<=198100) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=205100) ++ { ++ writearray[0]=3; ++ writearray[2]=19; ++ } ++ else if (Freq<=226900) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=233900) ++ { ++ writearray[0]=3; ++ writearray[2]=3; ++ } ++ else if (Freq<=350000) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=485600) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=493600) ++ { ++ writearray[0]=3; ++ writearray[2]=5; ++ } ++ else if (Freq<=514400) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=522400) ++ { ++ writearray[0]=3; ++ writearray[2]=5; ++ } ++ else if (Freq<=543200) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=551200) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=572000) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=580000) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=600800) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=608800) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=629600) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=637600) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=658400) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=666400) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=687200) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=695200) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=716000) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=724000) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=744800) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=752800) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=773600) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=781600) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=802400) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=810400) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=831200) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=839200) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=860000) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=868000) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else ++ { ++ writearray[0]=0; ++ writearray[2]=7; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,7,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,5,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++ ++/****************************************************************************\ ++* Function: LNAfilter ++* ++* Detailed Description: ++* The function configures the E4000 LNA filter. (Register 0x10). ++* ++\****************************************************************************/ ++ ++int LNAfilter(TUNER_MODULE *pTuner, int Freq) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ if(Freq<=370000) ++ { ++ writearray[0]=0; ++ } ++ else if(Freq<=392500) ++ { ++ writearray[0]=1; ++ } ++ else if(Freq<=415000) ++ { ++ writearray[0] =2; ++ } ++ else if(Freq<=437500) ++ { ++ writearray[0]=3; ++ } ++ else if(Freq<=462500) ++ { ++ writearray[0]=4; ++ } ++ else if(Freq<=490000) ++ { ++ writearray[0]=5; ++ } ++ else if(Freq<=522500) ++ { ++ writearray[0]=6; ++ } ++ else if(Freq<=557500) ++ { ++ writearray[0]=7; ++ } ++ else if(Freq<=595000) ++ { ++ writearray[0]=8; ++ } ++ else if(Freq<=642500) ++ { ++ writearray[0]=9; ++ } ++ else if(Freq<=695000) ++ { ++ writearray[0]=10; ++ } ++ else if(Freq<=740000) ++ { ++ writearray[0]=11; ++ } ++ else if(Freq<=800000) ++ { ++ writearray[0]=12; ++ } ++ else if(Freq<=865000) ++ { ++ writearray[0] =13; ++ } ++ else if(Freq<=930000) ++ { ++ writearray[0]=14; ++ } ++ else if(Freq<=1000000) ++ { ++ writearray[0]=15; ++ } ++ else if(Freq<=1310000) ++ { ++ writearray[0]=0; ++ } ++ else if(Freq<=1340000) ++ { ++ writearray[0]=1; ++ } ++ else if(Freq<=1385000) ++ { ++ writearray[0]=2; ++ } ++ else if(Freq<=1427500) ++ { ++ writearray[0]=3; ++ } ++ else if(Freq<=1452500) ++ { ++ writearray[0]=4; ++ } ++ else if(Freq<=1475000) ++ { ++ writearray[0]=5; ++ } ++ else if(Freq<=1510000) ++ { ++ writearray[0]=6; ++ } ++ else if(Freq<=1545000) ++ { ++ writearray[0]=7; ++ } ++ else if(Freq<=1575000) ++ { ++ writearray[0] =8; ++ } ++ else if(Freq<=1615000) ++ { ++ writearray[0]=9; ++ } ++ else if(Freq<=1650000) ++ { ++ writearray[0] =10; ++ } ++ else if(Freq<=1670000) ++ { ++ writearray[0]=11; ++ } ++ else if(Freq<=1690000) ++ { ++ writearray[0]=12; ++ } ++ else if(Freq<=1710000) ++ { ++ writearray[0]=13; ++ } ++ else if(Freq<=1735000) ++ { ++ writearray[0]=14; ++ } ++ else ++ { ++ writearray[0]=15; ++ } ++ status=I2CWriteByte (pTuner, 200,16,writearray[0]); ++ //printf("\nRegister 10=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: IFfilter ++* ++* Detailed Description: ++* The function configures the E4000 IF filter. (Register 0x11,0x12). ++* ++\****************************************************************************/ ++int IFfilter(TUNER_MODULE *pTuner, int bandwidth, int Ref_clk) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ int IF_BW; ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2150) ++ { ++ writearray[0]=253; ++ writearray[1]=31; ++ } ++ else if(IF_BW<=2200) ++ { ++ writearray[0]=253; ++ writearray[1]=30; ++ } ++ else if(IF_BW<=2240) ++ { ++ writearray[0]=252; ++ writearray[1]=29; ++ } ++ else if(IF_BW<=2280) ++ { ++ writearray[0]=252; ++ writearray[1]=28; ++ } ++ else if(IF_BW<=2300) ++ { ++ writearray[0]=252; ++ writearray[1]=27; ++ } ++ else if(IF_BW<=2400) ++ { ++ writearray[0]=252; ++ writearray[1]=26; ++ } ++ else if(IF_BW<=2450) ++ { ++ writearray[0]=252; ++ writearray[1]=25; ++ } ++ else if(IF_BW<=2500) ++ { ++ writearray[0]=252; ++ writearray[1]=24; ++ } ++ else if(IF_BW<=2550) ++ { ++ writearray[0]=252; ++ writearray[1]=23; ++ } ++ else if(IF_BW<=2600) ++ { ++ writearray[0]=252; ++ writearray[1]=22; ++ } ++ else if(IF_BW<=2700) ++ { ++ writearray[0]=252; ++ writearray[1]=21; ++ } ++ else if(IF_BW<=2750) ++ { ++ writearray[0]=252; ++ writearray[1]=20; ++ } ++ else if(IF_BW<=2800) ++ { ++ writearray[0]=252; ++ writearray[1]=19; ++ } ++ else if(IF_BW<=2900) ++ { ++ writearray[0]=251; ++ writearray[1]=18; ++ } ++ else if(IF_BW<=2950) ++ { ++ writearray[0]=251; ++ writearray[1]=17; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=251; ++ writearray[1]=16; ++ } ++ else if(IF_BW<=3100) ++ { ++ writearray[0]=251; ++ writearray[1]=15; ++ } ++ else if(IF_BW<=3200) ++ { ++ writearray[0]=250; ++ writearray[1]=14; ++ } ++ else if(IF_BW<=3300) ++ { ++ writearray[0]=250; ++ writearray[1]=13; ++ } ++ else if(IF_BW<=3400) ++ { ++ writearray[0]=249; ++ writearray[1]=12; ++ } ++ else if(IF_BW<=3600) ++ { ++ writearray[0]=249; ++ writearray[1]=11; ++ } ++ else if(IF_BW<=3700) ++ { ++ writearray[0]=249; ++ writearray[1]=10; ++ } ++ else if(IF_BW<=3800) ++ { ++ writearray[0]=248; ++ writearray[1]=9; ++ } ++ else if(IF_BW<=3900) ++ { ++ writearray[0]=248; ++ writearray[1]=8; ++ } ++ else if(IF_BW<=4100) ++ { ++ writearray[0]=248; ++ writearray[1]=7; ++ } ++ else if(IF_BW<=4300) ++ { ++ writearray[0]=247; ++ writearray[1]=6; ++ } ++ else if(IF_BW<=4400) ++ { ++ writearray[0]=247; ++ writearray[1]=5; ++ } ++ else if(IF_BW<=4600) ++ { ++ writearray[0]=247; ++ writearray[1]=4; ++ } ++ else if(IF_BW<=4800) ++ { ++ writearray[0]=246; ++ writearray[1]=3; ++ } ++ else if(IF_BW<=5000) ++ { ++ writearray[0]=246; ++ writearray[1]=2; ++ } ++ else if(IF_BW<=5300) ++ { ++ writearray[0]=245; ++ writearray[1]=1; ++ } ++ else if(IF_BW<=5500) ++ { ++ writearray[0]=245; ++ writearray[1]=0; ++ } ++ else ++ { ++ writearray[0]=0; ++ writearray[1]=32; ++ } ++ status=I2CWriteArray(pTuner, 200,17,2,writearray); ++ //printf("\nRegister 11=%d", writearray[0]); ++ //printf("\nRegister 12=%d", writearray[1]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: freqband ++* ++* Detailed Description: ++* Configures the E4000 frequency band. (Registers 0x07, 0x78). ++* ++\****************************************************************************/ ++int freqband(TUNER_MODULE *pTuner, int Freq) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ if (Freq<=140000) ++ { ++ writearray[0] = 3; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else if (Freq<=350000) ++ { ++ writearray[0] = 3; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else if (Freq<=1000000) ++ { ++ writearray[0] = 3; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else ++ { ++ writearray[0] = 7; ++ status=I2CWriteByte(pTuner, 200,7,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: DCoffLUT ++* ++* Detailed Description: ++* Populates DC offset LUT. (Registers 0x50 - 0x53, 0x60 - 0x63). ++* ++\****************************************************************************/ ++int DCoffLUT(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ unsigned char read1[1]; ++ unsigned char IOFF; ++ unsigned char QOFF; ++ unsigned char RANGE1; ++// unsigned char RANGE2; ++ unsigned char QRANGE; ++ unsigned char IRANGE; ++ writearray[0] = 0; ++ writearray[1] = 126; ++ writearray[2] = 36; ++ status=I2CWriteArray(pTuner, 200,21,3,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 00 and IF stg 2+ to max gain. ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ QOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ RANGE1=read1[0]; ++ //reads DC offset values back ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE=RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ ++ writearray[0] = (IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,96,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,80,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Populate DC offset LUT ++ writearray[0] = 0; ++ writearray[1] = 127; ++ status=I2CWriteArray(pTuner, 200,21,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 01 leaving IF stg 2+ at max gain. ++ writearray[0]= 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ QOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ RANGE1=read1[0]; ++ // Read DC offset values ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE = RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ ++ writearray[0] = (IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,97,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,81,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Populate DC offset LUT ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,21,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 11 leaving IF stg 2+ at max gain. ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ QOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ RANGE1 = read1[0]; ++ // Read DC offset values ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE = RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ writearray[0] = (IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,99,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,83,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Populate DC offset LUT ++ writearray[0] = 126; ++ status=I2CWriteByte(pTuner, 200,22,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 11 leaving IF stg 2+ at max gain. ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ IOFF=read1[0]; ++ ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ QOFF=read1[0]; ++ ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ RANGE1=read1[0]; ++ ++ // Read DC offset values ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE = RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ ++ writearray[0]=(IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,98,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,82,writearray[0]); ++ // Populate DC offset LUT ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: GainControlinit ++* ++* Detailed Description: ++* Configures gain control mode. (Registers 0x1a) ++* ++\****************************************************************************/ ++int GainControlauto(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 23; ++ status=I2CWriteByte(pTuner, 200,26,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Main program ++* ++* ++* ++\****************************************************************************/ ++/* ++int main() ++{ ++ Gainmanual(); ++ PLL(Ref_clk, Freq); ++ LNAfilter(Freq); ++ IFfilter(bandwidth, Ref_clk); ++ freqband(Freq); ++ DCoffLUT(); ++ GainControlauto(); ++ return(0); ++} ++*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Elonics source code - RT2832_SW_optimisation_rev2.c ++ ++ ++ ++/****************************************************************************\ ++* Function: E4000_sensitivity ++* ++* Detailed Description: ++* The function configures the E4000 for sensitivity mode. ++* ++\****************************************************************************/ ++ ++int E4000_sensitivity(TUNER_MODULE *pTuner, int Freq, int bandwidth) ++{ ++ unsigned char writearray[2]; ++ int status; ++ int IF_BW; ++ ++ if(Freq<=700000) ++ { ++ writearray[0] = 0x07; ++ } ++ else ++ { ++ writearray[0] = 0x05; ++ } ++ status = I2CWriteArray(pTuner,200,36,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2500) ++ { ++ writearray[0]=0xfc; ++ writearray[1]=0x17; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=0xfb; ++ writearray[1]=0x0f; ++ } ++ else if(IF_BW<=3500) ++ { ++ writearray[0]=0xf9; ++ writearray[1]=0x0b; ++ } ++ else if(IF_BW<=4000) ++ { ++ writearray[0]=0xf8; ++ writearray[1]=0x07; ++ } ++ status = I2CWriteArray(pTuner,200,17,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: E4000_linearity ++* ++* Detailed Description: ++* The function configures the E4000 for linearity mode. ++* ++\****************************************************************************/ ++int E4000_linearity(TUNER_MODULE *pTuner, int Freq, int bandwidth) ++{ ++ ++ unsigned char writearray[2]; ++ int status; ++ int IF_BW; ++ ++ if(Freq<=700000) ++ { ++ writearray[0] = 0x03; ++ } ++ else ++ { ++ writearray[0] = 0x01; ++ } ++ status = I2CWriteArray(pTuner,200,36,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2500) ++ { ++ writearray[0]=0xfe; ++ writearray[1]=0x19; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=0xfd; ++ writearray[1]=0x11; ++ } ++ else if(IF_BW<=3500) ++ { ++ writearray[0]=0xfb; ++ writearray[1]=0x0d; ++ } ++ else if(IF_BW<=4000) ++ { ++ writearray[0]=0xfa; ++ writearray[1]=0x0a; ++ } ++ status = I2CWriteArray(pTuner,200,17,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: E4000_nominal ++* ++* Detailed Description: ++* The function configures the E4000 for nominal ++* ++\****************************************************************************/ ++int E4000_nominal(TUNER_MODULE *pTuner, int Freq, int bandwidth) ++{ ++ unsigned char writearray[2]; ++ int status; ++ int IF_BW; ++ ++ if(Freq<=700000) ++ { ++ writearray[0] = 0x03; ++ } ++ else ++ { ++ writearray[0] = 0x01; ++ } ++ status = I2CWriteArray(pTuner,200,36,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2500) ++ { ++ writearray[0]=0xfc; ++ writearray[1]=0x17; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=0xfb; ++ writearray[1]=0x0f; ++ } ++ else if(IF_BW<=3500) ++ { ++ writearray[0]=0xf9; ++ writearray[1]=0x0b; ++ } ++ else if(IF_BW<=4000) ++ { ++ writearray[0]=0xf8; ++ writearray[1]=0x07; ++ } ++ status = I2CWriteArray(pTuner,200,17,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_e4000.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_e4000.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_e4000.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_e4000.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,295 @@ ++#ifndef __TUNER_E4000_H ++#define __TUNER_E4000_H ++ ++/** ++ ++@file ++ ++@brief E4000 tuner module declaration ++ ++One can manipulate E4000 tuner through E4000 module. ++E4000 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_e4000.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ E4000_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build E4000 tuner module. ++ BuildE4000Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xac, // I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // Crystal frequency is 16.384 MHz. ++ E4000_AGC_INTERNAL // The E4000 AGC mode is internal AGC mode. ++ ); ++ ++ ++ ++ ++ ++ // Get E4000 tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set E4000 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, E4000_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get E4000 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is implemented for E4000 source code. ++ ++ ++// Definition (implemeted for E4000) ++#define E4000_1_SUCCESS 1 ++#define E4000_1_FAIL 0 ++#define E4000_I2C_SUCCESS 1 ++#define E4000_I2C_FAIL 0 ++ ++ ++ ++// Function (implemeted for E4000) ++int ++I2CReadByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++int ++I2CWriteByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char WritingByte ++ ); ++ ++int ++I2CWriteArray( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegStartAddr, ++ unsigned char ByteNum, ++ unsigned char *pWritingBytes ++ ); ++ ++ ++ ++// Functions (from E4000 source code) ++int tunerreset (TUNER_MODULE *pTuner); ++int Tunerclock(TUNER_MODULE *pTuner); ++int Qpeak(TUNER_MODULE *pTuner); ++int DCoffloop(TUNER_MODULE *pTuner); ++int GainControlinit(TUNER_MODULE *pTuner); ++ ++int Gainmanual(TUNER_MODULE *pTuner); ++int E4000_gain_freq(TUNER_MODULE *pTuner, int frequency); ++int PLL(TUNER_MODULE *pTuner, int Ref_clk, int Freq); ++int LNAfilter(TUNER_MODULE *pTuner, int Freq); ++int IFfilter(TUNER_MODULE *pTuner, int bandwidth, int Ref_clk); ++int freqband(TUNER_MODULE *pTuner, int Freq); ++int DCoffLUT(TUNER_MODULE *pTuner); ++int GainControlauto(TUNER_MODULE *pTuner); ++ ++int E4000_sensitivity(TUNER_MODULE *pTuner, int Freq, int bandwidth); ++int E4000_linearity(TUNER_MODULE *pTuner, int Freq, int bandwidth); ++int E4000_high_linearity(TUNER_MODULE *pTuner); ++int E4000_nominal(TUNER_MODULE *pTuner, int Freq, int bandwidth); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is E4000 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Bandwidth in Hz ++enum E4000_BANDWIDTH_HZ ++{ ++ E4000_BANDWIDTH_6000000HZ = 6000000, ++ E4000_BANDWIDTH_7000000HZ = 7000000, ++ E4000_BANDWIDTH_8000000HZ = 8000000, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildE4000Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++e4000_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++e4000_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++e4000_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++e4000_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++e4000_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++e4000_GetRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++int ++e4000_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++int ++e4000_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc0012.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc0012.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc0012.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc0012.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,1055 @@ ++/** ++ ++@file ++ ++@brief FC0012 tuner module definition ++ ++One can manipulate FC0012 tuner through FC0012 module. ++FC0012 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_fc0012.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief FC0012 tuner module builder ++ ++Use BuildFc0012Module() to build FC0012 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to FC0012 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr FC0012 I2C device address ++@param [in] CrystalFreqHz FC0012 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildFc0012Module() to build FC0012 module before using it. ++ ++*/ ++void ++BuildFc0012Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_FC0012; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = fc0012_GetTunerType; ++ pTuner->GetDeviceAddr = fc0012_GetDeviceAddr; ++ ++ pTuner->Initialize = fc0012_Initialize; ++ pTuner->SetRfFreqHz = fc0012_SetRfFreqHz; ++ pTuner->GetRfFreqHz = fc0012_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = fc0012_SetBandwidthMode; ++ pExtra->GetBandwidthMode = fc0012_GetBandwidthMode; ++ ++ ++ // Set tuner RF frequency and tuner bandwidth mode. ++ // Note: Need to give default tuner RF frequency and tuner bandwidth mode, ++ // because FC0012 API use one funnction to set RF frequency and bandwidth mode. ++ pTuner->RfFreqHz = FC0012_RF_FREQ_HZ_DEFAULT; ++ pExtra->BandwidthMode = FC0012_BANDWIDTH_MODE_DEFAULT; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++fc0012_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++fc0012_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++fc0012_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Initialize tuner. ++ if(FC0012_Open(pTuner) != FC0012_FUNCTION_SUCCESS) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++fc0012_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ unsigned long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Set tuner RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (RfFreqHz + 500) / 1000; ++ ++ if(FC0011_SetFrequency(pTuner, RfFreqKhz, (unsigned short)(pExtra->BandwidthMode)) != FC0012_FUNCTION_SUCCESS) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++fc0012_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set FC0012 tuner bandwidth mode. ++ ++*/ ++int ++fc0012_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ unsigned long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Set tuner bandwidth mode. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (pTuner->RfFreqHz + 500) / 1000; ++ ++ if(FC0011_SetFrequency(pTuner, RfFreqKhz, (unsigned short)BandwidthMode) != FC0012_FUNCTION_SUCCESS) ++ goto error_status_set_tuner_bandwidth_mode; ++ ++ ++ // Set tuner bandwidth mode parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get FC0012 tuner bandwidth mode. ++ ++*/ ++int ++fc0012_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is implemented for FC0012 source code. ++ ++ ++// Read FC0012 register. ++int FC0012_Read(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char *pByte) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, pByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return FC0012_I2C_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return FC0012_I2C_ERROR; ++} ++ ++ ++ ++ ++ ++// Write FC0012 register. ++int FC0012_Write(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char Byte) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = RegAddr; ++ WritingBuffer[1] = Byte; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FC0012_I2C_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return FC0012_I2C_ERROR; ++} ++ ++ ++ ++ ++ ++// Set FC0012 register mask bits. ++int ++fc0012_SetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingByte; ++ unsigned char WritingByte; ++ ++ unsigned char Mask; ++ unsigned char Shift; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get tuner register byte according to register adddress. ++ if(FC0012_Read(pTuner, RegAddr, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ // Reserve byte unmask bit with mask and inlay writing value into it. ++ WritingByte = ReadingByte & (~Mask); ++ WritingByte |= (WritingValue << Shift) & Mask; ++ ++ ++ // Write tuner register byte with writing byte. ++ if(FC0012_Write(pTuner, RegAddr, WritingByte) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Get FC0012 register mask bits. ++int ++fc0012_GetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned char *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingByte; ++ ++ unsigned char Mask; ++ unsigned char Shift; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get tuner register byte according to register adddress. ++ if(FC0012_Read(pTuner, RegAddr, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ // Get register bits from reading byte with mask and shift ++ *pReadingValue = (ReadingByte & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by fitipower. ++ ++ ++ ++ ++ ++// fitipower source code - FC0012_Tuner_Code.cpp ++ ++ ++//=========================================================== ++// Fitipower Integrated Technology Inc. ++// ++// FC0012 Tuner Code ++// ++// Version 1.2e ++// ++// Date: 2009/09/15 ++// ++// Copyright 2008, All rights reversed. ++// ++// Compile in Visual Studio 2005 C++ Win32 Console ++// ++//--------------------------------------------------------------------- ++// Modify History: ++// 2009-05-11: Change to recieve 28.8 MHz clock ++// 2009-05-14: fix frequency lock problem on 111MHz~148MHz ++// 2009-05-15: remove the limitation of Xin range ++// 2009-07-30: Add VHF filter control ++// Add VHF frequency offset ++// Add reference RSSI function ++// Change register[0x07] to 0x20 ++// 2009-09-15: update VCO re-calibration function ++//--------------------------------------------------------------------- ++//===================================================================== ++ ++// Data Format: ++// BYTE: unsigned char, 1 byte, 8 bits ++// WORD: unsighed short, 2 bytes, 16 bits ++// DWORD: unsigned int, 4 bytes, 32 bits ++ ++// include header, just for testing. ++//#include "stdafx.h" ++//#include "stdlib.h" ++//#include ++ ++//void FC0012_Write(unsigned char address, unsigned char data); ++//unsigned char FC0012_Read(unsigned char address); ++//void FC0012_Open(); ++//void FC0012_Close(); ++//void FC0012_SetFrequency(unsigned int Frequency, unsigned short Bandwidth); ++ ++/* ++// Console main function, just for testing ++int main(int argc, const char* argv[]) ++{ ++ printf("\n"); ++ ++ if ( argc > 1 ) ++ { ++ for( int i = 1; i < argc; i++ ) ++ { ++ FC0012_SetFrequency( atoi(argv[i]), 6); ++ } ++ } ++ ++ return 0; ++} ++ ++// FC0012 I2C Write Function ++void FC0012_Write(unsigned char address, unsigned char data) ++{ ++ // depend on driver function in demodulator vendor. ++} ++ ++// FC0012 I2C Read Function ++unsigned char FC0012_Read(unsigned char address) ++{ ++ // depend on driver function in demodulator vendor. ++ unsigned char value = 0; ++ // value = ........ ++ return value; ++} ++*/ ++ ++// FC0012 Open Function, includes enable/reset pin control and registers initialization. ++int FC0012_Open(TUNER_MODULE *pTuner) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Enable FC0012 Power ++// (...) ++ // FC0012 Enable = High ++// (...) ++ // FC0012 Reset = High -> Low ++// (...) ++ ++ //================================ Initial FC0012 Tuner Register ++ if(FC0012_Write(pTuner, 0x01, 0x05) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x02, 0x10) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x03, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x04, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR test ++ if(FC0012_Write(pTuner, 0x05, 0x0F) != FC0012_I2C_SUCCESS) goto error_status; ++ //===================================== Arios Modify - 2009-10-23 ++ ++ ++ if(FC0012_Write(pTuner, 0x06, 0x00) != FC0012_I2C_SUCCESS) goto error_status; // divider 2, VCO slow. ++ ++ switch(pExtra->CrystalFreqHz) // Gain Shift: 15 // Set bit 5 to 1 for 28.8 MHz clock input (2009/05/12) ++ { ++ default: ++ case CRYSTAL_FREQ_28800000HZ: ++ ++ if(FC0012_Write(pTuner, 0x07, 0x20) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ break; ++ ++ ++ case CRYSTAL_FREQ_27000000HZ: ++ ++ if(FC0012_Write(pTuner, 0x07, 0x20) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ break; ++ ++ ++ case CRYSTAL_FREQ_36000000HZ: ++ ++ if(FC0012_Write(pTuner, 0x07, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ break; ++ } ++ ++ if(FC0012_Write(pTuner, 0x08, 0xFF) != FC0012_I2C_SUCCESS) goto error_status; // AGC Clock divide by 256, AGC gain 1/256, Loop Bw 1/8 ++ if(FC0012_Write(pTuner, 0x09, 0x6E) != FC0012_I2C_SUCCESS) goto error_status; // Disable LoopThrough ++ if(FC0012_Write(pTuner, 0x0A, 0xB8) != FC0012_I2C_SUCCESS) goto error_status; // Disable LO Test Buffer ++ if(FC0012_Write(pTuner, 0x0B, 0x82) != FC0012_I2C_SUCCESS) goto error_status; // Output Clock is same as clock frequency ++ ++ //-------------------------------------------------------------------------- ++ // reg[12] need to be changed if the system is in AGC Up-Down mode ++ //-------------------------------------------------------------------------- ++// if(FC0012_Write(pTuner, 0x0C, 0xF8) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ // Modified for up-dowm AGC by Realtek. ++ if(FC0012_Write(pTuner, 0x0C, 0xFC) != FC0012_I2C_SUCCESS) goto error_status; ++ ++// if(FC0012_Write(pTuner, 0x0D, 0x02) != FC0012_I2C_SUCCESS) goto error_status; // AGC Not Forcing & LNA Forcing ++ ++ // Modified for 2836B DTMB by Realtek. ++ if(FC0012_Write(pTuner, 0x0D, 0x06) != FC0012_I2C_SUCCESS) goto error_status; // AGC Not Forcing & LNA Forcing ++ ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0F, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x10, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x11, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x12, 0x1F) != FC0012_I2C_SUCCESS) goto error_status; // Set to maximum gain ++ ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR test ++// if(FC0012_Write(pTuner, 0x13, 0x10) != FC0012_I2C_SUCCESS) goto error_status; // Enable IX2, Set to High Gain ++ if(FC0012_Write(pTuner, 0x13, 0x08) != FC0012_I2C_SUCCESS) goto error_status; // Enable IX2, Set to Middle Gain ++// if(FC0012_Write(pTuner, 0x13, 0x00) != FC0012_I2C_SUCCESS) goto error_status; // Enable IX2, Set to Low Gain ++ //===================================== Arios Modify - 2009-10-23 ++ ++ if(FC0012_Write(pTuner, 0x14, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x15, 0x04) != FC0012_I2C_SUCCESS) goto error_status; // Enable LNA COMPS ++ ++ return FC0012_FUNCTION_SUCCESS; ++ ++error_status: ++ return FC0012_FUNCTION_ERROR; ++} ++ ++ ++/* ++// FC0012 Close Function, control enable/reset and power. ++void FC0012_Close() ++{ ++ // FC0012 Enable = Low ++ // (...) ++ // FC0012 Reset = Low -> High ++ // (...) ++ // Disable FC0012 Power ++ // (...) ++} ++ ++void Delay(unsigned int) ++{ ++ // delay function ++} ++ ++ ++//===================================== RSSI & LNA Control 2009/07/30 ++// better ACI Performance for D-Book & field-test ++void FC0012_RSSI() ++{ ++ unsigned char Input_Power; ++ ++ Delay(200); // Delay 200 ms ++ ++ ++ switch( FC0012_Read(0x13) ) // Read FC0012 LNA gain setting ++ { ++ case 0x10: // High gain 19.7 dB ++ if( Input_Power > -40 ) // if intput power level is bigger than -40 dBm ++ FC0012_Write(0x13, 0x17); // Switch to 17.9 dB ++ break; ++ ++ case 0x17: // High gain 17.9 dB ++ if( Input_Power > -15 ) // if intput power level is bigger than -15 dBm ++ FC0012_Write(0x13, 0x08); // Switch to 7.1 dB ++ else if( Input_Power < -45 ) // if intput power level is smaller than -45 dBm ++ FC0012_Write(0x13, 0x10); // Switch to 19.7 dB ++ break; ++ ++ case 0x08: // Middle gain 7.1 dB ++ if( Input_Power > -5 ) // if intput power level is bigger than -5 dBm ++ FC0012_Write(0x13, 0x02); // Switch to -9.9 dB ++ else if( Input_Power < -20 ) // if intput power level is smaller than -20 dBm ++ FC0012_Write(0x13, 0x17); // Switch to 17.9 dB ++ break; ++ ++ case 0x02: // Low gain -9.9 dB ++ if( Input_Power < -12 ) // if intput power level is smaller than -12 dBm ++ FC0012_Write(0x13, 0x08); // Switch to 7.1 dB ++ break; ++ } ++ ++} ++ ++ ++ ++ ++//===================================== Frequency Control 2009/07/30 ++// Frequency unit: KHz, bandwidth unit: MHz ++void FC0012_Frequency_Control(unsigned int Frequency, unsigned short Bandwidth) ++{ ++ if( Frequency < 260000 && Frequency > 150000 ) ++ { ++ // set GPIO6 = low ++ ++ // 1. Set tuner frequency ++ // 2. if the program quality is not good enough, switch to frequency + 500kHz ++ // 3. if the program quality is still no good, switch to frequency - 500kHz ++ } ++ else ++ { ++ // set GPIO6 = high ++ ++ // set tuner frequency ++ } ++} ++*/ ++ ++ ++ ++// FC0012 frequency/bandwidth setting function. ++// Frequency unit: KHz, bandwidth unit: MHz ++int FC0011_SetFrequency(TUNER_MODULE *pTuner, unsigned long Frequency, unsigned short Bandwidth) ++{ ++// bool VCO1 = false; ++// unsigned int doubleVCO; ++// unsigned short xin, xdiv; ++// unsigned char reg[21], am, pm, multi; ++ int VCO1 = FC0012_FALSE; ++ unsigned long doubleVCO; ++ unsigned short xin, xdiv; ++ unsigned char reg[21], am, pm, multi; ++ unsigned char read_byte; ++ ++ FC0012_EXTRA_MODULE *pExtra; ++ unsigned long CrystalFreqKhz; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ // Get tuner crystal frequency in KHz. ++ // Note: CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ CrystalFreqKhz = (pExtra->CrystalFreqHz + 500) / 1000; ++ ++ ++ //===================================== Select frequency divider and the frequency of VCO ++ if (Frequency * 96 < 3560000) ++ { ++ multi = 96; ++ reg[5] = 0x82; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 64 < 3560000) ++ { ++ multi = 64; ++ reg[5] = 0x82; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 48 < 3560000) ++ { ++ multi = 48; ++ reg[5] = 0x42; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 32 < 3560000) ++ { ++ multi = 32; ++ reg[5] = 0x42; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 24 < 3560000) ++ { ++ multi = 24; ++ reg[5] = 0x22; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 16 < 3560000) ++ { ++ multi = 16; ++ reg[5] = 0x22; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 12 < 3560000) ++ { ++ multi = 12; ++ reg[5] = 0x12; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 8 < 3560000) ++ { ++ multi = 8; ++ reg[5] = 0x12; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 6 < 3560000) ++ { ++ multi = 6; ++ reg[5] = 0x0A; ++ reg[6] = 0x00; ++ } ++ else ++ { ++ multi = 4; ++ reg[5] = 0x0A; ++ reg[6] = 0x02; ++ } ++ ++ doubleVCO = Frequency * multi; ++ ++ ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR test ++ reg[6] = reg[6] | 0x08; ++// VCO1 = true; ++ VCO1 = FC0012_TRUE; ++ /* ++ if (doubleVCO >= 3060000) ++ { ++ reg[6] = reg[6] | 0x08; ++// VCO1 = true; ++ VCO1 = FC0012_TRUE; ++ } ++ */ ++ //===================================== Arios Modify - 2009-10-23 ++ ++ //===================================== From divided value (XDIV) determined the FA and FP value ++// xdiv = (unsigned short)(doubleVCO / 14400); // implement round function, 2009-05-01 by Arios ++// if( (doubleVCO - xdiv * 14400) >= 7200 ) ++ xdiv = (unsigned short)(doubleVCO / (CrystalFreqKhz / 2)); // implement round function, 2009-05-01 by Arios ++ if( (doubleVCO - xdiv * (CrystalFreqKhz / 2)) >= (CrystalFreqKhz / 4) ) ++ xdiv = xdiv + 1; ++ ++ pm = (unsigned char)( xdiv / 8 ); ++ am = (unsigned char)( xdiv - (8 * pm)); ++ ++ if (am < 2) ++ { ++ reg[1] = am + 8; ++ reg[2] = pm - 1; ++ } ++ else ++ { ++ reg[1] = am; ++ reg[2] = pm; ++ } ++ ++ //===================================== From VCO frequency determines the XIN ( fractional part of Delta Sigma PLL) and divided value (XDIV). ++// xin = (unsigned short)(doubleVCO - ((unsigned short)(doubleVCO / 14400)) * 14400); ++// xin = ((xin << 15)/14400); ++ xin = (unsigned short)(doubleVCO - ((unsigned short)(doubleVCO / (CrystalFreqKhz / 2))) * (CrystalFreqKhz / 2)); ++ xin = ((xin << 15)/(unsigned short)(CrystalFreqKhz / 2)); ++ ++// if( xin >= (unsigned short) pow( (double)2, (double)14) ) ++// xin = xin + (unsigned short) pow( (double)2, (double)15); ++ if( xin >= (unsigned short) 16384 ) ++ xin = xin + (unsigned short) 32768; ++ ++ reg[3] = (unsigned char)(xin >> 8); ++ reg[4] = (unsigned char)(xin & 0x00FF); ++ ++ ++ //===================================== Only for testing, 2009-05-01 by Arios ++// printf("Frequency: %d, Fa: %d, Fp: %d, Xin:%d \n", Frequency, am, pm, xin); ++ ++ //===================================== Set Bandwidth ++ switch(Bandwidth) ++ { ++ case 6: ++ reg[6] = 0x80 | reg[6]; ++ break; ++ case 7: ++ reg[6] = ~0x80 & reg[6]; ++ reg[6] = 0x40 | reg[6]; ++ break; ++ case 8: ++ default: ++ reg[6] = ~0xC0 & reg[6]; ++ break; ++ } ++ ++ //===================================== Write registers ++ if(FC0012_Write(pTuner, 0x01, reg[1]) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x02, reg[2]) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x03, reg[3]) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x04, reg[4]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR Test ++ reg[5] = reg[5] | 0x07; ++ if(FC0012_Write(pTuner, 0x05, reg[5]) != FC0012_I2C_SUCCESS) goto error_status; ++ //===================================== Arios Modify - 2009-10-23 ++ ++ if(FC0012_Write(pTuner, 0x06, reg[6]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ //===================================== VCO Calibration ++ if(FC0012_Write(pTuner, 0x0E, 0x80) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ //===================================== VCO Re-Calibration if needed ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++// reg[14] = 0x3F & FC0012_Read(0x0E); ++ if(FC0012_Read(pTuner, 0x0E, &read_byte) != FC0012_I2C_SUCCESS) goto error_status; ++ reg[14] = 0x3F & read_byte; ++ ++ if (VCO1) ++ { ++ if (reg[14] > 0x3C) // modify 2009-09-15 ++ { ++ reg[6] = ~0x08 & reg[6]; ++ ++ if(FC0012_Write(pTuner, 0x06, reg[6]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ if(FC0012_Write(pTuner, 0x0E, 0x80) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ } ++ } ++ else ++ { ++ if (reg[14] < 0x02) // modify 2009-09-15 ++ { ++ reg[6] = 0x08 | reg[6]; ++ ++ if(FC0012_Write(pTuner, 0x06, reg[6]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ if(FC0012_Write(pTuner, 0x0E, 0x80) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ } ++ } ++ ++ return FC0012_FUNCTION_SUCCESS; ++ ++error_status: ++ return FC0012_FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc0012.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc0012.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc0012.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc0012.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,292 @@ ++#ifndef __TUNER_FC0012_H ++#define __TUNER_FC0012_H ++ ++/** ++ ++@file ++ ++@brief FC0012 tuner module declaration ++ ++One can manipulate FC0012 tuner through FC0012 module. ++FC0012 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_fc0012.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build FC0012 tuner module. ++ BuildFc0012Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc6, // I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_36000000HZ // Crystal frequency is 36.0 MHz. ++ ); ++ ++ ++ ++ ++ ++ // Get FC0012 tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set FC0012 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, FC0012_BANDWIDTH_6000000HZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get FC0012 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is implemented for FC0012 source code. ++ ++ ++// Definitions ++enum FC0012_TRUE_FALSE_STATUS ++{ ++ FC0012_FALSE, ++ FC0012_TRUE, ++}; ++ ++ ++enum FC0012_I2C_STATUS ++{ ++ FC0012_I2C_SUCCESS, ++ FC0012_I2C_ERROR, ++}; ++ ++ ++enum FC0012_FUNCTION_STATUS ++{ ++ FC0012_FUNCTION_SUCCESS, ++ FC0012_FUNCTION_ERROR, ++}; ++ ++ ++ ++// Functions ++int FC0012_Read(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char *pByte); ++int FC0012_Write(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char Byte); ++ ++int ++fc0012_SetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ); ++ ++int ++fc0012_GetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned char *pReadingValue ++ ); ++ ++int FC0012_Open(TUNER_MODULE *pTuner); ++int FC0011_SetFrequency(TUNER_MODULE *pTuner, unsigned long Frequency, unsigned short Bandwidth); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is FC0012 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Bandwidth mode ++enum FC0012_BANDWIDTH_MODE ++{ ++ FC0012_BANDWIDTH_6000000HZ = 6, ++ FC0012_BANDWIDTH_7000000HZ = 7, ++ FC0012_BANDWIDTH_8000000HZ = 8, ++}; ++ ++ ++// Default for initialing ++#define FC0012_RF_FREQ_HZ_DEFAULT 50000000 ++#define FC0012_BANDWIDTH_MODE_DEFAULT FC0012_BANDWIDTH_6000000HZ ++ ++ ++// Tuner LNA ++enum FC0012_LNA_GAIN_VALUE ++{ ++ FC0012_LNA_GAIN_LOW = 0x0, ++ FC0012_LNA_GAIN_MIDDLE = 0x1, ++ FC0012_LNA_GAIN_HIGH = 0x2, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildFc0012Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++fc0012_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++fc0012_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++fc0012_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++fc0012_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++fc0012_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++fc0012_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++fc0012_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc2580.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc2580.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc2580.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc2580.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,932 @@ ++/** ++ ++@file ++ ++@brief FC2580 tuner module definition ++ ++One can manipulate FC2580 tuner through FC2580 module. ++FC2580 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_fc2580.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief FC2580 tuner module builder ++ ++Use BuildFc2580Module() to build FC2580 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to FC2580 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr FC2580 I2C device address ++@param [in] CrystalFreqHz FC2580 crystal frequency in Hz ++@param [in] AgcMode FC2580 AGC mode ++ ++ ++@note ++ -# One should call BuildFc2580Module() to build FC2580 module before using it. ++ ++*/ ++void ++BuildFc2580Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int AgcMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ FC2580_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_FC2580; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = fc2580_GetTunerType; ++ pTuner->GetDeviceAddr = fc2580_GetDeviceAddr; ++ ++ pTuner->Initialize = fc2580_Initialize; ++ pTuner->SetRfFreqHz = fc2580_SetRfFreqHz; ++ pTuner->GetRfFreqHz = fc2580_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->AgcMode = AgcMode; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = fc2580_SetBandwidthMode; ++ pExtra->GetBandwidthMode = fc2580_GetBandwidthMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++fc2580_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++fc2580_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++fc2580_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ int AgcMode; ++ unsigned int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Get AGC mode. ++ AgcMode = pExtra->AgcMode; ++ ++ // Initialize tuner with AGC mode. ++ // Note: CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(fc2580_set_init(pTuner, AgcMode, CrystalFreqKhz) != FC2580_FCI_SUCCESS) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++fc2580_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ unsigned int RfFreqKhz; ++ unsigned int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Set tuner RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ // CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ RfFreqKhz = (unsigned int)((RfFreqHz + 500) / 1000); ++ CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(fc2580_set_freq(pTuner, RfFreqKhz, CrystalFreqKhz) != FC2580_FCI_SUCCESS) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++fc2580_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set FC2580 tuner bandwidth mode. ++ ++*/ ++int ++fc2580_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ unsigned int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Set tuner bandwidth mode. ++ // Note: CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(fc2580_set_filter(pTuner, (unsigned char)BandwidthMode, CrystalFreqKhz) != FC2580_FCI_SUCCESS) ++ goto error_status_set_tuner_bandwidth_mode; ++ ++ ++ // Set tuner bandwidth mode parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get FC2580 tuner bandwidth mode. ++ ++*/ ++int ++fc2580_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by FCI. ++ ++ ++ ++ ++ ++// FCI source code - fc2580_driver_v14011_r.c ++ ++ ++/*============================================================================== ++ FILE NAME : FC2580_driver_v1400_r.c ++ ++ VERSION : 1.400_r ++ ++ UPDATE : September 22. 2008 ++ ++==============================================================================*/ ++ ++/*============================================================================== ++ ++ Chip ID of FC2580 is 0x56 or 0xAC(including I2C write bit) ++ ++==============================================================================*/ ++ ++//#include "fc2580_driver_v1400_r.h" ++ ++//fc2580_band_type curr_band = FC2580_NO_BAND; ++//unsigned int freq_xtal = 16384; ++ ++ ++/*============================================================================== ++ milisecond delay function EXTERNAL FUNCTION ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ a ++ length of wanted delay in milisecond unit ++ ++==============================================================================*/ ++void fc2580_wait_msec(TUNER_MODULE *pTuner, int a) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ // Wait time in millisecond. ++ pBaseInterface->WaitMs(pBaseInterface, (unsigned long)a); ++ ++ ++ return; ++} ++ ++/*============================================================================== ++ ++ fc2580 i2c write ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ addr ++ fc2580's memory address\ ++ type : byte ++ ++ data ++ target data ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_write( TUNER_MODULE *pTuner, unsigned char addr, unsigned char data ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBytes[0] = addr; ++ WritingBytes[1] = data; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FC2580_FCI_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return FC2580_FCI_FAIL; ++}; ++ ++/*============================================================================== ++ ++ fc2580 i2c read ++ ++ This function is a generic function which gets called to read data from ++ fc2580's target memory address. ++ ++ ++ ++ addr ++ fc2580's memory address ++ type : byte ++ ++ ++ ++ data ++ a byte of data read out of target address 'addr' ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_read( TUNER_MODULE *pTuner, unsigned char addr, unsigned char *read_data ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &addr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, read_data, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return FC2580_FCI_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return FC2580_FCI_FAIL; ++}; ++ ++ ++ ++/*============================================================================== ++ fc2580 I2C Test ++ ++ This function is a generic function which tests I2C interface's availability ++ ++ by reading out it's I2C id data from reg. address '0x01'. ++ ++ ++ ++ None ++ ++ ++ int ++ 1 : success - communication is avilable ++ 0 : fail - communication is unavailable ++ ++ ++==============================================================================*/ ++//int fc2580_i2c_test( void ) ++//{ ++// return ( fc2580_i2c_read( 0x01 ) == 0x56 )? 0x01 : 0x00; ++//} ++ ++ ++ ++ ++/*============================================================================== ++ fc2580 initial setting ++ ++ This function is a generic function which gets called to initialize ++ ++ fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ ++ ifagc_mode ++ type : integer ++ 1 : Internal AGC ++ 2 : Voltage Control Mode ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_init( TUNER_MODULE *pTuner, int ifagc_mode, unsigned int freq_xtal ) ++{ ++ fc2580_fci_result_type result = FC2580_FCI_SUCCESS; ++ ++ result &= fc2580_i2c_write(pTuner, 0x00, 0x00); /*** Confidential ***/ ++ result &= fc2580_i2c_write(pTuner, 0x12, 0x86); ++ result &= fc2580_i2c_write(pTuner, 0x14, 0x5C); ++ result &= fc2580_i2c_write(pTuner, 0x16, 0x3C); ++ result &= fc2580_i2c_write(pTuner, 0x1F, 0xD2); ++ result &= fc2580_i2c_write(pTuner, 0x09, 0xD7); ++ result &= fc2580_i2c_write(pTuner, 0x0B, 0xD5); ++ result &= fc2580_i2c_write(pTuner, 0x0C, 0x32); ++ result &= fc2580_i2c_write(pTuner, 0x0E, 0x43); ++ result &= fc2580_i2c_write(pTuner, 0x21, 0x0A); ++ result &= fc2580_i2c_write(pTuner, 0x22, 0x82); ++ if( ifagc_mode == 1 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x45, 0x10); //internal AGC ++ result &= fc2580_i2c_write(pTuner, 0x4C, 0x00); //HOLD_AGC polarity ++ } ++ else if( ifagc_mode == 2 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x45, 0x20); //Voltage Control Mode ++ result &= fc2580_i2c_write(pTuner, 0x4C, 0x02); //HOLD_AGC polarity ++ } ++ result &= fc2580_i2c_write(pTuner, 0x3F, 0x88); ++ result &= fc2580_i2c_write(pTuner, 0x02, 0x0E); ++ result &= fc2580_i2c_write(pTuner, 0x58, 0x14); ++ result &= fc2580_set_filter(pTuner, 8, freq_xtal); //BW = 7.8MHz ++ ++ return result; ++} ++ ++ ++/*============================================================================== ++ fc2580 frequency setting ++ ++ This function is a generic function which gets called to change LO Frequency ++ ++ of fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ freq_xtal: kHz ++ ++ f_lo ++ Value of target LO Frequency in 'kHz' unit ++ ex) 2.6GHz = 2600000 ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_freq( TUNER_MODULE *pTuner, unsigned int f_lo, unsigned int freq_xtal ) ++{ ++ unsigned int f_diff, f_diff_shifted, n_val, k_val; ++ unsigned int f_vco, r_val, f_comp; ++ unsigned char pre_shift_bits = 4;// number of preshift to prevent overflow in shifting f_diff to f_diff_shifted ++ unsigned char data_0x18; ++ unsigned char data_0x02 = (USE_EXT_CLK<<5)|0x0E; ++ ++ fc2580_band_type band = ( f_lo > 1000000 )? FC2580_L_BAND : ( f_lo > 400000 )? FC2580_UHF_BAND : FC2580_VHF_BAND; ++ ++ fc2580_fci_result_type result = FC2580_FCI_SUCCESS; ++ ++ f_vco = ( band == FC2580_UHF_BAND )? f_lo * 4 : (( band == FC2580_L_BAND )? f_lo * 2 : f_lo * 12); ++ r_val = ( f_vco >= 2*76*freq_xtal )? 1 : ( f_vco >= 76*freq_xtal )? 2 : 4; ++ f_comp = freq_xtal/r_val; ++ n_val = ( f_vco / 2 ) / f_comp; ++ ++ f_diff = f_vco - 2* f_comp * n_val; ++ f_diff_shifted = f_diff << ( 20 - pre_shift_bits ); ++ k_val = f_diff_shifted / ( ( 2* f_comp ) >> pre_shift_bits ); ++ ++ if( f_diff_shifted - k_val * ( ( 2* f_comp ) >> pre_shift_bits ) >= ( f_comp >> pre_shift_bits ) ) ++ k_val = k_val + 1; ++ ++ if( f_vco >= BORDER_FREQ ) //Select VCO Band ++ data_0x02 = data_0x02 | 0x08; //0x02[3] = 1; ++ else ++ data_0x02 = data_0x02 & 0xF7; //0x02[3] = 0; ++ ++// if( band != curr_band ) { ++ switch(band) ++ { ++ case FC2580_UHF_BAND: ++ data_0x02 = (data_0x02 & 0x3F); ++ ++ result &= fc2580_i2c_write(pTuner, 0x25, 0xF0); ++ result &= fc2580_i2c_write(pTuner, 0x27, 0x77); ++ result &= fc2580_i2c_write(pTuner, 0x28, 0x53); ++ result &= fc2580_i2c_write(pTuner, 0x29, 0x60); ++ result &= fc2580_i2c_write(pTuner, 0x30, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x50, 0x8C); ++ result &= fc2580_i2c_write(pTuner, 0x53, 0x50); ++ ++ if( f_lo < 538000 ) ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x13); ++ else ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x15); ++ ++ if( f_lo < 538000 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x06); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x06); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x08); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x10); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x12); ++ } ++ else if( f_lo < 794000 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x03); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x03); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x03); //ACI improve ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x05); //ACI improve ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x0C); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x0E); ++ } ++ else ++ { ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x06); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x10); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x12); ++ } ++ ++ result &= fc2580_i2c_write(pTuner, 0x63, 0x15); ++ ++ result &= fc2580_i2c_write(pTuner, 0x6B, 0x0B); ++ result &= fc2580_i2c_write(pTuner, 0x6C, 0x0C); ++ result &= fc2580_i2c_write(pTuner, 0x6D, 0x78); ++ result &= fc2580_i2c_write(pTuner, 0x6E, 0x32); ++ result &= fc2580_i2c_write(pTuner, 0x6F, 0x14); ++ result &= fc2580_set_filter(pTuner, 8, freq_xtal); //BW = 7.8MHz ++ break; ++ case FC2580_VHF_BAND: ++ data_0x02 = (data_0x02 & 0x3F) | 0x80; ++ result &= fc2580_i2c_write(pTuner, 0x27, 0x77); ++ result &= fc2580_i2c_write(pTuner, 0x28, 0x33); ++ result &= fc2580_i2c_write(pTuner, 0x29, 0x40); ++ result &= fc2580_i2c_write(pTuner, 0x30, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x50, 0x8C); ++ result &= fc2580_i2c_write(pTuner, 0x53, 0x50); ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x0F); ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x63, 0x15); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x03); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x05); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x10); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x12); ++ result &= fc2580_i2c_write(pTuner, 0x6B, 0x08); ++ result &= fc2580_i2c_write(pTuner, 0x6C, 0x0A); ++ result &= fc2580_i2c_write(pTuner, 0x6D, 0x78); ++ result &= fc2580_i2c_write(pTuner, 0x6E, 0x32); ++ result &= fc2580_i2c_write(pTuner, 0x6F, 0x54); ++ result &= fc2580_set_filter(pTuner, 7, freq_xtal); //BW = 6.8MHz ++ break; ++ case FC2580_L_BAND: ++ data_0x02 = (data_0x02 & 0x3F) | 0x40; ++ result &= fc2580_i2c_write(pTuner, 0x2B, 0x70); ++ result &= fc2580_i2c_write(pTuner, 0x2C, 0x37); ++ result &= fc2580_i2c_write(pTuner, 0x2D, 0xE7); ++ result &= fc2580_i2c_write(pTuner, 0x30, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x44, 0x20); ++ result &= fc2580_i2c_write(pTuner, 0x50, 0x8C); ++ result &= fc2580_i2c_write(pTuner, 0x53, 0x50); ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x0F); ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x0F); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x63, 0x13); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x02); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x0C); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x0E); ++ result &= fc2580_i2c_write(pTuner, 0x6B, 0x08); ++ result &= fc2580_i2c_write(pTuner, 0x6C, 0x0A); ++ result &= fc2580_i2c_write(pTuner, 0x6D, 0xA0); ++ result &= fc2580_i2c_write(pTuner, 0x6E, 0x50); ++ result &= fc2580_i2c_write(pTuner, 0x6F, 0x14); ++ result &= fc2580_set_filter(pTuner, 1, freq_xtal); //BW = 1.53MHz ++ break; ++ default: ++ break; ++ } ++// curr_band = band; ++// } ++ ++ //A command about AGC clock's pre-divide ratio ++ if( freq_xtal >= 28000 ) ++ result &= fc2580_i2c_write(pTuner, 0x4B, 0x22 ); ++ ++ //Commands about VCO Band and PLL setting. ++ result &= fc2580_i2c_write(pTuner, 0x02, data_0x02); ++ data_0x18 = ( ( r_val == 1 )? 0x00 : ( ( r_val == 2 )? 0x10 : 0x20 ) ) + (unsigned char)(k_val >> 16); ++ result &= fc2580_i2c_write(pTuner, 0x18, data_0x18); //Load 'R' value and high part of 'K' values ++ result &= fc2580_i2c_write(pTuner, 0x1A, (unsigned char)( k_val >> 8 ) ); //Load middle part of 'K' value ++ result &= fc2580_i2c_write(pTuner, 0x1B, (unsigned char)( k_val ) ); //Load lower part of 'K' value ++ result &= fc2580_i2c_write(pTuner, 0x1C, (unsigned char)( n_val ) ); //Load 'N' value ++ ++ //A command about UHF LNA Load Cap ++ if( band == FC2580_UHF_BAND ) ++ result &= fc2580_i2c_write(pTuner, 0x2D, ( f_lo <= (unsigned int)794000 )? 0x9F : 0x8F ); //LNA_OUT_CAP ++ ++ ++ return result; ++} ++ ++ ++/*============================================================================== ++ fc2580 filter BW setting ++ ++ This function is a generic function which gets called to change Bandwidth ++ ++ frequency of fc2580's channel selection filter ++ ++ ++ freq_xtal: kHz ++ ++ filter_bw ++ 1 : 1.53MHz(TDMB) ++ 6 : 6MHz (Bandwidth 6MHz) ++ 7 : 6.8MHz (Bandwidth 7MHz) ++ 8 : 7.8MHz (Bandwidth 8MHz) ++ ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_filter( TUNER_MODULE *pTuner, unsigned char filter_bw, unsigned int freq_xtal ) ++{ ++ unsigned char cal_mon, i; ++ fc2580_fci_result_type result = FC2580_FCI_SUCCESS; ++ ++ if(filter_bw == 1) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x1C); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(4151*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ if(filter_bw == 6) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x18); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(4400*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ else if(filter_bw == 7) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x18); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(3910*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x80); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ else if(filter_bw == 8) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x18); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(3300*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x80); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ ++ ++ for(i=0; i<5; i++) ++ { ++ fc2580_wait_msec(pTuner, 5);//wait 5ms ++ result &= fc2580_i2c_read(pTuner, 0x2F, &cal_mon); ++ if( (cal_mon & 0xC0) != 0xC0) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x01); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ else ++ break; ++ } ++ ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x01); ++ ++ return result; ++} ++ ++/*============================================================================== ++ fc2580 RSSI function ++ ++ This function is a generic function which returns fc2580's ++ ++ current RSSI value. ++ ++ ++ none ++ ++ ++ int ++ rssi : estimated input power. ++ ++==============================================================================*/ ++//int fc2580_get_rssi(void) { ++// ++// unsigned char s_lna, s_rfvga, s_cfs, s_ifvga; ++// int ofs_lna, ofs_rfvga, ofs_csf, ofs_ifvga, rssi; ++// ++// fc2580_i2c_read(0x71, &s_lna ); ++// fc2580_i2c_read(0x72, &s_rfvga ); ++// fc2580_i2c_read(0x73, &s_cfs ); ++// fc2580_i2c_read(0x74, &s_ifvga ); ++// ++// ++// ofs_lna = ++// (curr_band==FC2580_UHF_BAND)? ++// (s_lna==0)? 0 : ++// (s_lna==1)? -6 : ++// (s_lna==2)? -17 : ++// (s_lna==3)? -22 : -30 : ++// (curr_band==FC2580_VHF_BAND)? ++// (s_lna==0)? 0 : ++// (s_lna==1)? -6 : ++// (s_lna==2)? -19 : ++// (s_lna==3)? -24 : -32 : ++// (curr_band==FC2580_L_BAND)? ++// (s_lna==0)? 0 : ++// (s_lna==1)? -6 : ++// (s_lna==2)? -11 : ++// (s_lna==3)? -16 : -34 : ++// 0;//FC2580_NO_BAND ++// ofs_rfvga = -s_rfvga+((s_rfvga>=11)? 1 : 0) + ((s_rfvga>=18)? 1 : 0); ++// ofs_csf = -6*s_cfs; ++// ofs_ifvga = s_ifvga/4; ++// ++// return rssi = ofs_lna+ofs_rfvga+ofs_csf+ofs_ifvga+OFS_RSSI; ++// ++//} ++ ++/*============================================================================== ++ fc2580 Xtal frequency Setting ++ ++ This function is a generic function which sets ++ ++ the frequency of xtal. ++ ++ ++ ++ frequency ++ frequency value of internal(external) Xtal(clock) in kHz unit. ++ ++==============================================================================*/ ++//void fc2580_set_freq_xtal(unsigned int frequency) { ++// ++// freq_xtal = frequency; ++// ++//} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc2580.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc2580.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_fc2580.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_fc2580.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,461 @@ ++#ifndef __TUNER_FC2580_H ++#define __TUNER_FC2580_H ++ ++/** ++ ++@file ++ ++@brief FC2580 tuner module declaration ++ ++One can manipulate FC2580 tuner through FC2580 module. ++FC2580 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_fc2580.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ FC2580_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build FC2580 tuner module. ++ BuildFc2580Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xac, // I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // Crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is internal AGC mode. ++ ); ++ ++ ++ ++ ++ ++ // Get FC2580 tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set FC2580 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, FC2580_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get FC2580 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is source code provided by FCI. ++ ++ ++ ++ ++ ++// FCI source code - fc2580_driver_v1400_r.h ++ ++ ++/*============================================================================== ++ FILE NAME : FC2580_driver_v1400_r.h ++ ++ VERSION : 1.400_r ++ ++ UPDATE : September 22. 2008 ++ ++==============================================================================*/ ++ ++/*============================================================================== ++ ++ Chip ID of FC2580 is 0x56 or 0xAC(including I2C write bit) ++ ++==============================================================================*/ ++ ++ ++#define BORDER_FREQ 2600000 //2.6GHz : The border frequency which determines whether Low VCO or High VCO is used ++#define USE_EXT_CLK 0 //0 : Use internal XTAL Oscillator / 1 : Use External Clock input ++#define OFS_RSSI 57 ++ ++typedef enum { ++ FC2580_UHF_BAND, ++ FC2580_L_BAND, ++ FC2580_VHF_BAND, ++ FC2580_NO_BAND ++} fc2580_band_type; ++ ++typedef enum { ++ FC2580_FCI_FAIL, ++ FC2580_FCI_SUCCESS ++} fc2580_fci_result_type; ++ ++/*============================================================================== ++ i2c command write EXTERNAL FUNCTION ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ slave_id ++ i2c id of slave chip ++ type : byte ++ ++ addr ++ memory address of slave chip ++ type : byte ++ ++ data ++ target data ++ type : byte ++ ++==============================================================================*/ ++//extern fc2580_fci_result_type i2c_write( unsigned char slave_id, unsigned char addr, unsigned char *data, unsigned char n ); ++ ++/*============================================================================== ++ i2c command write EXTERNAL FUNCTION ++ ++ This function is a generic function which gets called to read data from ++ slave chip's target memory address. ++ ++ ++ ++ slave_id ++ i2c id of slave chip ++ type : byte ++ ++ addr ++ memory address of slave chip ++ type : byte ++ ++ ++ data ++ a byte of data read out of target address 'addr' of slave chip ++ type : byte ++ ++==============================================================================*/ ++//extern fc2580_fci_result_type i2c_read( unsigned char slave_id, unsigned char addr, unsigned char *read_data, unsigned char n ); ++ ++/*============================================================================== ++ milisecond delay function EXTERNAL FUNCTION ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ a ++ length of wanted delay in milisecond unit ++ ++==============================================================================*/ ++extern void fc2580_wait_msec(TUNER_MODULE *pTuner, int a); ++ ++ ++ ++/*============================================================================== ++ fc2580 i2c command write ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ addr ++ fc2580's memory address ++ type : byte ++ ++ data ++ target data ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_write( TUNER_MODULE *pTuner, unsigned char addr, unsigned char data ); ++ ++/*============================================================================== ++ fc2580 i2c data read ++ ++ This function is a generic function which gets called to read data from ++ fc2580's target memory address. ++ ++ ++ ++ addr ++ fc2580's memory address ++ type : byte ++ ++ ++ ++ data ++ a byte of data read out of target address 'addr' ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_read( TUNER_MODULE *pTuner, unsigned char addr, unsigned char *read_data ); ++ ++/*============================================================================== ++ fc2580 initial setting ++ ++ This function is a generic function which gets called to initialize ++ ++ fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ ++ ifagc_mode ++ type : integer ++ 1 : Internal AGC ++ 2 : Voltage Control Mode ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_init( TUNER_MODULE *pTuner, int ifagc_mode, unsigned int freq_xtal ); ++ ++/*============================================================================== ++ fc2580 frequency setting ++ ++ This function is a generic function which gets called to change LO Frequency ++ ++ of fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ ++ f_lo ++ Value of target LO Frequency in 'kHz' unit ++ ex) 2.6GHz = 2600000 ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_freq( TUNER_MODULE *pTuner, unsigned int f_lo, unsigned int freq_xtal ); ++ ++ ++/*============================================================================== ++ fc2580 filter BW setting ++ ++ This function is a generic function which gets called to change Bandwidth ++ ++ frequency of fc2580's channel selection filter ++ ++ ++ ++ filter_bw ++ 1 : 1.53MHz(TDMB) ++ 6 : 6MHz ++ 7 : 7MHz ++ 8 : 7.8MHz ++ ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_filter( TUNER_MODULE *pTuner, unsigned char filter_bw, unsigned int freq_xtal ); ++ ++/*============================================================================== ++ fc2580 RSSI function ++ ++ This function is a generic function which returns fc2580's ++ ++ current RSSI value. ++ ++ ++ ++ ++==============================================================================*/ ++//int fc2580_get_rssi(void); ++ ++/*============================================================================== ++ fc2580 Xtal frequency Setting ++ ++ This function is a generic function which sets ++ ++ the frequency of xtal. ++ ++ ++ ++ frequency ++ frequency value of internal(external) Xtal(clock) in kHz unit. ++ ++==============================================================================*/ ++//void fc2580_set_freq_xtal(unsigned int frequency); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is FC2580 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// AGC mode ++enum FC2580_AGC_MODE ++{ ++ FC2580_AGC_INTERNAL = 1, ++ FC2580_AGC_EXTERNAL = 2, ++}; ++ ++ ++// Bandwidth mode ++enum FC2580_BANDWIDTH_MODE ++{ ++ FC2580_BANDWIDTH_1530000HZ = 1, ++ FC2580_BANDWIDTH_6000000HZ = 6, ++ FC2580_BANDWIDTH_7000000HZ = 7, ++ FC2580_BANDWIDTH_8000000HZ = 8, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildFc2580Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int AgcMode ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++fc2580_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++fc2580_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++fc2580_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++fc2580_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++fc2580_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++fc2580_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++fc2580_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_max3543.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_max3543.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_max3543.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_max3543.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,1441 @@ ++/** ++ ++@file ++ ++@brief MAX3543 tuner module definition ++ ++One can manipulate MAX3543 tuner through MAX3543 module. ++MAX3543 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_max3543.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MAX3543 tuner module builder ++ ++Use BuildMax3543Module() to build MAX3543 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MAX3543 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MAX3543 I2C device address ++@param [in] CrystalFreqHz MAX3543 crystal frequency in Hz ++@param [in] StandardMode MAX3543 standard mode ++@param [in] IfFreqHz MAX3543 IF frequency in Hz ++@param [in] OutputMode MAX3543 output mode ++ ++ ++@note ++ -# One should call BuildMax3543Module() to build MAX3543 module before using it. ++ ++*/ ++void ++BuildMax3543Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int OutputMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MAX3543; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->RfFreqHz = MAX3543_RF_FREQ_HZ_DEFAULT; ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = max3543_GetTunerType; ++ pTuner->GetDeviceAddr = max3543_GetDeviceAddr; ++ ++ pTuner->Initialize = max3543_Initialize; ++ pTuner->SetRfFreqHz = max3543_SetRfFreqHz; ++ pTuner->GetRfFreqHz = max3543_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->StandardMode = StandardMode; ++ pExtra->IfFreqHz = IfFreqHz; ++ pExtra->OutputMode = OutputMode; ++ pExtra->BandwidthMode = MAX3543_BANDWIDTH_MODE_DEFAULT; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ pExtra->broadcast_standard = StandardMode; ++ ++ switch(CrystalFreqHz) ++ { ++ default: ++ case CRYSTAL_FREQ_16000000HZ: ++ ++ switch(IfFreqHz) ++ { ++ default: ++ case IF_FREQ_36170000HZ: ++ ++ pExtra->XTALSCALE = 8; ++ pExtra->XTALREF = 128; ++ pExtra->LOSCALE = 65; ++ ++ break; ++ } ++ } ++ ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = max3543_SetBandwidthMode; ++ pExtra->GetBandwidthMode = max3543_GetBandwidthMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++max3543_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++max3543_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++max3543_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Initializing tuner. ++ // Note: Call MAX3543 source code function. ++ if(MAX3543_Init(pTuner) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner standard mode and output mode. ++ // Note: Call MAX3543 source code function. ++ if(MAX3543_Standard(pTuner, pExtra->StandardMode, pExtra->OutputMode) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++max3543_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ unsigned long FreqUnit; ++ unsigned short CalculatedValue; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Calculate frequency unit. ++ FreqUnit = MAX3543_CONST_1_MHZ / pExtra->LOSCALE; ++ ++ // Set tuner RF frequency in KHz. ++ // Note: 1. CalculatedValue = round(RfFreqHz / FreqUnit) ++ // 2. Call MAX3543 source code function. ++ CalculatedValue = (unsigned short)((RfFreqHz + (FreqUnit / 2)) / FreqUnit); ++ ++ if(MAX3543_SetFrequency(pTuner, CalculatedValue) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++max3543_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MAX3543 tuner bandwidth mode. ++ ++*/ ++int ++max3543_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ unsigned short BandwidthModeUshort; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Set tuner bandwidth mode. ++ // Note: Call MAX3543 source code function. ++ BandwidthModeUshort = (unsigned short)BandwidthMode; ++ ++ if(MAX3543_ChannelBW(pTuner, BandwidthModeUshort) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner bandwidth Hz parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MAX3543 tuner bandwidth mode. ++ ++*/ ++int ++max3543_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Get tuner bandwidth Hz from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Function (implemeted for MAX3543) ++int ++Max3543_Read( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short *pData ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingByte; ++ unsigned char ReadingByte; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ WritingByte = (unsigned char)RegAddr; ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &WritingByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, &ReadingByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ *pData = (unsigned short)ReadingByte; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++ ++ ++int ++Max3543_Write( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short Data ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = (unsigned char)RegAddr; ++ WritingBuffer[1] = (unsigned char)Data; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by MAXIM. ++ ++ ++ ++ ++ ++// MAXIM source code - Max3543_Driver.c ++ ++ ++/* ++------------------------------------------------------------------------- ++| MAX3543 Tuner Driver ++| Author: Paul Nichol ++| ++| Version: 1.0.3 ++| Date: 12/09/09 ++| ++| ++| Copyright (C) 2009 Maxim Integrated Products. ++| PLEASE READ THE ATTACHED LICENSE CAREFULLY BEFORE USING THIS SOFTWARE. ++| BY USING THE SOFTWARE OF MAXIM INTEGRATED PRODUCTS, INC, YOU ARE AGREEING ++| TO BE BOUND BY THE TERMS OF THE ATTACHED LICENSE, WHICH INCLUDES THE SOFTWARE ++| LICENSE AND SOFTWARE WARRANTY DISCLAIMER, EVEN WITHOUT YOUR SIGNATURE. ++| IF YOU DO NOT AGREE TO THE TERMS OF THIS AGREEMENT, DO NOT USE THIS SOFTWARE. ++| ++| IMPORTANT: This code is operate the Max3543 Multi-Band Terrestrial ++| Hybrid Tuner. Routines include: initializing, tuning, reading the ++| ROM table, reading the lock detect status and tuning the tracking ++| filter. Only integer math is used in this program and no floating point ++| variables are used. Your MCU must be capable of processing unsigned 32 bit integer ++| math to use this routine. (That is: two 16 bit numbers multiplied resulting in a ++| 32 bit result, or a 32 bit number divided by a 16 bit number). ++| ++-------------------------------------------------------------------------- ++*/ ++ ++ ++//#include ++//#include ++///#include ++//#include "mxmdef.h" ++//#include "Max3543_Driver.h" ++ ++/* ++double debugreg[10]; ++UINT_16 TFRomCoefs[3][4]; ++UINT_16 denominator; ++UINT_32 fracscale ; ++UINT_16 regs[22]; ++UINT_16 IF_Frequency; ++*/ ++ ++/* table of fixed coefficients for the tracking filter equations. */ ++ ++const ++static UINT_16 co[6][5]={{ 26, 6, 68, 20, 45 }, /* VHF LO TFS */ ++ { 16, 8, 88, 40, 0 }, /* VHF LO TFP */ ++ { 27, 10, 54, 30,20 }, /* VHF HI TFS */ ++ { 18, 10, 41, 20, 0 }, /* VHF HI TFP */ ++ { 32, 10, 34, 8, 10 }, /* UHF TFS */ ++ { 13, 15, 21, 16, 0 }}; /* UHF TFP */ ++ ++ ++ ++//int MAX3543_Init(TUNER_MODULE *pTuner, UINT_16 RfFreq) ++int MAX3543_Init(TUNER_MODULE *pTuner) ++{ ++ /* ++ Initialize every register. Don't rely on MAX3543 power on reset. ++ Call before using the other routines in this file. ++ */ ++ UINT_16 RegNumber; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ unsigned long FreqUnit; ++ unsigned short CalculatedValue; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ /*Initialize the registers in the MAX3543:*/ ++ ++ ++ ++ pExtra->regs[REG3543_VCO] = 0x4c; ++ pExtra->regs[REG3543_NDIV] = 0x2B; ++ pExtra->regs[REG3543_FRAC2] = 0x8E; ++ pExtra->regs[REG3543_FRAC1] = 0x26; ++ pExtra->regs[REG3543_FRAC0] = 0x66; ++ pExtra->regs[REG3543_MODE] = 0xd8; ++ pExtra->regs[REG3543_TFS] = 0x00; ++ pExtra->regs[REG3543_TFP] = 0x00; ++ pExtra->regs[REG3543_SHDN] = 0x00; ++ pExtra->regs[REG3543_REF] = 0x0a; ++ pExtra->regs[REG3543_VAS] = 0x17; ++ pExtra->regs[REG3543_PD_CFG1] = 0x43; ++ pExtra->regs[REG3543_PD_CFG2] = 0x01; ++ pExtra->regs[REG3543_FILT_CF] = 0x25; ++ pExtra->regs[REG3543_ROM_ADDR] = 0x00; ++ pExtra->regs[REG3543_IRHR] = 0x80; ++ pExtra->regs[REG3543_BIAS_ADJ] = 0x57; ++ pExtra->regs[REG3543_TEST1] = 0x40; ++ pExtra->regs[REG3543_ROM_WRITE] = 0x00; ++ ++ ++ ++ /* Write each register out to the MAX3543: */ ++ for (RegNumber=0;RegNumber<=MAX3543_NUMREGS;RegNumber++) ++ { ++// Max3543_Write(RegNumber, regs[RegNumber]); ++ if(Max3543_Write(pTuner, RegNumber, pExtra->regs[RegNumber]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ } ++ ++ /* First read calibration constants from MAX3543 and store in global ++ variables for use when setting RF tracking filter */ ++// MAX3543_ReadROM(); ++ if(MAX3543_ReadROM(pTuner) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Define the IF frequency used. ++ If using non-floating point math, enter the IF Frequency multiplied ++ by the factor LOSCALE here as an integer. ++ i.e. IF_Frequency = 1445; ++ If using floating point math, use the scalefrq macro: ++ i.e. IF_Frequency = scalefrq(36.125); ++ */ ++// IF_Frequency = scalefrq(36.125); ++ ++ ++ // Calculate frequency unit. ++ FreqUnit = MAX3543_CONST_1_MHZ / pExtra->LOSCALE; ++ ++ // Set tuner RF frequency in KHz. ++ // Note: 1. CalculatedValue = round(RfFreqHz / FreqUnit) ++ // 2. Call MAX3543 source code function. ++ CalculatedValue = (unsigned short)((pExtra->IfFreqHz + (FreqUnit / 2)) / FreqUnit); ++ pExtra->IF_Frequency = CalculatedValue; ++ ++ ++ /* Calculate the denominator just once since it is dependant on the xtal freq only. ++ The denominator is used to calculate the N+FractionalN ratio. ++ */ ++ pExtra->denominator = pExtra->XTALREF * 4 * pExtra->LOSCALE; ++ ++ /* The fracscale is used to calculate the fractional remainder of the N+FractionalN ratio. */ ++ pExtra->fracscale = 2147483648/pExtra->denominator; ++ ++ ++// Note: Set standard mode, channel bandwith, and RF frequency in other functions. ++ ++// MAX3543_Standard(DVB_T, IFOUT1_DIFF_DTVOUT); ++ ++// MAX3543_ChannelBW(BW8MHZ); ++ // Note: Set bandwidth with 8 MHz for QAM. ++ MAX3543_ChannelBW(pTuner, MAX3543_BANDWIDTH_MODE_DEFAULT); ++ ++// MAX3543_SetFrequency(RfFreq); ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++/* Set the channel bandwidth. Call with arguments: BW7MHZ or BW8MHZ */ ++int MAX3543_ChannelBW(TUNER_MODULE *pTuner, UINT_16 bw) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ pExtra->regs[REG3543_MODE] = (pExtra->regs[REG3543_MODE] & 0xef) | (bw<<4); ++// Max3543_Write(REG3543_MODE, regs[REG3543_MODE]); ++ if(Max3543_Write(pTuner, REG3543_MODE, pExtra->regs[REG3543_MODE]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++/* ++ Set the broadcast standared and RF signal path. ++ This routine must be called prior to tuning (Set_Frequency() ) ++ such as in MAX3543_Init() or when necessary to change modes. ++ ++ This sub routine has 2 input/function ++ 1. bcstd:it set MAX3543 to optimized power detector/bias setting for each standard (dvb-t,pal?, currently it has 4 choice: ++ 1.1 bcstd=DVBT, optimized for DVB-T ++ 1.2 bcstd=DVBC, optimized for DVB-C ++ 1.3 bcstd=ATV1, optimized for PAL/SECAM - B/G/D/K/I ++ 1.4 bcstd=ATV2, optimized for SECAM-L ++ 2. outputmode: this setting has to match you hardware signal path, it has 3 choice: ++ 2.1 outputmode=IFOUT1_DIFF_IFOUT_DIFF ++ signal path: IFOUT1 (pin6/7) driving a diff input IF filter (ie LC filter or 6966 SAW), ++ then go back to IFVGA input (pin 10/11) and IF output of MAX3543 is pin 15/16. ++ this is common seting for all DTV_only demod and hybrid demod ++ 2.2 outputmode=IFOUT1_SE_IFOUT_DIFF ++ signal path: IFOUT1 (pin6) driving a single-ended input IF filter (ie 7251 SAW) ++ then go back to IFVGA input (pin 10/11) and IF output of MAX3543 is pin 15/16. ++ this is common seting for all DTV_only demod and hybrid demod ++ 2.3 outputmode=IFOUT2 ++ signal path: IFOUT2 (pin14) is MAX3543 IF output, normally it drives a ATV demod. ++ The IFVGA is shutoff ++ this is common setting for separate ATV demod app ++*/ ++ ++int MAX3543_Standard(TUNER_MODULE *pTuner, standard bcstd, outputmode outmd) ++{ ++ char IFSEL; ++ char LNA2G; ++ char SDIVG; ++ char WPDA; ++ char NPDA; ++ char RFIFD; ++ char MIXGM; ++ char LNA2B; ++ char MIXB; ++ ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ pExtra->broadcast_standard = bcstd; /* used later in tuning */ ++ ++ ++ switch ( bcstd ) ++ { ++ case DVB_T: ++ LNA2G = 1; ++ WPDA = 4; ++ NPDA = 3; ++ RFIFD = 1; ++ MIXGM = 1; ++ LNA2B = 1; ++ MIXB = 1; ++ break; ++ case DVB_C: ++ LNA2G = 1; ++ WPDA = 3; ++ NPDA = 3; ++ RFIFD = 1; ++ MIXGM = 1; ++ LNA2B = 1; ++ MIXB = 1; ++ break; ++ case ATV: ++ LNA2G = 0; ++ WPDA = 3; ++ NPDA = 5; ++ RFIFD = 2; ++ MIXGM = 0; ++ LNA2B = 3; ++ MIXB = 3; ++ break; ++ case ATV_SECAM_L: ++ LNA2G = 0; ++ WPDA = 3; ++ NPDA = 3; ++ RFIFD = 2; ++ MIXGM = 0; ++ LNA2B = 3; ++ MIXB = 3; ++ break; ++ default: ++ return MAX3543_ERROR; ++ } ++ ++ /* the outmd must be set after the standard mode bits are set. ++ Please do not change order. */ ++ switch ( outmd ) ++ { ++ case IFOUT1_DIFF_DTVOUT: ++ IFSEL = 0; ++ SDIVG = 0; ++ break; ++ case IFOUT1_SE_DTVOUT: ++ IFSEL = 1; ++ SDIVG = 0; ++ break; ++ case IFOUT2: ++ IFSEL = 2; ++ SDIVG = 1; ++ NPDA = 3; ++ LNA2G = 1; /* overrites value chosen above for this case */ ++ RFIFD = 3; /* overrites value chosen above for this case */ ++ break; ++ default: ++ return MAX3543_ERROR; ++ } ++ ++ ++ /* Mask in each set of bits into the register variables */ ++ pExtra->regs[REG3543_MODE] = (pExtra->regs[REG3543_MODE] & 0x7c) | IFSEL | (LNA2G<<7); ++ pExtra->regs[REG3543_SHDN] = (pExtra->regs[REG3543_SHDN] & 0xf7) | (SDIVG<<3); ++ pExtra->regs[REG3543_PD_CFG1] = (pExtra->regs[REG3543_PD_CFG1] & 0x88) | (WPDA<<4) | NPDA; ++ pExtra->regs[REG3543_PD_CFG2] = (pExtra->regs[REG3543_PD_CFG2] & 0xfc) | RFIFD; ++ pExtra->regs[REG3543_BIAS_ADJ] = (pExtra->regs[REG3543_BIAS_ADJ] & 0x13) | (MIXGM<<6) | (LNA2B<<4) | (MIXB<<2); ++ ++ /* Send each register variable: */ ++// Max3543_Write(REG3543_MODE, regs[REG3543_MODE]); ++ if(Max3543_Write(pTuner, REG3543_MODE, pExtra->regs[REG3543_MODE]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_SHDN, regs[REG3543_SHDN]); ++ if(Max3543_Write(pTuner, REG3543_SHDN, pExtra->regs[REG3543_SHDN]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_PD_CFG1, regs[REG3543_PD_CFG1]); ++ if(Max3543_Write(pTuner, REG3543_PD_CFG1, pExtra->regs[REG3543_PD_CFG1]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_PD_CFG2, regs[REG3543_PD_CFG2]); ++ if(Max3543_Write(pTuner, REG3543_PD_CFG2, pExtra->regs[REG3543_PD_CFG2]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_BIAS_ADJ, regs[REG3543_BIAS_ADJ]); ++ if(Max3543_Write(pTuner, REG3543_BIAS_ADJ, pExtra->regs[REG3543_BIAS_ADJ]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++/*This will set the LO Frequency and all other tuning related register bits. ++ ++ NOTE!!!! The frequency passed to this routine must be scaled by th factor ++ LOSCALE. For example if the frequency was 105.25 MHz you multiply ++ this by LOSCALE which results in a whole number frequency. ++ For example if LOSCALE = 20, then 105.25 * 20 = 2105. ++ You would then call: MAX3543_SetFrequency(2105); ++*/ ++int MAX3543_SetFrequency(TUNER_MODULE *pTuner, UINT_16 RF_Frequency) ++{ ++ UINT_16 RDiv, NewR, NDiv, Vdiv; ++ UINT_32 Num; ++ UINT_16 LO_Frequency; ++ UINT_16 Rem; ++ UINT_32 FracN; ++ ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ LO_Frequency = RF_Frequency + pExtra->IF_Frequency ; ++ ++ /* Determine VCO Divider */ ++ if (LO_Frequency < scalefrq(138)) /* 138MHz scaled UHF band */ ++ { ++ Vdiv = 3; /* divide by 32 */ ++ } ++ else if ( LO_Frequency < scalefrq(275)) /* VHF Band */ ++ { ++ Vdiv = 2; /* divide by 16 */ ++ } ++ else if (LO_Frequency < scalefrq(550)) ++ { ++ Vdiv = 1; /* divide by 8 */ ++ } ++ else ++ { ++ Vdiv = 0; /* divide by 4 */ ++ } ++ ++ ++ /* calculate the r-divider from the RDIV bits: ++ RDIV bits RDIV ++ 00 1 ++ 01 2 ++ 10 4 ++ 11 8 ++ */ ++ RDiv = 1<<((pExtra->regs[REG3543_FRAC2] & 0x30) >> 4); ++ ++ /* Set the R-Divider based on the frequency if in DVB mode. ++ Otherwise set the R-Divider to 2. ++ Only send RDivider if it needs to change from the current state. ++ */ ++ NewR = 0; ++ if ((pExtra->broadcast_standard == DVB_T || pExtra->broadcast_standard == DVB_C) ) ++ { ++ if ((LO_Frequency <= scalefrq(275)) && (RDiv == 1)) ++ NewR = 2; ++ else if ((LO_Frequency > scalefrq(275)) && (RDiv == 2)) ++ NewR = 1; ++ } ++ else if (RDiv == 1) ++ NewR = 2; ++ ++ if (NewR != 0){ ++ RDiv = NewR; ++ pExtra->regs[REG3543_FRAC2] = (pExtra->regs[REG3543_FRAC2] & 0xcf) | ((NewR-1) <<4); ++// Max3543_Write(REG3543_FRAC2, regs[REG3543_FRAC2]); ++ if(Max3543_Write(pTuner, REG3543_FRAC2, pExtra->regs[REG3543_FRAC2]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ } ++ ++ /* Update the VDIV bits in the VCO variable. ++ we will write this variable out to the VCO register during the MAX3543_SeedVCO routine. ++ We can write over all the other bits (D<7:2>) in that register variable because they ++ will be filled in: MAX3543_SeedVCO later. ++ */ ++ pExtra->regs[REG3543_VCO] = Vdiv; ++ ++ /* now convert the Vdiv bits into the multiplier for use in the equation: ++ Vdiv Mult ++ 0 4 ++ 1 8 ++ 2 16 ++ 3 32 ++ */ ++ Vdiv = 1<<(Vdiv+2); ++ ++ ++ //#ifdef HAVE_32BIT_MATH ++ ++ /* Calculate Numerator and Denominator for N+FN calculation */ ++ Num = LO_Frequency * RDiv * Vdiv * pExtra->XTALSCALE; ++ ++ ++ NDiv = (UINT_16) (Num/(UINT_32)pExtra->denominator); /* Note: this is an integer division, returns 16 bit value. */ ++ ++// Max3543_Write(REG3543_NDIV,NDiv); ++ if(Max3543_Write(pTuner, REG3543_NDIV,NDiv) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Calculate whole number remainder from division of Num by denom: ++ Returns 16 bit value. */ ++ Rem = (UINT_16)(Num - (UINT_32) NDiv * (UINT_32) pExtra->denominator); ++ ++ /* FracN = Rem * 2^20/Denom, Scale 2^20/Denom 2048 X larger for more accuracy. */ ++ /* fracscale = 2^31/denom. 2048 = 2^31/2^20 */ ++ FracN =(Rem*pExtra->fracscale)/2048; ++ ++ ++ ++ /* Optional - Seed the VCO to cause it to tune faster. ++ (LO_Frequency/LOSCALE) * Vdiv = the unscaled VCO Frequency. ++ It is unscaled to prevent overflow when it is multiplied by vdiv. ++ */ ++// MAX3543_SeedVCO((LO_Frequency/LOSCALE) * Vdiv); ++ if(MAX3543_SeedVCO(pTuner, (LO_Frequency/pExtra->LOSCALE) * Vdiv) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ ++ pExtra->regs[REG3543_FRAC2] = (pExtra->regs[REG3543_FRAC2] & 0xf0) | ((UINT_16)(FracN >> 16) & 0xf); ++// Max3543_Write(REG3543_FRAC2, regs[REG3543_FRAC2]); ++ if(Max3543_Write(pTuner, REG3543_FRAC2, pExtra->regs[REG3543_FRAC2]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_FRAC1,(UINT_16)(FracN >> 8) & 0xff); ++ if(Max3543_Write(pTuner, REG3543_FRAC1,(UINT_16)(FracN >> 8) & 0xff) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_FRAC0, (UINT_16) FracN & 0xff); ++ if(Max3543_Write(pTuner, REG3543_FRAC0, (UINT_16) FracN & 0xff) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Program tracking filters and other frequency dependent registers */ ++// MAX3543_SetTrackingFilter(RF_Frequency); ++ if(MAX3543_SetTrackingFilter(pTuner, RF_Frequency) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++/*As you tune in frequency, the tracking filter needs ++to be set as a function of frequency. Stored in the ROM on the ++IC are two end points for the VHFL, VHFH, and UHF frequency bands. ++This routine performs the necessary function to calculate the ++needed series and parallel capacitor values from these two end ++points for the current frequency. Once the value is calculated, ++it is loaded into the Tracking Filter Caps register and the ++internal capacitors are switched in tuning the tracking ++filter. ++*/ ++int MAX3543_SetTrackingFilter(TUNER_MODULE *pTuner, UINT_16 RF_Frequency) ++{ ++ /* Calculate the series and parallel capacitor values for the given frequency */ ++ /* band. These values are then written to the registers. This causes the */ ++ /* MAX3543's internal series and parallel capacitors to change thus tuning the */ ++ /* tracking filter to the proper frequency. */ ++ ++ UINT_16 TFB, tfs, tfp, RFin, HRF; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ /* Set the TFB Bits (Tracking Filter Band) for the given frequency. */ ++ if (RF_Frequency < scalefrq(196)) /* VHF Low Band */ ++ { ++ TFB = VHF_L; ++ } ++ else if (RF_Frequency < scalefrq(440)) /* VHF High 196-440 MHz */ ++ { ++ TFB = VHF_H; ++ } ++ else{ /* UHF */ ++ TFB = UHF; ++ } ++ ++ /* Set the RFIN bit. RFIN selects a input low pass filter */ ++ if (RF_Frequency < scalefrq(345)){ /* 345 MHz is the change over point. */ ++ RFin = 0; ++ } ++ else{ ++ RFin = 1; ++ } ++ ++ if (RF_Frequency < scalefrq(110)){ /* 110 MHz is the change over point. */ ++ HRF = 1; ++ } ++ else{ ++ HRF = 0; ++ } ++ ++ /* Write the TFB<1:0> Bits and the RFIN bit into the IFOVLD register */ ++ /* TFB sets the tracking filter band in the chip, RFIN selects the RF input */ ++ pExtra->regs[REG3543_MODE] = (pExtra->regs[REG3543_MODE] & 0x93 ) | (TFB << 2) | (RFin << 6) | (HRF<<5); ++// Max3543_Write(REG3543_MODE,(regs[REG3543_MODE])) ; ++ if(Max3543_Write(pTuner, REG3543_MODE,(pExtra->regs[REG3543_MODE])) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ tfs = tfs_i(pExtra->TFRomCoefs[TFB][SER0], pExtra->TFRomCoefs[TFB][SER1], RF_Frequency/pExtra->LOSCALE, co[TFB*2]); ++ tfp = tfs_i(pExtra->TFRomCoefs[TFB][PAR0], pExtra->TFRomCoefs[TFB][PAR1], RF_Frequency/pExtra->LOSCALE, co[(TFB*2)+1]); ++ ++ /* Write the TFS Bits into the Tracking Filter Series Capacitor register */ ++ if (tfs > 255) /* 255 = 8 bits of TFS */ ++ tfs = 255; ++ if (tfs < 0) ++ tfs = 0; ++ pExtra->regs[REG3543_TFS] = tfs; ++ ++ /* Write the TFP Bits into the Tracking Filter Parallel Capacitor register */ ++ if (tfp > 63) /* 63 = 6 bits of TFP */ ++ tfp = 63; ++ if (tfp < 0) ++ tfp = 0; ++ pExtra->regs[REG3543_TFP] = (pExtra->regs[REG3543_TFP] & 0xc0 ) | tfp; ++ ++ /* Send registers that have been changed */ ++ /* Maxim evkit I2c communication... Replace by microprocessor specific code */ ++// Max3543_Write(REG3543_TFS,(regs[REG3543_TFS])) ; ++ if(Max3543_Write(pTuner, REG3543_TFS,(pExtra->regs[REG3543_TFS])) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_TFP,(regs[REG3543_TFP])) ; ++ if(Max3543_Write(pTuner, REG3543_TFP,(pExtra->regs[REG3543_TFP])) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++ ++ ++/* calculate aproximation for Max3540 tracking filter useing integer math only */ ++ ++UINT_16 tfs_i(UINT_16 S0, UINT_16 S1, UINT_16 FreqRF, const UINT_16 c[5]) ++{ UINT_16 i,y,y1,y2,y3,y4,y5,y6,y7,add; ++ UINT_32 res; ++ ++/* y=4*((64*c[0])+c[1]*S0)-((64*c[2]-(S1*c[3]))*(FreqRF))/250; */ ++ y1=64*c[0]; ++ y2=c[1]*S0; ++ y3=4*(y1+y2); ++ y4=S1*c[3]; ++ y5=64*c[2]; ++ y6=y5-y4; ++ y7=(y6*(FreqRF))/250; ++ if (y7((UINT_32)100*c[4])) res=(res+50*1)/100-c[4]; ++ else res=0; ++ ++ if (res<255) return (UINT_16) res; else return 255; ++} ++ ++/* ++ As soon as you program the Frac0 register, a state machine is started to find the ++ correct VCO for the N and Fractional-N values entered. ++ If the VASS bit is set, the search routine will start from the band and ++ sub-band that is currently programmed into the VCO register (VCO and VSUB bits = seed). ++ If you seed the register with bands close to where the auto routine will ++ finally select, the search routine will finish much faster. ++ This routine determines the best seed to use for the VCO and VSUB values. ++ If VASS is cleared, the search will start as the lowest VCO and search up. ++ This takes much longer. Make sure VASS is set before using this routine. ++ For the seed value to be read in the VCO register, it must be there prior to ++ setting the Frac0 register. So call this just before setting the Fractional-N ++ registers. The VASS bit is bit 5 of register 10 (or REG3543_VAS). ++*/ ++int MAX3543_SeedVCO(TUNER_MODULE *pTuner, UINT_16 Fvco){ ++ /* Fvco is the VCO frequency in MHz and is not scaled by LOSCALE */ ++ UINT_16 VCO; ++ UINT_16 VSUB; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ if (Fvco <= 2750) ++ { ++ /* The VCO seed: */ ++ ++ VCO = 0; ++ /* Determine the VCO sub-band (VSUB) seed: */ ++ if (Fvco < 2068) ++ VSUB = 0; ++ else if (Fvco < 2101) ++ VSUB = 1; ++ else if (Fvco < 2137) ++ VSUB = 2; ++ else if (Fvco < 2174) ++ VSUB = 3; ++ else if (Fvco < 2215) ++ VSUB = 4; ++ else if (Fvco < 2256) ++ VSUB = 5; ++ else if (Fvco < 2300) ++ VSUB = 6; ++ else if (Fvco < 2347) ++ VSUB = 7; ++ else if (Fvco < 2400) ++ VSUB = 8; ++ else if (Fvco < 2453) ++ VSUB = 9; ++ else if (Fvco < 2510) ++ VSUB = 10; ++ else if (Fvco < 2571) ++ VSUB = 11; ++ else if (Fvco < 2639) ++ VSUB = 12; ++ else if (Fvco < 2709) ++ VSUB = 13; ++ else if (Fvco < 2787) ++ VSUB = 14; ++ } ++ else if (Fvco <= 3650) ++ { ++ /* The VCO seed: */ ++ VCO = 1; ++ /* Determine the VCO sub-band (VSUB) seed: */ ++ if (Fvco <= 2792) ++ VSUB = 1; ++ else if (Fvco <= 2839) ++ VSUB = 2; ++ else if (Fvco <= 2890) ++ VSUB = 3; ++ else if (Fvco <= 2944) ++ VSUB = 4; ++ else if (Fvco <= 3000) ++ VSUB = 5; ++ else if (Fvco <= 3059) ++ VSUB = 6; ++ else if (Fvco <= 3122) ++ VSUB = 7; ++ else if (Fvco <= 3194) ++ VSUB = 8; ++ else if (Fvco <= 3266) ++ VSUB = 9; ++ else if (Fvco <= 3342) ++ VSUB = 10; ++ else if (Fvco <= 3425) ++ VSUB = 11; ++ else if (Fvco <= 3516) ++ VSUB = 12; ++ else if (Fvco <= 3612) ++ VSUB = 13; ++ else if (Fvco <= 3715) ++ VSUB = 14; ++ } ++ else ++ { ++ /* The VCO seed: */ ++ VCO = 2; ++ /* Determine the VCO sub-band (VSUB) seed: */ ++ if (Fvco <= 3658) ++ VSUB = 0; ++ else if (Fvco <= 3716) ++ VSUB = 2; ++ else if (Fvco <= 3776) ++ VSUB = 2; ++ else if (Fvco <= 3840) ++ VSUB = 3; ++ else if (Fvco <= 3909) ++ VSUB = 4; ++ else if (Fvco <= 3980) ++ VSUB = 5; ++ else if (Fvco <= 4054) ++ VSUB = 6; ++ else if (Fvco <= 4134) ++ VSUB = 7; ++ else if (Fvco <= 4226) ++ VSUB = 8; ++ else if (Fvco <= 4318) ++ VSUB = 9; ++ else if (Fvco <= 4416) ++ VSUB = 10; ++ else if (Fvco <= 4520) ++ VSUB = 11; ++ else if (Fvco <= 4633) ++ VSUB = 12; ++ else if (Fvco <= 4751) ++ VSUB = 13; ++ else if (Fvco <= 4876) ++ VSUB = 14; ++ else ++ VSUB = 15; ++ } ++ /* VCO = D<7:6>, VSUB = D<5:2> */ ++ pExtra->regs[REG3543_VCO] = (pExtra->regs[REG3543_VCO] & 3) | (VSUB<<2) | (VCO<<6); ++ /* Program the VCO register with the seed: */ ++// Max3543_Write(REG3543_VCO, regs[REG3543_VCO]); ++ if(Max3543_Write(pTuner, REG3543_VCO, pExtra->regs[REG3543_VCO]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++/* Returns the lock detect status. This is accomplished by ++ examining the ADC value read from the MAX3543. The ADC ++ value is the tune voltage digitized. If it is too close to ++ ground or Vcc, the part is unlocked. The ADC ranges from 0-7. ++ Values 1 to 6 are considered locked. 0 or 7 is unlocked. ++ Returns True for locked, fase for unlocked. ++*/ ++int MAX3543_LockDetect(TUNER_MODULE *pTuner, int *pAnswer) ++{ ++// BOOL vcoselected; ++ int vcoselected; ++ UINT_16 tries = 65535; ++ char adc; ++ unsigned short Data; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ /* The ADC will not be stable until the VCO is selected. ++ usually the selection process will take 25ms or less but ++ it could theoretically take 100ms. Set tries to some number ++ of your processor clocks corresponding to 100ms. ++ You have to take into account all instructions processed ++ in determining this time. I am picking a value out of the air ++ for now. ++ */ ++ vcoselected = MAX_FALSE; ++ while ((--tries > 0) && (vcoselected == MAX_FALSE)) ++ { ++// if ((Max3543_Read(REG3543_VAS_STATUS) & 1) == 1) ++ if(Max3543_Read(pTuner, REG3543_VAS_STATUS, &Data) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ if ((Data & 1) == 1) ++ vcoselected = MAX_TRUE; ++ } ++ /* open the ADC latch: ADL=0, ADE=1 */ ++ pExtra->regs[REG3543_VAS] = (pExtra->regs[REG3543_VAS] & 0xf3) | 4; ++// Max3543_Write(REG3543_VAS, regs[REG3543_VAS]); ++ if(Max3543_Write(pTuner, REG3543_VAS, pExtra->regs[REG3543_VAS]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* ADC = 3 LSBs of Gen Status Register: */ ++// adc = Max3543_Read(REG3543_GEN_STATUS) & 0x7; ++ if(Max3543_Read(pTuner, REG3543_GEN_STATUS, &Data) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ adc = Data & 0x7; ++ ++ ++ ++ ++ /* locked if ADC within range of 1-6: */ ++ if ((adc<1 ) || (adc>6)) ++ return MAX_FALSE; ++ else ++ return MAX_TRUE; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++int MAX3543_ReadROM(TUNER_MODULE *pTuner) ++{ ++ unsigned short Data; ++ ++ /* Read the ROM table, extract tracking filter ROM coefficients, ++ IRHR and CFSET constants. ++ This is to be called after the Max3543 powers up. ++ */ ++ UINT_16 rom_data[11]; ++ UINT_16 i; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ for (i=0; i <= 10; i++) ++ { ++// Max3543_Write(REG3543_ROM_ADDR,i); /*Select ROM Row by setting address register */ ++ if(Max3543_Write(pTuner, REG3543_ROM_ADDR,i) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; /*Select ROM Row by setting address register */ ++ ++// rom_data[i] = Max3543_Read(REG3543_ROM_READ); /* Read from ROMR Register */ ++ if(Max3543_Read(pTuner, REG3543_ROM_READ, &Data) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ rom_data[i] = Data; /* Read from ROMR Register */ ++ } ++ ++ ++ /* The ROM address must be returned to 0 for normal operation or the part will not be biased properly. */ ++// Max3543_Write(REG3543_ROM_ADDR,0); ++ if(Max3543_Write(pTuner, REG3543_ROM_ADDR,0) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Copy all of ROM Row 10 to Filt_CF register. */ ++// Max3543_Write(REG3543_FILT_CF,rom_data[10]); ++ if(Max3543_Write(pTuner, REG3543_FILT_CF,rom_data[10]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Copy the IRHR ROM value to the IRHR register: */ ++// Max3543_Write(REG3543_IRHR, rom_data[0xb]); ++ if(Max3543_Write(pTuner, REG3543_IRHR, rom_data[0xb]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ /* assemble the broken up word pairs from the ROM table into complete ROM coefficients: */ ++ pExtra->TFRomCoefs[VHF_L][SER0] = (rom_data[1] & 0xFC) >> 2; /*'LS0 )*/ ++ pExtra->TFRomCoefs[VHF_L][SER1] = ((rom_data[1] & 0x3 ) << 4) + ((rom_data[2] & 0xf0) >> 4); /* 'LS1*/ ++ pExtra->TFRomCoefs[VHF_L][PAR0] = ((rom_data[2] & 0xf) << 2) + ((rom_data[3] & 0xc0) >> 6); /*'LP0*/ ++ pExtra->TFRomCoefs[VHF_L][PAR1] = rom_data[3] & 0x3f; /*LP1 */ ++ ++ pExtra->TFRomCoefs[VHF_H][SER0] = ((rom_data[4] & 0xfc) >> 2); /*'HS0 */ ++ pExtra->TFRomCoefs[VHF_H][SER1] = ((rom_data[4] & 0x3) << 4) + ((rom_data[5] & 0xF0) >> 4); /*'HS1 */ ++ pExtra->TFRomCoefs[VHF_H][PAR0] = ((rom_data[5] & 0xf) << 2) + ((rom_data[6] & 0xc0) >> 6); /*'HP0 */ ++ pExtra->TFRomCoefs[VHF_H][PAR1] = rom_data[6] & 0x3F; /*'HP1 */ ++ ++ pExtra->TFRomCoefs[UHF][SER0] = ((rom_data[7] & 0xFC) >> 2); /*'US0 */ ++ pExtra->TFRomCoefs[UHF][SER1] = ((rom_data[7] & 0x3) << 4) + ((rom_data[8] & 0xf0) >> 4 ); /*'US1 */ ++ pExtra->TFRomCoefs[UHF][PAR0] = ((rom_data[8] & 0xF) << 2) + ((rom_data[9] & 0xc0) >> 6); /*'UP0 */ ++ pExtra->TFRomCoefs[UHF][PAR1] = rom_data[9] & 0x3f; /*'UP1 */ ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++ } ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_max3543.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_max3543.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_max3543.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_max3543.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,521 @@ ++#ifndef __TUNER_MAX3543_H ++#define __TUNER_MAX3543_H ++ ++/** ++ ++@file ++ ++@brief MAX3543 tuner module declaration ++ ++One can manipulate MAX3543 tuner through MAX3543 module. ++MAX3543 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_max3543.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MAX3543_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build MAX3543 tuner module. ++ BuildMax3543Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0, // I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // Crystal frequency is 16.0 MHz. ++ MAX3543_STANDARD_DVBT, // The MAX3543 standard mode is DVB-T. ++ IF_FREQ_36170000HZ, // The MAX3543 IF frequency is 36.17 MHz. ++ MAX3543_SAW_INPUT_SE // The MAX3543 SAW input type is single-ended. ++ ); ++ ++ ++ ++ ++ ++ // Get MAX3543 tuner extra module. ++ pTunerExtra = (MAX3543_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MAX3543 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, MAX3543_BANDWIDTH_7MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MAX3543 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is implemented for MAX3543 source code. ++ ++ ++// Definition (implemeted for MAX3543) ++ ++// Function return status ++#define MAX3543_SUCCESS 1 ++#define MAX3543_ERROR 0 ++ ++ ++ ++// Function (implemeted for MAX3543) ++int ++Max3543_Read( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short *pData ++ ); ++ ++int ++Max3543_Write( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short Data ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Analog Devices. ++ ++ ++ ++ ++ ++// MAXIM source code - mxmdef.h ++ ++ ++ ++//#ifndef MXMDEF_H ++//#define MXMDEF_H ++ ++#define MAX_PATH 260 ++/* ++#ifndef NULL ++#ifdef __cplusplus ++#define NULL 0 ++#else ++#define NULL ((void *)0) ++#endif ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++*/ ++ ++#define MAX_FALSE 0 ++#define MAX_TRUE 1 ++ ++ ++typedef unsigned long DWORD; ++ ++//#endif /* _WINDEF_ */ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MAXIM source code - Max3543_Driver.h ++ ++ ++ ++ /* ++------------------------------------------------------ ++| Max3543_Driver.h, v 1.0.3, 12/9/2009, Paul Nichol ++| Description: Max3543 Driver Includes. ++| ++| Copyright (C) 2009 Maxim Integrated Products ++| ++------------------------------------------------------ ++*/ ++ ++ ++ ++ ++//#ifndef Max3543_Driver_H ++ ++/* integer only mode = 1, floating point mode = 0 */ ++//#define intmode 0 ++ ++ ++//#define Max3543_Driver_H ++ ++ ++#define MAX3543_ADDR 0xc0 ++ ++#define MAX3543_NUMREGS 0x15 ++ ++ ++/* Register Address offsets. Used when sending or indexing registers. */ ++#define REG3543_VCO 0 ++#define REG3543_NDIV 0x1 ++#define REG3543_FRAC2 0x2 ++#define REG3543_FRAC1 0x3 ++#define REG3543_FRAC0 0x4 ++#define REG3543_MODE 0x5 ++#define REG3543_TFS 0x6 ++#define REG3543_TFP 0x7 ++#define REG3543_SHDN 0x8 ++#define REG3543_REF 0x9 ++#define REG3543_VAS 0xa ++#define REG3543_PD_CFG1 0xb ++#define REG3543_PD_CFG2 0xc ++#define REG3543_FILT_CF 0xd ++#define REG3543_ROM_ADDR 0xe ++#define REG3543_IRHR 0xf ++#define REG3543_ROM_READ 0x10 ++#define REG3543_VAS_STATUS 0x11 ++#define REG3543_GEN_STATUS 0x12 ++#define REG3543_BIAS_ADJ 0x13 ++#define REG3543_TEST1 0x14 ++#define REG3543_ROM_WRITE 0x15 ++ ++/* Band constants: */ ++#define VHF_L 0 ++#define VHF_H 1 ++#define UHF 2 ++ ++/* Channel Bandwidth: */ ++#define BW7MHZ 0 ++#define BW8MHZ 1 ++ ++#define SER0 0 ++#define SER1 1 ++#define PAR0 2 ++#define PAR1 3 ++ ++ ++ ++ ++typedef enum {IFOUT1_DIFF_DTVOUT, IFOUT1_SE_DTVOUT,IFOUT2} outputmode; ++ ++typedef enum {DVB_T, DVB_C, ATV, ATV_SECAM_L} standard; ++ ++//standard broadcast_standard; ++ ++ ++ ++/* Note: ++ The SetFrequency() routine must make it's calculations without ++ overflowing 32 bit accumulators. This is a difficult balance of LO, IF and Xtal frequencies. ++ Scaling factors are applied to these frequencies to keep the numbers below the 32 bit result during ++ caltculations. The calculations have been checked for only the following combinations of frequencies ++ and settings: Xtal freqencies of 16.0MHz, 20.25 MHz, 20.48 MHz; IF Frequencies of 30.0 MHz and 30.15MHz; ++ R-Dividers /1 and /2. Any combination of the above numbers may be used. ++ If other combinations or frequencies are needed, the scaling factors: LOSCALE and XTALSCALE must be ++ recalculated. This has been done in a spreadsheet calc.xls. Without checking these ++ scale factors carefully, there could be overflow and tuning errors or amplitude losses due to an ++ incorrect tracking filter setting. ++*/ ++ ++ ++#define scalefrq(x) ( (UINT_32) ( ( (UINT_16) x) * (UINT_16) pExtra->LOSCALE ) ) ++ ++ ++ ++ ++ ++#define ATV_SINGLE 2 ++ ++typedef short INT_16; /* compiler type for 16 bit integer */ ++typedef unsigned short UINT_16; /* compiler type for 16 bit unsigned integer */ ++typedef unsigned long UINT_32; /* compiler type for 32 bit unsigned integer */ ++ ++typedef enum {IFOUT_1,IFOUT_2} outmd; ++ ++//int MAX3543_Init(TUNER_MODULE *pTuner, UINT_16 RfFreq); ++int MAX3543_Init(TUNER_MODULE *pTuner); ++int MAX3543_SetFrequency(TUNER_MODULE *pTuner, UINT_16 RF_Frequency); ++//unsigned short MAX3543_Read(UINT_16 reg); ++//void MAX3543_Write(UINT_16 reg, UINT_16 value); ++int MAX3543_LockDetect(TUNER_MODULE *pTuner, int *pAnswer); ++int MAX3543_Standard(TUNER_MODULE *pTuner, standard bcstd, outputmode outmd); ++int MAX3543_ChannelBW(TUNER_MODULE *pTuner, UINT_16 bw); ++int MAX3543_SetTrackingFilter(TUNER_MODULE *pTuner, UINT_16 RF_Frequency); ++int MAX3543_ReadROM(TUNER_MODULE *pTuner); ++UINT_16 tfs_i(UINT_16 S0, UINT_16 S1, UINT_16 FreqRF, const UINT_16 c[5]); ++int MAX3543_SeedVCO(TUNER_MODULE *pTuner, UINT_16 Fvco); ++ ++ ++//////////////// External functions called by Max3543 code ///////////// ++// The implementation of these functions is left for the end user. ++// This is because of the many different microcontrollers and serial ++// I/O methods that can be used. ++// void Max3543_Write(unsigned short RegAddr, unsigned short data); ++// This function sends out a byte of data using the following format. ++// Start, IC_address, ACK, Register Address, Ack, Data, Ack, Stop ++// IC_address is 0xC0 or 0xC4 depending on JP8 of the Max3543 evkit board. ++// 0xC0 if the ADDR pin of the Max3543 is low, x0C4 if the pin is high. ++// The register address is the Index into the register ++// you wish to fill. ++// unsigned short Max3543_Read(unsigned short reg); ++// This reads and returns a byte from the Max3543. ++// The read sequence is: ++// Start, IC_address, ACK, Register Address, ack, Start, DeviceReadAddress, ack, ++// Data, NAck, Stop ++// Note that there is a IC_Address (0xC0 or 0xC4 as above) and a Device Read ++// Address which is the IC_Address + 1 (0xC1 or 0xC5). ++// There are also two start conditions in the read back sequence. ++// The Register Address is an index into the register you ++// wish to read back ++//#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MAX3543 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Standard mode ++enum MAX3543_STANDARD_MODE ++{ ++ MAX3543_STANDARD_DVBT = DVB_T, ++ MAX3543_STANDARD_QAM = DVB_C, ++}; ++ ++ ++// Bandwidth mode ++enum MAX3543_BANDWIDTH_MODE ++{ ++ MAX3543_BANDWIDTH_7000000HZ = BW7MHZ, ++ MAX3543_BANDWIDTH_8000000HZ = BW8MHZ, ++}; ++ ++ ++// SAW input type ++enum MAX3543_SAW_INPUT_TYPE ++{ ++ MAX3543_SAW_INPUT_DIFF = IFOUT1_DIFF_DTVOUT, ++ MAX3543_SAW_INPUT_SE = IFOUT1_SE_DTVOUT, ++}; ++ ++ ++ ++// Default for initialing ++#define MAX3543_RF_FREQ_HZ_DEFAULT 474000000 ++#define MAX3543_BANDWIDTH_MODE_DEFAULT MAX3543_BANDWIDTH_8000000HZ ++ ++ ++// Definition for RF frequency setting. ++#define MAX3543_CONST_1_MHZ 1000000 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMax3543Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int OutputMode ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++max3543_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++max3543_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++max3543_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++max3543_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++max3543_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++max3543_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++max3543_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2063.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2063.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2063.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2063.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,5264 @@ ++/** ++ ++@file ++ ++@brief MT2063 tuner module definition ++ ++One can manipulate MT2063 tuner through MT2063 module. ++MT2063 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_mt2063.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MT2063 tuner module builder ++ ++Use BuildMt2063Module() to build MT2063 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MT2063 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MT2063 I2C device address ++@param [in] IfFreqHz MT2063 output IF frequency in Hz ++@param [in] StandardMode Standard mode ++@param [in] IfVgaGainControl IF VGA gain control ++ ++ ++@note ++ -# One should call BuildMt2063Module() to build MT2063 module before using it. ++ ++*/ ++void ++BuildMt2063Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ int StandardMode, ++ unsigned long VgaGc ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MT2063; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = mt2063_GetTunerType; ++ pTuner->GetDeviceAddr = mt2063_GetDeviceAddr; ++ ++ pTuner->Initialize = mt2063_Initialize; ++ pTuner->SetRfFreqHz = mt2063_SetRfFreqHz; ++ pTuner->GetRfFreqHz = mt2063_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->StandardMode = StandardMode; ++ pExtra->VgaGc = VgaGc; ++ pExtra->IsIfFreqHzSet = NO; ++ pExtra->IsBandwidthHzSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->OpenHandle = mt2063_OpenHandle; ++ pExtra->CloseHandle = mt2063_CloseHandle; ++ pExtra->GetHandle = mt2063_GetHandle; ++ pExtra->SetIfFreqHz = mt2063_SetIfFreqHz; ++ pExtra->GetIfFreqHz = mt2063_GetIfFreqHz; ++ pExtra->SetBandwidthHz = mt2063_SetBandwidthHz; ++ pExtra->GetBandwidthHz = mt2063_GetBandwidthHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++mt2063_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++mt2063_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++mt2063_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Re-initialize tuner. ++ Status = MT2063_ReInit(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner output bandwidth. ++// Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_BW, MT2063_BANDWIDTH_6MHZ); ++ ++// if(MT_IS_ERROR(Status)) ++// goto error_status_execute_function; ++ ++ ++ // Set tuner parameters according to standard mode. ++ switch(pExtra->StandardMode) ++ { ++ default: ++ case MT2063_STANDARD_DVBT: ++ ++ Status = MT2063_SetParam(DeviceHandle, MT2063_RCVR_MODE, MT2063_OFFAIR_COFDM); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case MT2063_STANDARD_QAM: ++ ++ Status = MT2063_SetParam(DeviceHandle, MT2063_RCVR_MODE, MT2063_CABLE_QAM); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ // Set tuner VGAGC with IF AGC gain control setting value. ++ Status = MT2063_SetParam(DeviceHandle, MT2063_VGAGC, (UData_t)(pExtra->VgaGc)); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++mt2063_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner RF frequency in Hz. ++ Status = MT2063_Tune(DeviceHandle, RfFreqHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++mt2063_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Open MT2063 tuner handle. ++ ++*/ ++int ++mt2063_OpenHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ unsigned char DeviceAddr; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner I2C device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Open MT2063 handle. ++ // Note: 1. Must take tuner extra module DeviceHandle as handle input argument. ++ // 2. Take pTuner as user-defined data input argument. ++ Status = MT2063_Open(DeviceAddr, &pExtra->DeviceHandle, pTuner); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2063_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2063_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Close MT2063 tuner handle. ++ ++*/ ++int ++mt2063_CloseHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Close MT2063 handle. ++ Status = MT2063_Close(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2063_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2063_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2063 tuner handle. ++ ++*/ ++void ++mt2063_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ *pDeviceHandle = pExtra->DeviceHandle; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MT2063 tuner IF frequency in Hz. ++ ++*/ ++int ++mt2063_SetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ unsigned int IfFreqHzUint; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner output IF frequency. ++ IfFreqHzUint = (unsigned int)IfFreqHz; ++ Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_FREQ, IfFreqHzUint); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner IF frequnecy parameter in tuner extra module. ++ pExtra->IfFreqHz = IfFreqHz; ++ pExtra->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2063 tuner IF frequency in Hz. ++ ++*/ ++int ++mt2063_GetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ // Get tuner IF frequency in Hz from tuner extra module. ++ if(pExtra->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pExtra->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MT2063 tuner bandwidth in Hz. ++ ++*/ ++// Note: The function MT2063_SetParam() only sets software bandwidth variables, ++// so execute MT2063_Tune() after this function. ++int ++mt2063_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++// unsigned long BandwidthHzWithShift; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner bandwidth in Hz with shift. ++// BandwidthHzWithShift = BandwidthHz - MT2063_BANDWIDTH_SHIFT_HZ; ++// Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_BW, BandwidthHzWithShift); ++ Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_BW, BandwidthHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthHz = BandwidthHz; ++ pExtra->IsBandwidthHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2063 tuner bandwidth in Hz. ++ ++*/ ++int ++mt2063_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ // Get tuner bandwidth in Hz from tuner module. ++ if(pExtra->IsBandwidthHzSet != YES) ++ goto error_status_get_tuner_bandwidth; ++ ++ *pBandwidthHz = pExtra->BandwidthHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.c ++** ++** Description: User-defined MicroTuner software interface ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.c,v 1.2 2008/11/05 13:46:20 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_userdef.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++//#include "mt_userdef.h" ++ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++// UData_t status = MT_OK; /* Status to be returned */ ++ /* ++ ** ToDo: Add code here to implement a serial-bus write ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i, j; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pWritingBytes; ++ unsigned long ByteNum; ++ ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pWritingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set tuner register bytes with writing bytes. ++ // Note: Set tuner register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + ++ // stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++// UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to implement a serial-bus read ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pReadingBytes; ++ unsigned long ByteNum; ++ ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pReadingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get tuner register bytes. ++ // Note: Get tuner register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register bytes. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2063_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime) ++{ ++ /* ++ ** ToDo: Add code here to implement a OS blocking ++ ** for a period of "nMinDelayTime" milliseconds. ++ */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get tuner module, base interface. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ // Wait nMinDelayTime milliseconds. ++ pBaseInterface->WaitMs(pBaseInterface, nMinDelayTime); ++ ++ ++ return; ++} ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to return the gain / power level measured ++ ** at the input to the demodulator. ++ */ ++ ++ ++ ++ return (status); ++} ++#endif ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_2063.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt2063.c ++** ++** Copyright 2007-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2063.c ++** ++** Description: Microtune MT2063 B0, B1 & B3 Tuner software interface ++** Supports tuners with Part/Rev code: 0x9B - 0x9E. ++** ++** Functions ++** Implemented: UData_t MT2063_Open ++** UData_t MT2063_Close ++** UData_t MT2063_ClearPowerMaskBits ++** UData_t MT2063_GetGPIO ++** UData_t MT2063_GetLocked ++** UData_t MT2063_GetParam ++** UData_t MT2063_GetPowerMaskBits ++** UData_t MT2063_GetReg ++** UData_t MT2063_GetTemp ++** UData_t MT2063_GetUserData ++** UData_t MT2063_ReInit ++** UData_t MT2063_SetGPIO ++** UData_t MT2063_SetParam ++** UData_t MT2063_SetPowerMaskBits ++** UData_t MT2063_SetReg ++** UData_t MT2063_Tune ++** ++** References: AN-00189: MT2063 Programming Procedures Application Note ++** MicroTune, Inc. ++** AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for nMinDelayTime milliseconds ++** ++** CVS ID: $Id: mt2063.c,v 1.6 2009/04/29 09:58:14 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt2063.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** N/A 08-01-2007 PINZ Ver 1.01: Changed Analog &DVB-T settings and added ++** SAW-less receiver mode. ++** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference ++** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements ++** 150 09-10-2007 RSK Ver 1.04: Added GetParam/SetParam support for ++** LO1 and LO2 freq for PHY-21 cal. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive ++** modulation ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have ++** the same settings as with MT Launcher ++** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI ++** Add SetParam DNC_OUTPUT_ENABLE ++** Removed VGAGC from receiver mode, ++** default now 3 ++** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode ++** Add SetParam AMPGC, removed from rcvr-mode ++** Corrected names of GCU values ++** reorganized receiver modes, removed, ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** Actualized Receiver-Mode values ++** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values ++** N/A 11-27-2007 PINZ Improved buffered writing ++** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for ++** correct wakeup of the LNA after shutdown ++** Set AFCsd = 1 as default ++** Changed CAP1sel default ++** 01-14-2008 PINZ Ver 1.11: Updated gain settings, default for VGAGC 3 ++** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW ++** in GetParam. ++** 03-18-2008 PINZ Ver 1.13: Added Support for MT2063 B3 ++** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune ++** cross-over frequency values. ++** Documentation Updates ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 189 S 05-13-2008 PINZ Ver 1.16: Correct location for ExtSRO control. ++** Add control to avoid DECT freqs. ++** Updated Receivermodes for MT2063 B3 ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** 08-05-2008 PINZ Ver 1.20: Disable SDEXT pin while MT2063_ReInit ++** with MT2063B3 ++** 09-18-2008 PINZ Ver 1.22: Updated values for CTFILT_SW ++** 205 M 10-01-2008 JWS Ver 1.23: Use DMAX when LO2 FracN is near 4096 ++** M 10-24-2008 JWS Ver 1.25: Use DMAX when LO1 FracN is 32 ++** 11-05-2008 PINZ Ver 1.26: Minor code fixes ++** 01-07-2009 PINZ Ver 1.27: Changed value of MT2063_ALL_SD in .h ++** 01-20-2009 PINZ Ver 1.28: Fixed a compare to avoid compiler warning ++** 02-16-2009 PINZ Ver 1.29: Several fixes to improve compiler behavior ++** N/A I 02-26-2009 PINZ Ver 1.30: RCVRmode 2: acfifmax 29->0, pd2tgt 33->34 ++** RCVRmode 4: acfifmax 29->0, pd2tgt 30->34 ++** N/A I 03-02-2009 PINZ Ver 1.31: new default Fout 43.75 -> 36.125MHz ++** new default Output-BW 6 -> 8MHz ++** new default Stepsize 50 -> 62.5kHz ++** new default Fin 651 -> 666 MHz ++** Changed order of receiver-mode init ++** N/A I 03-19-2009 PINZ Ver 1.32: Add GetParam VERSION (of API) ++** Add GetParam IC_REV ++** N/A I 04-22-2009 PINZ Ver 1.33: Small fix in GetParam PD1/PD2 ++** N/A I 04-29-2009 PINZ Ver 1.34: Optimized ReInit function ++** ++*****************************************************************************/ ++//#include "mt2063.h" ++//#include "mt_spuravoid.h" ++//#include /* for NULL */ ++#define MT_NULL 0 ++ ++/* Version of this module */ ++#define MT2063_VERSION 10304 /* Version 01.34 */ ++ ++ ++/* ++** The expected version of MT_AvoidSpursData_t ++** If the version is different, an updated file is needed from Microtune ++*/ ++/* Expecting version 1.21 of the Spur Avoidance API */ ++#define EXPECTED_MT_AVOID_SPURS_INFO_VERSION 010201 ++ ++#if MT2063_AVOID_SPURS_INFO_VERSION < EXPECTED_MT_AVOID_SPURS_INFO_VERSION ++#error Contact Microtune for a newer version of MT_SpurAvoid.c ++#elif MT2063_AVOID_SPURS_INFO_VERSION > EXPECTED_MT_AVOID_SPURS_INFO_VERSION ++#error Contact Microtune for a newer version of mt2063.c ++#endif ++ ++#ifndef MT2063_CNT ++#error You must define MT2063_CNT in the "mt_userdef.h" file ++#endif ++ ++ ++/* ++** Two-wire serial bus subaddresses of the tuner registers. ++** Also known as the tuner's register addresses. ++*/ ++enum MT2063_Register_Offsets ++{ ++ PART_REV = 0, /* 0x00: Part/Rev Code */ ++ LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */ ++ LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */ ++ LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */ ++ LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */ ++ LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */ ++ RSVD_06, /* 0x06: Reserved */ ++ LO_STATUS, /* 0x07: LO Status */ ++ FIFFC, /* 0x08: FIFF Center */ ++ CLEARTUNE, /* 0x09: ClearTune Filter */ ++ ADC_OUT, /* 0x0A: ADC_OUT */ ++ LO1C_1, /* 0x0B: LO1C Byte 1 */ ++ LO1C_2, /* 0x0C: LO1C Byte 2 */ ++ LO2C_1, /* 0x0D: LO2C Byte 1 */ ++ LO2C_2, /* 0x0E: LO2C Byte 2 */ ++ LO2C_3, /* 0x0F: LO2C Byte 3 */ ++ RSVD_10, /* 0x10: Reserved */ ++ PWR_1, /* 0x11: PWR Byte 1 */ ++ PWR_2, /* 0x12: PWR Byte 2 */ ++ TEMP_STATUS, /* 0x13: Temp Status */ ++ XO_STATUS, /* 0x14: Crystal Status */ ++ RF_STATUS, /* 0x15: RF Attn Status */ ++ FIF_STATUS, /* 0x16: FIF Attn Status */ ++ LNA_OV, /* 0x17: LNA Attn Override */ ++ RF_OV, /* 0x18: RF Attn Override */ ++ FIF_OV, /* 0x19: FIF Attn Override */ ++ LNA_TGT, /* 0x1A: Reserved */ ++ PD1_TGT, /* 0x1B: Pwr Det 1 Target */ ++ PD2_TGT, /* 0x1C: Pwr Det 2 Target */ ++ RSVD_1D, /* 0x1D: Reserved */ ++ RSVD_1E, /* 0x1E: Reserved */ ++ RSVD_1F, /* 0x1F: Reserved */ ++ RSVD_20, /* 0x20: Reserved */ ++ BYP_CTRL, /* 0x21: Bypass Control */ ++ RSVD_22, /* 0x22: Reserved */ ++ RSVD_23, /* 0x23: Reserved */ ++ RSVD_24, /* 0x24: Reserved */ ++ RSVD_25, /* 0x25: Reserved */ ++ RSVD_26, /* 0x26: Reserved */ ++ RSVD_27, /* 0x27: Reserved */ ++ FIFF_CTRL, /* 0x28: FIFF Control */ ++ FIFF_OFFSET, /* 0x29: FIFF Offset */ ++ CTUNE_CTRL, /* 0x2A: Reserved */ ++ CTUNE_OV, /* 0x2B: Reserved */ ++ CTRL_2C, /* 0x2C: Reserved */ ++ FIFF_CTRL2, /* 0x2D: Fiff Control */ ++ RSVD_2E, /* 0x2E: Reserved */ ++ DNC_GAIN, /* 0x2F: DNC Control */ ++ VGA_GAIN, /* 0x30: VGA Gain Ctrl */ ++ RSVD_31, /* 0x31: Reserved */ ++ TEMP_SEL, /* 0x32: Temperature Selection */ ++ RSVD_33, /* 0x33: Reserved */ ++ FN_CTRL, /* 0x34: FracN Control */ ++ RSVD_35, /* 0x35: Reserved */ ++ RSVD_36, /* 0x36: Reserved */ ++ RSVD_37, /* 0x37: Reserved */ ++ RSVD_38, /* 0x38: Reserved */ ++ RSVD_39, /* 0x39: Reserved */ ++ RSVD_3A, /* 0x3A: Reserved */ ++ RSVD_3B, /* 0x3B: Reserved */ ++ RSVD_3C, /* 0x3C: Reserved */ ++ END_REGS ++}; ++ ++ ++/* ++** Constants used by the tuning algorithm ++*/ ++#define REF_FREQ (16000000) /* Reference oscillator Frequency (in Hz) */ ++#define IF1_BW (22000000) /* The IF1 filter bandwidth (in Hz) */ ++#define TUNE_STEP_SIZE (62500) /* Tune in steps of 62.5 kHz */ ++#define SPUR_STEP_HZ (250000) /* Step size (in Hz) to move IF1 when avoiding spurs */ ++#define ZIF_BW (2000000) /* Zero-IF spur-free bandwidth (in Hz) */ ++#define MAX_HARMONICS_1 (15) /* Highest intra-tuner LO Spur Harmonic to be avoided */ ++#define MAX_HARMONICS_2 (5) /* Highest inter-tuner LO Spur Harmonic to be avoided */ ++#define MIN_LO_SEP (1000000) /* Minimum inter-tuner LO frequency separation */ ++#define LO1_FRACN_AVOID (0) /* LO1 FracN numerator avoid region (in Hz) */ ++#define LO2_FRACN_AVOID (199999) /* LO2 FracN numerator avoid region (in Hz) */ ++#define MIN_FIN_FREQ (44000000) /* Minimum input frequency (in Hz) */ ++#define MAX_FIN_FREQ (1100000000) /* Maximum input frequency (in Hz) */ ++#define DEF_FIN_FREQ (666000000) /* Default frequency at initialization (in Hz) */ ++#define MIN_FOUT_FREQ (36000000) /* Minimum output frequency (in Hz) */ ++#define MAX_FOUT_FREQ (57000000) /* Maximum output frequency (in Hz) */ ++#define MIN_DNC_FREQ (1293000000) /* Minimum LO2 frequency (in Hz) */ ++#define MAX_DNC_FREQ (1614000000) /* Maximum LO2 frequency (in Hz) */ ++#define MIN_UPC_FREQ (1396000000) /* Minimum LO1 frequency (in Hz) */ ++#define MAX_UPC_FREQ (2750000000U) /* Maximum LO1 frequency (in Hz) */ ++ ++ ++typedef struct ++{ ++ Handle_t handle; ++ Handle_t hUserData; ++ UData_t address; ++ UData_t version; ++ UData_t tuner_id; ++ MT2063_AvoidSpursData_t AS_Data; ++ UData_t f_IF1_actual; ++ UData_t rcvr_mode; ++ UData_t ctfilt_sw; ++ UData_t CTFiltMax[31]; ++ UData_t num_regs; ++ U8Data reg[END_REGS]; ++} MT2063_Info_t; ++ ++static UData_t nMaxTuners = MT2063_CNT; ++static MT2063_Info_t MT2063_Info[MT2063_CNT]; ++static MT2063_Info_t *Avail[MT2063_CNT]; ++static UData_t nOpenTuners = 0; ++ ++ ++/* ++** Constants for setting receiver modes. ++** (6 modes defined at this time, enumerated by MT2063_RCVR_MODES) ++** (DNC1GC & DNC2GC are the values, which are used, when the specific ++** DNC Output is selected, the other is always off) ++** ++** If PAL-L or L' is received, set: ++** MT2063_SetParam(hMT2063,MT2063_TAGC,1); ++** ++** --------------+---------------------------------------------- ++** Mode 0 : | MT2063_CABLE_QAM ++** Mode 1 : | MT2063_CABLE_ANALOG ++** Mode 2 : | MT2063_OFFAIR_COFDM ++** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS ++** Mode 4 : | MT2063_OFFAIR_ANALOG ++** Mode 5 : | MT2063_OFFAIR_8VSB ++** --------------+----+----+----+----+-----+-----+-------------- ++** Mode | 0 | 1 | 2 | 3 | 4 | 5 | ++** --------------+----+----+----+----+-----+-----+ ++** ++** ++*/ ++static const U8Data RFAGCEN[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data LNARIN[] = { 0, 0, 3, 3, 3, 3 }; ++static const U8Data FIFFQEN[] = { 1, 1, 1, 1, 1, 1 }; ++static const U8Data FIFFQ[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data DNC1GC[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data DNC2GC[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 }; ++static const U8Data LNATGT[] = { 44, 43, 43, 43, 43, 43 }; ++static const U8Data RFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data ACRFMAX[] = { 31, 31, 31, 31, 31, 31 }; ++static const U8Data PD1TGT[] = { 36, 36, 38, 38, 36, 38 }; ++static const U8Data FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data ACFIFMAX[] = { 29, 0, 29, 29, 0, 29 }; ++static const U8Data PD2TGT[] = { 40, 34, 38, 42, 34, 38 }; ++ ++ ++static const UData_t df_dosc[] = { ++ 55000, 127000, 167000, 210000, 238000, 267000, 312000, 350000, ++ 372000, 396000, 410000, 421000, 417000, 408000, 387000, 278000, ++ 769000, 816000, 824000, 848000, 903000, 931000, 934000, 961000, ++ 969000, 987000,1005000,1017000, 1006000, 840000, 850000, 0 ++ }; ++ ++ ++/* Forward declaration(s): */ ++static UData_t CalcLO1Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); ++static UData_t CalcLO2Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); ++static UData_t fLO_FractionalTerm(UData_t f_ref, UData_t num, UData_t denom); ++static UData_t FindClearTuneFilter(MT2063_Info_t* pInfo, UData_t f_in); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: MT2063_Addr - Serial bus address of the tuner. ++** hMT2063 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_NULL - Null pointer argument passed ++** MT_COMM_ERR - Serial bus communications error ++** MT_TUNER_CNT_ERR - Too many tuners open ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Open(UData_t MT2063_Addr, ++ Handle_t* hMT2063, ++ Handle_t hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned. */ ++ SData_t i; ++ MT2063_Info_t* pInfo = MT_NULL; ++ ++ /* Check the argument before using */ ++ if (hMT2063 == MT_NULL) ++ return (UData_t)MT_ARG_NULL; ++ ++ /* Default tuner handle to NULL. If successful, it will be reassigned */ ++ *hMT2063 = MT_NULL; ++ ++ /* ++ ** If this is our first tuner, initialize the address fields and ++ ** the list of available control blocks. ++ */ ++ if (nOpenTuners == 0) ++ { ++ for (i=MT2063_CNT-1; i>=0; i--) ++ { ++ MT2063_Info[i].handle = MT_NULL; ++ MT2063_Info[i].address = (UData_t)MAX_UDATA; ++ MT2063_Info[i].rcvr_mode = MT2063_CABLE_QAM; ++ MT2063_Info[i].hUserData = MT_NULL; ++ Avail[i] = &MT2063_Info[i]; ++ } ++ } ++ ++ /* ++ ** Look for an existing MT2063_State_t entry with this address. ++ */ ++ for (i=MT2063_CNT-1; i>=0; i--) ++ { ++ /* ++ ** If an open'ed handle provided, we'll re-initialize that structure. ++ ** ++ ** We recognize an open tuner because the address and hUserData are ++ ** the same as one that has already been opened ++ */ ++ if ((MT2063_Info[i].address == MT2063_Addr) && ++ (MT2063_Info[i].hUserData == hUserData)) ++ { ++ pInfo = &MT2063_Info[i]; ++ break; ++ } ++ } ++ ++ /* If not found, choose an empty spot. */ ++ if (pInfo == MT_NULL) ++ { ++ /* Check to see that we're not over-allocating */ ++ if (nOpenTuners == MT2063_CNT) ++ return (UData_t)MT_TUNER_CNT_ERR; ++ ++ /* Use the next available block from the list */ ++ pInfo = Avail[nOpenTuners]; ++ nOpenTuners++; ++ } ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_RegisterTuner(&pInfo->AS_Data); ++ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->handle = (Handle_t) pInfo; ++ pInfo->hUserData = hUserData; ++ pInfo->address = MT2063_Addr; ++ pInfo->rcvr_mode = MT2063_CABLE_QAM; ++// status |= MT2063_ReInit((Handle_t) pInfo); ++ } ++ ++ if (MT_IS_ERROR(status)) ++ /* MT2063_Close handles the un-registration of the tuner */ ++ (void)MT2063_Close((Handle_t) pInfo); ++ else ++ *hMT2063 = pInfo->handle; ++ ++ return (UData_t)(status); ++} ++ ++ ++static UData_t IsValidHandle(MT2063_Info_t* handle) ++{ ++ return (UData_t)(((handle != MT_NULL) && (handle->handle == handle)) ? 1 : 0); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2063 - Handle to the MT2063 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Close(Handle_t hMT2063) ++{ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) hMT2063; ++ ++ if (!IsValidHandle(pInfo)) ++ return (UData_t)MT_INV_HANDLE; ++ ++ /* Unregister tuner with SpurAvoidance routines (if needed) */ ++ MT2063_UnRegisterTuner(&pInfo->AS_Data); ++ ++ /* Now remove the tuner from our own list of tuners */ ++ pInfo->handle = MT_NULL; ++ pInfo->address = (UData_t)(MAX_UDATA);//4294967295 ++ pInfo->hUserData = MT_NULL; ++ nOpenTuners--; ++ Avail[nOpenTuners] = pInfo; /* Return control block to available list */ ++ ++ return (UData_t)MT_OK; ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetGPIO ++** ++** Description: Get the current MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** gpio_id - Selects GPIO0, GPIO1 or GPIO2 ++** attr - Selects input readback, I/O direction or ++** output value (MT2063_GPIO_IN, ++** MT2063_GPIO_DIR or MT2063_GPIO_OUT) ++** *value - current setting of GPIO pin ++** ++** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO0, ++** MT2063_GPIO_OUT, &value); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetGPIO(Handle_t h, ++ MT2063_GPIO_ID gpio_id, ++ MT2063_GPIO_Attr attr, ++ UData_t* value) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data regno; ++ SData_t shift; ++ const U8Data GPIOreg[3] = {RF_STATUS, FIF_OV, RF_OV}; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ if (value == MT_NULL) ++ return (UData_t)MT_ARG_NULL; ++ ++ regno = GPIOreg[attr]; ++ ++ /* We'll read the register just in case the write didn't work last time */ ++ status = MT2063_ReadSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1); ++ ++ shift = (SData_t)(gpio_id - MT2063_GPIO0 + 5); ++ *value = (pInfo->reg[regno] >> shift) & 1; ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetLocked ++** ++** Description: Checks to see if LO1 and LO2 are locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetLocked(Handle_t h) ++{ ++ const UData_t nMaxWait = 100; /* wait a maximum of 100 msec */ ++ const UData_t nPollRate = 2; /* poll status bits every 2 ms */ ++ const UData_t nMaxLoops = nMaxWait / nPollRate; ++ const U8Data LO1LK = 0x80; ++ U8Data LO2LK = 0x08; ++ UData_t status = MT_OK; /* Status to be returned */ ++ UData_t nDelays = 0; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ /* LO2 Lock bit was in a different place for B0 version */ ++ if (pInfo->tuner_id == MT2063_B0) ++ LO2LK = 0x40; ++ ++ do ++ { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, LO_STATUS, &pInfo->reg[LO_STATUS], 1); ++ ++ if (MT_IS_ERROR(status)) ++ return (UData_t)(status); ++ ++ if ((pInfo->reg[LO_STATUS] & (LO1LK | LO2LK)) == (LO1LK | LO2LK)) ++ return (UData_t)(status); ++ ++ MT2063_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */ ++ } ++ while (++nDelays < nMaxLoops); ++ ++ if ((pInfo->reg[LO_STATUS] & LO1LK) == 0x00) ++ status |= MT_UPC_UNLOCK; ++ if ((pInfo->reg[LO_STATUS] & LO2LK) == 0x00) ++ status |= MT_DNC_UNLOCK; ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_VERSION Version of the API ++** MT2063_IC_ADDR Serial Bus address of this tuner ++** MT2063_IC_REV Tuner revision code ++** MT2063_MAX_OPEN Max # of MT2063's allowed open ++** MT2063_NUM_OPEN # of MT2063's open ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_INPUT_FREQ input center frequency ++** MT2063_LO1_FREQ LO1 Frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_ACTUAL Current 1st IF in use ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_IF1_CENTER Center of 1st IF SAW filter ++** MT2063_IF1_BW Bandwidth of 1st IF SAW filter ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 Frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_AS_ALG ID of avoid-spurs algorithm in use ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_EXCL_ZONES # of 1st IF exclusion zones ++** MT2063_NUM_SPURS # of spurs found/avoided ++** MT2063_SPUR_AVOIDED >0 spurs avoided ++** MT2063_SPUR_PRESENT >0 spurs in output (mathematically) ++** MT2063_RCVR_MODE Predefined modes. ++** MT2063_LNA_RIN Get LNA RIN value ++** MT2063_LNA_TGT Get target power level at LNA ++** MT2063_PD1_TGT Get target power level at PD1 ++** MT2063_PD2_TGT Get target power level at PD2 ++** MT2063_ACLNA LNA attenuator gain code ++** MT2063_ACRF RF attenuator gain code ++** MT2063_ACFIF FIF attenuator gain code ++** MT2063_ACLNA_MAX LNA attenuator limit ++** MT2063_ACRF_MAX RF attenuator limit ++** MT2063_ACFIF_MAX FIF attenuator limit ++** MT2063_PD1 Actual value of PD1 ++** MT2063_PD2 Actual value of PD2 ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** Usage: status |= MT2063_GetParam(hMT2063, ++** MT2063_IF1_ACTUAL, ++** &f_IF1_Actual); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_SetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW ++** in GetParam. ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** N/A I 03-19-2009 PINZ Ver 1.32: Add GetParam VERSION (of API) ++** Add GetParam IC_REV ++** N/A I 04-22-2009 PINZ Ver 1.33: Small fix in GetParam PD1/PD2 ++****************************************************************************/ ++UData_t MT2063_GetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t* pValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ UData_t Div; ++ UData_t Num; ++ UData_t i; ++ U8Data reg; ++ ++ if (pValue == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ *pValue = 0; ++ ++ switch (param) ++ { ++ /* version of the API, e.g. 10302 = 1.32 */ ++ case MT2063_VERSION: ++ *pValue = pInfo->version; ++ break; ++ ++ /* Serial Bus address of this tuner */ ++ case MT2063_IC_ADDR: ++ *pValue = pInfo->address; ++ break; ++ ++ /* tuner revision code (see enum MT2063_REVCODE for values) */ ++ case MT2063_IC_REV: ++ *pValue = pInfo->tuner_id; ++ break; ++ ++ /* Max # of MT2063's allowed to be open */ ++ case MT2063_MAX_OPEN: ++ *pValue = nMaxTuners; ++ break; ++ ++ /* # of MT2063's open */ ++ case MT2063_NUM_OPEN: ++ *pValue = nOpenTuners; ++ break; ++ ++ /* crystal frequency */ ++ case MT2063_SRO_FREQ: ++ *pValue = pInfo->AS_Data.f_ref; ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2063_STEPSIZE: ++ *pValue = pInfo->AS_Data.f_LO2_Step; ++ break; ++ ++ /* input center frequency */ ++ case MT2063_INPUT_FREQ: ++ *pValue = pInfo->AS_Data.f_in; ++ break; ++ ++ /* LO1 Frequency */ ++ case MT2063_LO1_FREQ: ++ { ++ /* read the actual tuner register values for LO1C_1 and LO1C_2 */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, LO1C_1, &pInfo->reg[LO1C_1], 2); ++ Div = pInfo->reg[LO1C_1]; ++ Num = pInfo->reg[LO1C_2] & 0x3F; ++ pInfo->AS_Data.f_LO1 = (pInfo->AS_Data.f_ref * Div) + fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 64); ++ *pValue = pInfo->AS_Data.f_LO1; ++ } ++ break; ++ ++ /* LO1 minimum step size */ ++ case MT2063_LO1_STEPSIZE: ++ *pValue = pInfo->AS_Data.f_LO1_Step; ++ break; ++ ++ /* LO1 FracN keep-out region */ ++ case MT2063_LO1_FRACN_AVOID: ++ *pValue = pInfo->AS_Data.f_LO1_FracN_Avoid; ++ break; ++ ++ /* Current 1st IF in use */ ++ case MT2063_IF1_ACTUAL: ++ *pValue = pInfo->f_IF1_actual; ++ break; ++ ++ /* Requested 1st IF */ ++ case MT2063_IF1_REQUEST: ++ *pValue = pInfo->AS_Data.f_if1_Request; ++ break; ++ ++ /* Center of 1st IF SAW filter */ ++ case MT2063_IF1_CENTER: ++ *pValue = pInfo->AS_Data.f_if1_Center; ++ break; ++ ++ /* Bandwidth of 1st IF SAW filter */ ++ case MT2063_IF1_BW: ++ *pValue = pInfo->AS_Data.f_if1_bw; ++ break; ++ ++ /* zero-IF bandwidth */ ++ case MT2063_ZIF_BW: ++ *pValue = pInfo->AS_Data.f_zif_bw; ++ break; ++ ++ /* LO2 Frequency */ ++ case MT2063_LO2_FREQ: ++ { ++ /* Read the actual tuner register values for LO2C_1, LO2C_2 and LO2C_3 */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, LO2C_1, &pInfo->reg[LO2C_1], 3); ++ Div = (pInfo->reg[LO2C_1] & 0xFE ) >> 1; ++ Num = ((pInfo->reg[LO2C_1] & 0x01 ) << 12) | (pInfo->reg[LO2C_2] << 4) | (pInfo->reg[LO2C_3] & 0x00F); ++ pInfo->AS_Data.f_LO2 = (pInfo->AS_Data.f_ref * Div) + fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 8191); ++ *pValue = pInfo->AS_Data.f_LO2; ++ } ++ break; ++ ++ /* LO2 minimum step size */ ++ case MT2063_LO2_STEPSIZE: ++ *pValue = pInfo->AS_Data.f_LO2_Step; ++ break; ++ ++ /* LO2 FracN keep-out region */ ++ case MT2063_LO2_FRACN_AVOID: ++ *pValue = pInfo->AS_Data.f_LO2_FracN_Avoid; ++ break; ++ ++ /* output center frequency */ ++ case MT2063_OUTPUT_FREQ: ++ *pValue = pInfo->AS_Data.f_out; ++ break; ++ ++ /* output bandwidth */ ++ case MT2063_OUTPUT_BW: ++ *pValue = pInfo->AS_Data.f_out_bw - 750000; ++ break; ++ ++ /* min inter-tuner LO separation */ ++ case MT2063_LO_SEPARATION: ++ *pValue = pInfo->AS_Data.f_min_LO_Separation; ++ break; ++ ++ /* ID of avoid-spurs algorithm in use */ ++ case MT2063_AS_ALG: ++ *pValue = pInfo->AS_Data.nAS_Algorithm; ++ break; ++ ++ /* max # of intra-tuner harmonics */ ++ case MT2063_MAX_HARM1: ++ *pValue = pInfo->AS_Data.maxH1; ++ break; ++ ++ /* max # of inter-tuner harmonics */ ++ case MT2063_MAX_HARM2: ++ *pValue = pInfo->AS_Data.maxH2; ++ break; ++ ++ /* # of 1st IF exclusion zones */ ++ case MT2063_EXCL_ZONES: ++ *pValue = pInfo->AS_Data.nZones; ++ break; ++ ++ /* # of spurs found/avoided */ ++ case MT2063_NUM_SPURS: ++ *pValue = pInfo->AS_Data.nSpursFound; ++ break; ++ ++ /* >0 spurs avoided */ ++ case MT2063_SPUR_AVOIDED: ++ *pValue = pInfo->AS_Data.bSpurAvoided; ++ break; ++ ++ /* >0 spurs in output (mathematically) */ ++ case MT2063_SPUR_PRESENT: ++ *pValue = pInfo->AS_Data.bSpurPresent; ++ break; ++ ++ /* Predefined receiver setup combination */ ++ case MT2063_RCVR_MODE: ++ *pValue = pInfo->rcvr_mode; ++ break; ++ ++ case MT2063_PD1: ++ case MT2063_PD2: ++ { ++ reg = pInfo->reg[BYP_CTRL] | ( (param == MT2063_PD1 ? 0x01 : 0x03) & 0x03 ); /* PD1 vs PD2 */ ++ ++ /* Initiate ADC output to reg 0x0A */ ++ if (reg != pInfo->reg[BYP_CTRL]) ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, ®, 1); ++ ++ if (MT_IS_ERROR(status)) ++ return (UData_t)(status); ++ ++ for (i=0; i<8; i++) { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, ADC_OUT, &pInfo->reg[ADC_OUT], 1); ++ ++ if (MT_NO_ERROR(status)) ++ *pValue += (pInfo->reg[ADC_OUT] >> 2); /* only want 6 MSB's out of 8 */ ++ else ++ break; /* break for-loop */ ++ } ++ *pValue /= (i+1); /* divide by number of reads */ ++ ++ /* Restore value of Register BYP_CTRL */ ++ if (reg != pInfo->reg[BYP_CTRL]) ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, &pInfo->reg[BYP_CTRL], 1); ++ } ++ break; ++ ++ ++ /* Get LNA RIN value */ ++ case MT2063_LNA_RIN: ++ status |= (pInfo->reg[CTRL_2C] & 0x03); ++ break; ++ ++ /* Get LNA target value */ ++ case MT2063_LNA_TGT: ++ status |= (pInfo->reg[LNA_TGT] & 0x3f); ++ break; ++ ++ /* Get PD1 target value */ ++ case MT2063_PD1_TGT: ++ status |= (pInfo->reg[PD1_TGT] & 0x3f); ++ break; ++ ++ /* Get PD2 target value */ ++ case MT2063_PD2_TGT: ++ status |= (pInfo->reg[PD2_TGT] & 0x3f); ++ break; ++ ++ /* Get LNA attenuator code */ ++ case MT2063_ACLNA: ++ { ++ status |= MT2063_GetReg(pInfo, XO_STATUS, ®); ++ *pValue = reg & 0x1f; ++ } ++ break; ++ ++ /* Get RF attenuator code */ ++ case MT2063_ACRF: ++ { ++ status |= MT2063_GetReg(pInfo, RF_STATUS, ®); ++ *pValue = reg & 0x1f; ++ } ++ break; ++ ++ /* Get FIF attenuator code */ ++ case MT2063_ACFIF: ++ { ++ status |= MT2063_GetReg(pInfo, FIF_STATUS, ®); ++ *pValue = reg & 0x1f; ++ } ++ break; ++ ++ /* Get LNA attenuator limit */ ++ case MT2063_ACLNA_MAX: ++ status |= (pInfo->reg[LNA_OV] & 0x1f); ++ break; ++ ++ /* Get RF attenuator limit */ ++ case MT2063_ACRF_MAX: ++ status |= (pInfo->reg[RF_OV] & 0x1f); ++ break; ++ ++ /* Get FIF attenuator limit */ ++ case MT2063_ACFIF_MAX: ++ status |= (pInfo->reg[FIF_OV] & 0x1f); ++ break; ++ ++ /* Get current used DNC output */ ++ case MT2063_DNC_OUTPUT_ENABLE: ++ { ++ if ( (pInfo->reg[DNC_GAIN] & 0x03) == 0x03) /* if DNC1 is off */ ++ { ++ if ( (pInfo->reg[VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ ++ *pValue = (UData_t)MT2063_DNC_NONE; ++ else ++ *pValue = (UData_t)MT2063_DNC_2; ++ } ++ else /* DNC1 is on */ ++ { ++ if ( (pInfo->reg[VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ ++ *pValue = (UData_t)MT2063_DNC_1; ++ else ++ *pValue = (UData_t)MT2063_DNC_BOTH; ++ } ++ } ++ break; ++ ++ /* Get VGA Gain Code */ ++ case MT2063_VGAGC: ++ *pValue = ( (pInfo->reg[VGA_GAIN] & 0x0C) >> 2 ); ++ break; ++ ++ /* Get VGA bias current */ ++ case MT2063_VGAOI: ++ *pValue = (pInfo->reg[RSVD_31] & 0x07); ++ break; ++ ++ /* Get TAGC setting */ ++ case MT2063_TAGC: ++ *pValue = (pInfo->reg[RSVD_1E] & 0x03); ++ break; ++ ++ /* Get AMP Gain Code */ ++ case MT2063_AMPGC: ++ *pValue = (pInfo->reg[TEMP_SEL] & 0x03); ++ break; ++ ++ /* Avoid DECT Frequencies */ ++ case MT2063_AVOID_DECT: ++ *pValue = pInfo->AS_Data.avoidDECT; ++ break; ++ ++ /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ ++ case MT2063_CTFILT_SW: ++ *pValue = pInfo->ctfilt_sw; ++ break; ++ ++ case MT2063_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetReg ++** ++** Description: Gets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** *val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2063. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (val == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, reg, &pInfo->reg[reg], 1); ++ if (MT_NO_ERROR(status)) ++ *val = pInfo->reg[reg]; ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetTemp ++** ++** Description: Get the MT2063 Temperature register. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** *value - value read from the register ++** ++** Binary ++** Value Returned Value Approx Temp ++** --------------------------------------------- ++** MT2063_T_0C 0000 0C ++** MT2063_T_10C 0001 10C ++** MT2063_T_20C 0010 20C ++** MT2063_T_30C 0011 30C ++** MT2063_T_40C 0100 40C ++** MT2063_T_50C 0101 50C ++** MT2063_T_60C 0110 60C ++** MT2063_T_70C 0111 70C ++** MT2063_T_80C 1000 80C ++** MT2063_T_90C 1001 90C ++** MT2063_T_100C 1010 100C ++** MT2063_T_110C 1011 110C ++** MT2063_T_120C 1100 120C ++** MT2063_T_130C 1101 130C ++** MT2063_T_140C 1110 140C ++** MT2063_T_150C 1111 150C ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetTemp(Handle_t h, MT2063_Temperature* value) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ if (value == MT_NULL) ++ return (UData_t)MT_ARG_NULL; ++ ++ if ((MT_NO_ERROR(status)) && ((pInfo->reg[TEMP_SEL] & 0xE0) != 0x00)) ++ { ++ pInfo->reg[TEMP_SEL] &= (0x1F); ++ status |= MT2063_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ TEMP_SEL, ++ &pInfo->reg[TEMP_SEL], ++ 1); ++ } ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, ++ pInfo->address, ++ TEMP_STATUS, ++ &pInfo->reg[TEMP_STATUS], ++ 1); ++ ++ if (MT_NO_ERROR(status)) ++ *value = (MT2063_Temperature) (pInfo->reg[TEMP_STATUS] >> 4); ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetUserData(Handle_t h, ++ Handle_t* hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (hUserData == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (MT_NO_ERROR(status)) ++ *hUserData = pInfo->hUserData; ++ ++ return (UData_t)(status); ++} ++ ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_SetReceiverMode ++** ++** Description: Set the MT2063 receiver mode ++** ++** --------------+---------------------------------------------- ++** Mode 0 : | MT2063_CABLE_QAM ++** Mode 1 : | MT2063_CABLE_ANALOG ++** Mode 2 : | MT2063_OFFAIR_COFDM ++** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS ++** Mode 4 : | MT2063_OFFAIR_ANALOG ++** Mode 5 : | MT2063_OFFAIR_8VSB ++** --------------+----+----+----+----+-----+-------------------- ++** (DNC1GC & DNC2GC are the values, which are used, when the specific ++** DNC Output is selected, the other is always off) ++** ++** |<---------- Mode -------------->| ++** Reg Field | 0 | 1 | 2 | 3 | 4 | 5 | ++** ------------+-----+-----+-----+-----+-----+-----+ ++** RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF | ++** LNARin | 0 | 0 | 3 | 3 | 3 | 3 | ++** FIFFQen | 1 | 1 | 1 | 1 | 1 | 1 | ++** FIFFq | 0 | 0 | 0 | 0 | 0 | 0 | ++** DNC1gc | 0 | 0 | 0 | 0 | 0 | 0 | ++** DNC2gc | 0 | 0 | 0 | 0 | 0 | 0 | ++** LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31 | ++** LNA Target | 44 | 43 | 43 | 43 | 43 | 43 | ++** ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0 | ++** RF max Atn | 31 | 31 | 31 | 31 | 31 | 31 | ++** PD1 Target | 36 | 36 | 38 | 38 | 36 | 38 | ++** ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0 | ++** FIF max Atn | 29 | 0 | 29 | 29 | 0 | 29 | ++** PD2 Target | 40 | 34 | 38 | 42 | 34 | 38 | ++** ++** ++** Parameters: pInfo - ptr to MT2063_Info_t structure ++** Mode - desired reciever mode ++** ++** Usage: status = MT2063_SetReceiverMode(hMT2063, Mode); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT2063_SetReg - Write a byte of data to a HW register. ++** Assumes that the tuner cache is valid. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** N/A 01-10-2007 PINZ Added additional GCU Settings, FIFF Calib will be triggered ++** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive ++** modulation ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have ++** the same settings as with MT Launcher ++** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI ++** Add SetParam DNC_OUTPUT_ENABLE ++** Removed VGAGC from receiver mode, ++** default now 1 ++** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode ++** Add SetParam AMPGC, removed from rcvr-mode ++** Corrected names of GCU values ++** reorganized receiver modes, removed, ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** Actualized Receiver-Mode values ++** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values ++** N/A 11-27-2007 PINZ Improved buffered writing ++** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for ++** correct wakeup of the LNA after shutdown ++** Set AFCsd = 1 as default ++** Changed CAP1sel default ++** 01-14-2008 PINZ Ver 1.11: Updated gain settings ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 11-05-2008 PINZ Ver 1.25: Bugfix, update rcvr_mode var earlier. ++** N/A I 02-26-2009 PINZ Ver 1.30: RCVRmode 2: acfifmax 29->0, pd2tgt 33->34 ++** RCVRmode 4: acfifmax 29->0, pd2tgt 30->34 ++** ++******************************************************************************/ ++static UData_t MT2063_SetReceiverMode(MT2063_Info_t* pInfo, MT2063_RCVR_MODES Mode) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data val; ++ UData_t longval; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ if (Mode >= MT2063_NUM_RCVR_MODES) ++ status = MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ pInfo->rcvr_mode = Mode; ++ ++ /* RFAGCen */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[PD1_TGT] & (U8Data)~0x40) | (RFAGCEN[Mode] ? 0x40 : 0x00); ++ if( pInfo->reg[PD1_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD1_TGT, val); ++ } ++ } ++ ++ /* LNARin */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_LNA_RIN, LNARIN[Mode]); ++ } ++ ++ /* FIFFQEN and FIFFQ */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[FIFF_CTRL2] & (U8Data)~0xF0) | (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4); ++ if( pInfo->reg[FIFF_CTRL2] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, FIFF_CTRL2, val); ++ /* trigger FIFF calibration, needed after changing FIFFQ */ ++ val = (pInfo->reg[FIFF_CTRL] | (U8Data)0x01); ++ status |= MT2063_SetReg(pInfo, FIFF_CTRL, val); ++ val = (pInfo->reg[FIFF_CTRL] & (U8Data)~0x01); ++ status |= MT2063_SetReg(pInfo, FIFF_CTRL, val); ++ } ++ } ++ ++ /* DNC1GC & DNC2GC */ ++ status |= MT2063_GetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, &longval); ++ status |= MT2063_SetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, longval); ++ ++ /* acLNAmax */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_ACLNA_MAX, ACLNAMAX[Mode]); ++ } ++ ++ /* LNATGT */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_LNA_TGT, LNATGT[Mode]); ++ } ++ ++ /* ACRF */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_ACRF_MAX, ACRFMAX[Mode]); ++ } ++ ++ /* PD1TGT */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_PD1_TGT, PD1TGT[Mode]); ++ } ++ ++ /* FIFATN */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_ACFIF_MAX, ACFIFMAX[Mode]); ++ } ++ ++ /* PD2TGT */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_PD2_TGT, PD2TGT[Mode]); ++ } ++ ++ /* Ignore ATN Overload */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[LNA_TGT] & (U8Data)~0x80) | (RFOVDIS[Mode] ? 0x80 : 0x00); ++ if( pInfo->reg[LNA_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, LNA_TGT, val); ++ } ++ } ++ ++ /* Ignore FIF Overload */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[PD1_TGT] & (U8Data)~0x80) | (FIFOVDIS[Mode] ? 0x80 : 0x00); ++ if( pInfo->reg[PD1_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD1_TGT, val); ++ } ++ } ++ ++ ++ return (UData_t)(status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference ++** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements ++** N/A 10-31-2007 PINZ Ver 1.08: Changed values suitable to rcvr-mode 0 ++** N/A 11-12-2007 PINZ Ver 1.09: Changed values suitable to rcvr-mode 0 ++** N/A 01-03-2007 PINZ Ver 1.10: Added AFCsd = 1 into defaults ++** N/A 01-04-2007 PINZ Ver 1.10: Changed CAP1sel default ++** 01-14-2008 PINZ Ver 1.11: Updated gain settings ++** 03-18-2008 PINZ Ver 1.13: Added Support for B3 ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 08-05-2008 PINZ Ver 1.20: Disable SDEXT pin while MT2063_ReInit ++** with MT2063B3 ++** N/A I 03-02-2009 PINZ Ver 1.31: new default Fout 43.75 -> 36.125MHz ++** new default Output-BW 6 -> 8MHz ++** new default Stepsize 50 -> 62.5kHz ++** new default Fin 651 -> 666 MHz ++** Changed order of receiver-mode init ++** N/A I 04-29-2009 PINZ Ver 1.34: Optimized ReInit function ++** ++******************************************************************************/ ++UData_t MT2063_ReInit(Handle_t h) ++{ ++ U8Data all_resets = 0xF0; /* reset/load bits */ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ UData_t rev=0; ++ ++ U8Data MT2063B0_defaults[] = { /* Reg, Value */ ++ 0x19, 0x05, ++ 0x1B, 0x1D, ++ 0x1C, 0x1F, ++ 0x1D, 0x0F, ++ 0x1E, 0x3F, ++ 0x1F, 0x0F, ++ 0x20, 0x3F, ++ 0x22, 0x21, ++ 0x23, 0x3F, ++ 0x24, 0x20, ++ 0x25, 0x3F, ++ 0x27, 0xEE, ++ 0x2C, 0x27, /* bit at 0x20 is cleared below */ ++ 0x30, 0x03, ++ 0x2C, 0x07, /* bit at 0x20 is cleared here */ ++ 0x2D, 0x87, ++ 0x2E, 0xAA, ++ 0x28, 0xE1, /* Set the FIFCrst bit here */ ++ 0x28, 0xE0, /* Clear the FIFCrst bit here */ ++ 0x00 }; ++ ++ /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ ++ U8Data MT2063B1_defaults[] = { /* Reg, Value */ ++ 0x05, 0xF0, ++ 0x11, 0x10, /* New Enable AFCsd */ ++ 0x19, 0x05, ++ 0x1A, 0x6C, ++ 0x1B, 0x24, ++ 0x1C, 0x28, ++ 0x1D, 0x8F, ++ 0x1E, 0x14, ++ 0x1F, 0x8F, ++ 0x20, 0x57, ++ 0x22, 0x21, /* New - ver 1.03 */ ++ 0x23, 0x3C, /* New - ver 1.10 */ ++ 0x24, 0x20, /* New - ver 1.03 */ ++ 0x2C, 0x24, /* bit at 0x20 is cleared below */ ++ 0x2D, 0x87, /* FIFFQ=0 */ ++ 0x2F, 0xF3, ++ 0x30, 0x0C, /* New - ver 1.11 */ ++ 0x31, 0x1B, /* New - ver 1.11 */ ++ 0x2C, 0x04, /* bit at 0x20 is cleared here */ ++ 0x28, 0xE1, /* Set the FIFCrst bit here */ ++ 0x28, 0xE0, /* Clear the FIFCrst bit here */ ++ 0x00 }; ++ ++ /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ ++ U8Data MT2063B3_defaults[] = { /* Reg, Value */ ++ 0x05, 0xF0, ++ 0x11, 0x13, /* disable SDEXT/INTsd for init */ ++ 0x2C, 0x24, /* bit at 0x20 is cleared below */ ++ 0x2C, 0x04, /* bit at 0x20 is cleared here */ ++ 0x28, 0xE1, /* Set the FIFCrst bit here */ ++ 0x28, 0xE0, /* Clear the FIFCrst bit here */ ++ 0x00 }; ++ ++ U8Data *def=MT2063B3_defaults; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* Read the Part/Rev code from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, PART_REV, pInfo->reg, 1); ++ ++ /* Read the Part/Rev codes (2nd byte) from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, RSVD_3B, &pInfo->reg[RSVD_3B], 2); ++ ++ if (MT_NO_ERROR(status)) { /* Check the part/rev code */ ++ switch (pInfo->reg[PART_REV]) { ++ case 0x9e : { ++ if ( (pInfo->reg[RSVD_3C] & 0x18) == 0x08 ) { ++ rev = MT2063_XX; ++ status |= MT_TUNER_ID_ERR; ++ } ++ else { ++ rev = MT2063_B3; ++ def = MT2063B3_defaults; ++ } ++ break; ++ } ++ case 0x9c : { ++ rev = MT2063_B1; ++ def = MT2063B1_defaults; ++ break; ++ } ++ case 0x9b : { ++ rev = MT2063_B0; ++ def = MT2063B0_defaults; ++ break; ++ } ++ default : { ++ rev = MT2063_XX; ++ status |= MT_TUNER_ID_ERR; ++ break; ++ } ++ } ++ } ++ ++ if (MT_NO_ERROR(status) /* Check the 2nd part/rev code */ ++ && ((pInfo->reg[RSVD_3B] & 0x80) != 0x00)) /* b7 != 0 ==> NOT MT2063 */ ++ status |= MT_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ ++ ++ /* Reset the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ LO2CQ_3, ++ &all_resets, ++ 1); ++ ++ while (MT_NO_ERROR(status) && *def) ++ { ++ U8Data reg = *def++; ++ U8Data val = *def++; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); ++ } ++ ++ /* Wait for FIFF location to complete. */ ++ if (MT_NO_ERROR(status)) ++ { ++ UData_t FCRUN = 1; ++ SData_t maxReads = 10; ++ while (MT_NO_ERROR(status) && (FCRUN != 0) && (maxReads-- > 0)) ++ { ++ MT2063_Sleep(pInfo->hUserData, 2); ++ status |= MT2063_ReadSub(pInfo->hUserData, ++ pInfo->address, ++ XO_STATUS, ++ &pInfo->reg[XO_STATUS], ++ 1); ++ FCRUN = (pInfo->reg[XO_STATUS] & 0x40) >> 6; ++ } ++ ++ if (FCRUN != 0) ++ status |= MT_TUNER_INIT_ERR | MT_TUNER_TIMEOUT; ++ ++ if (MT_NO_ERROR(status)) /* Re-read FIFFC value */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, FIFFC, &pInfo->reg[FIFFC], 1); ++ } ++ ++ /* Read back all the registers from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, ++ pInfo->address, ++ PART_REV, ++ pInfo->reg, ++ END_REGS); ++ ++ if (MT_NO_ERROR(status)) ++ { ++ /* Initialize the tuner state. */ ++ pInfo->version = MT2063_VERSION; ++ pInfo->tuner_id = rev; ++ pInfo->AS_Data.f_ref = REF_FREQ; ++ pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * ((UData_t) pInfo->reg[FIFFC] + 640); ++ pInfo->AS_Data.f_if1_bw = IF1_BW; ++ pInfo->AS_Data.f_out = 36125000; ++ pInfo->AS_Data.f_out_bw = 8000000; ++ pInfo->AS_Data.f_zif_bw = ZIF_BW; ++ pInfo->AS_Data.f_LO1_Step = pInfo->AS_Data.f_ref / 64; ++ pInfo->AS_Data.f_LO2_Step = TUNE_STEP_SIZE; ++ pInfo->AS_Data.maxH1 = MAX_HARMONICS_1; ++ pInfo->AS_Data.maxH2 = MAX_HARMONICS_2; ++ pInfo->AS_Data.f_min_LO_Separation = MIN_LO_SEP; ++ pInfo->AS_Data.f_if1_Request = pInfo->AS_Data.f_if1_Center; ++ pInfo->AS_Data.f_LO1 = 2181000000U; ++ pInfo->AS_Data.f_LO2 = 1486249786; ++ pInfo->f_IF1_actual = pInfo->AS_Data.f_if1_Center; ++ pInfo->AS_Data.f_in = pInfo->AS_Data.f_LO1 - pInfo->f_IF1_actual; ++ pInfo->AS_Data.f_LO1_FracN_Avoid = LO1_FRACN_AVOID; ++ pInfo->AS_Data.f_LO2_FracN_Avoid = LO2_FRACN_AVOID; ++ pInfo->num_regs = END_REGS; ++ pInfo->AS_Data.avoidDECT = MT_AVOID_BOTH; ++ pInfo->ctfilt_sw = 1; ++ } ++ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->CTFiltMax[ 0] = 69422000; ++ pInfo->CTFiltMax[ 1] = 106211000; ++ pInfo->CTFiltMax[ 2] = 140427000; ++ pInfo->CTFiltMax[ 3] = 177240000; ++ pInfo->CTFiltMax[ 4] = 213091000; ++ pInfo->CTFiltMax[ 5] = 241378000; ++ pInfo->CTFiltMax[ 6] = 274596000; ++ pInfo->CTFiltMax[ 7] = 309696000; ++ pInfo->CTFiltMax[ 8] = 342398000; ++ pInfo->CTFiltMax[ 9] = 378728000; ++ pInfo->CTFiltMax[10] = 416053000; ++ pInfo->CTFiltMax[11] = 456693000; ++ pInfo->CTFiltMax[12] = 496105000; ++ pInfo->CTFiltMax[13] = 534448000; ++ pInfo->CTFiltMax[14] = 572893000; ++ pInfo->CTFiltMax[15] = 603218000; ++ pInfo->CTFiltMax[16] = 632650000; ++ pInfo->CTFiltMax[17] = 668229000; ++ pInfo->CTFiltMax[18] = 710828000; ++ pInfo->CTFiltMax[19] = 735135000; ++ pInfo->CTFiltMax[20] = 765601000; ++ pInfo->CTFiltMax[21] = 809919000; ++ pInfo->CTFiltMax[22] = 842538000; ++ pInfo->CTFiltMax[23] = 863353000; ++ pInfo->CTFiltMax[24] = 911285000; ++ pInfo->CTFiltMax[25] = 942310000; ++ pInfo->CTFiltMax[26] = 977602000; ++ pInfo->CTFiltMax[27] = 1015100000; ++ pInfo->CTFiltMax[28] = 1053415000; ++ pInfo->CTFiltMax[29] = 1098330000; ++ pInfo->CTFiltMax[30] = 1138990000; ++ } ++ ++ /* ++ ** Fetch the FCU osc value and use it and the fRef value to ++ ** scale all of the Band Max values ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ UData_t fcu_osc; ++ UData_t i; ++ ++ pInfo->reg[CTUNE_CTRL] = 0x0A; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, CTUNE_CTRL, &pInfo->reg[CTUNE_CTRL], 1); ++ ++ /* Read the ClearTune filter calibration value */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, FIFFC, &pInfo->reg[FIFFC], 1); ++ fcu_osc = pInfo->reg[FIFFC]; ++ ++ pInfo->reg[CTUNE_CTRL] = 0x00; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, CTUNE_CTRL, &pInfo->reg[CTUNE_CTRL], 1); ++ ++ /* Adjust each of the values in the ClearTune filter cross-over table */ ++ for (i = 0; i < 31; i++) ++ { ++ if (fcu_osc>127) pInfo->CTFiltMax[i] += ( fcu_osc - 128 ) * df_dosc[i]; ++ else pInfo->CTFiltMax[i] -= ( 128 - fcu_osc ) * df_dosc[i]; ++ } ++ } ++ ++ /* ++ ** Set the default receiver mode ++ ** ++ */ ++ ++// if (MT_NO_ERROR(status) ) ++// { ++// status |= MT2063_SetParam(h,MT2063_RCVR_MODE,MT2063_CABLE_QAM); ++// } ++ ++ ++ /* ++ ** Tune to the default frequency ++ ** ++ */ ++ ++// if (MT_NO_ERROR(status) ) ++// { ++// status |= MT2063_Tune(h,DEF_FIN_FREQ); ++// } ++ ++ /* ++ ** Enable SDEXT pin again ++ ** ++ */ ++ ++ if ( (MT_NO_ERROR(status)) && (pInfo->tuner_id >= MT2063_B3) ) ++ { ++ status |= MT2063_SetReg(h,PWR_1,0x1b); ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_SetGPIO ++** ++** Description: Modify the MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** gpio_id - Selects GPIO0, GPIO1 or GPIO2 ++** attr - Selects input readback, I/O direction or ++** output value ++** value - value to set GPIO pin 15, 14 or 19 ++** ++** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_SetGPIO(Handle_t h, MT2063_GPIO_ID gpio_id, ++ MT2063_GPIO_Attr attr, ++ UData_t value) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data regno; ++ SData_t shift; ++ const U8Data GPIOreg[3] = {0x15, 0x19, 0x18}; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ regno = GPIOreg[attr]; ++ ++ shift = (SData_t)(gpio_id - MT2063_GPIO0 + 5); ++ ++ if (value & 0x01) ++ pInfo->reg[regno] |= (0x01 << shift); ++ else ++ pInfo->reg[regno] &= ~(0x01 << shift); ++ status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1); ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_LO1_FREQ LO1 frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_RCVR_MODE Predefined modes ++** MT2063_LNA_RIN Set LNA Rin (*) ++** MT2063_LNA_TGT Set target power level at LNA (*) ++** MT2063_PD1_TGT Set target power level at PD1 (*) ++** MT2063_PD2_TGT Set target power level at PD2 (*) ++** MT2063_ACLNA_MAX LNA attenuator limit (*) ++** MT2063_ACRF_MAX RF attenuator limit (*) ++** MT2063_ACFIF_MAX FIF attenuator limit (*) ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** (*) This parameter is set by MT2063_RCVR_MODE, do not call ++** additionally. ++** ++** Usage: status |= MT2063_SetParam(hMT2063, ++** MT2063_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_GetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 01-20-2009 PINZ Ver 1.28: Fixed a compare to avoid compiler warning ++** ++****************************************************************************/ ++UData_t MT2063_SetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t nValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data val=0; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ switch (param) ++ { ++ /* crystal frequency */ ++ case MT2063_SRO_FREQ: ++ pInfo->AS_Data.f_ref = nValue; ++ pInfo->AS_Data.f_LO1_FracN_Avoid = 0; ++ pInfo->AS_Data.f_LO2_FracN_Avoid = nValue / 80 - 1; ++ pInfo->AS_Data.f_LO1_Step = nValue / 64; ++ pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * (pInfo->reg[FIFFC] + 640); ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2063_STEPSIZE: ++ pInfo->AS_Data.f_LO2_Step = nValue; ++ break; ++ ++ ++ /* LO1 frequency */ ++ case MT2063_LO1_FREQ: ++ { ++ /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ ++ /* Capture the Divider and Numerator portions of other LO */ ++ U8Data tempLO2CQ[3]; ++ U8Data tempLO2C[3]; ++ U8Data tmpOneShot; ++ UData_t Div, FracN; ++ U8Data restore = 0; ++ ++ /* Buffer the queue for restoration later and get actual LO2 values. */ ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO2CQ_1, &(tempLO2CQ[0]), 3); ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO2C_1, &(tempLO2C[0]), 3); ++ ++ /* clear the one-shot bits */ ++ tempLO2CQ[2] = tempLO2CQ[2] & 0x0F; ++ tempLO2C[2] = tempLO2C[2] & 0x0F; ++ ++ /* only write the queue values if they are different from the actual. */ ++ if( ( tempLO2CQ[0] != tempLO2C[0] ) || ++ ( tempLO2CQ[1] != tempLO2C[1] ) || ++ ( tempLO2CQ[2] != tempLO2C[2] ) ) ++ { ++ /* put actual LO2 value into queue (with 0 in one-shot bits) */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_1, &(tempLO2C[0]), 3); ++ ++ if( status == MT_OK ) ++ { ++ /* cache the bytes just written. */ ++ pInfo->reg[LO2CQ_1] = tempLO2C[0]; ++ pInfo->reg[LO2CQ_2] = tempLO2C[1]; ++ pInfo->reg[LO2CQ_3] = tempLO2C[2]; ++ } ++ restore = 1; ++ } ++ ++ /* Calculate the Divider and Numberator components of LO1 */ ++ status = CalcLO1Mult(&Div, &FracN, nValue, pInfo->AS_Data.f_ref/64, pInfo->AS_Data.f_ref); ++ pInfo->reg[LO1CQ_1] = (U8Data)(Div & 0x00FF); ++ pInfo->reg[LO1CQ_2] = (U8Data)(FracN); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &pInfo->reg[LO1CQ_1], 2); ++ ++ /* set the one-shot bit to load the pair of LO values */ ++ tmpOneShot = tempLO2CQ[2] | 0xE0; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_3, &tmpOneShot, 1); ++ ++ /* only restore the queue values if they were different from the actual. */ ++ if( restore ) ++ { ++ /* put actual LO2 value into queue (0 in one-shot bits) */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_1, &(tempLO2CQ[0]), 3); ++ ++ /* cache the bytes just written. */ ++ pInfo->reg[LO2CQ_1] = tempLO2CQ[0]; ++ pInfo->reg[LO2CQ_2] = tempLO2CQ[1]; ++ pInfo->reg[LO2CQ_3] = tempLO2CQ[2]; ++ } ++ ++ status |= MT2063_GetParam( pInfo->hUserData, MT2063_LO1_FREQ, &pInfo->AS_Data.f_LO1 ); ++ } ++ break; ++ ++ /* LO1 minimum step size */ ++ case MT2063_LO1_STEPSIZE: ++ pInfo->AS_Data.f_LO1_Step = nValue; ++ break; ++ ++ /* LO1 FracN keep-out region */ ++ case MT2063_LO1_FRACN_AVOID: ++ pInfo->AS_Data.f_LO1_FracN_Avoid = nValue; ++ break; ++ ++ /* Requested 1st IF */ ++ case MT2063_IF1_REQUEST: ++ pInfo->AS_Data.f_if1_Request = nValue; ++ break; ++ ++ /* zero-IF bandwidth */ ++ case MT2063_ZIF_BW: ++ pInfo->AS_Data.f_zif_bw = nValue; ++ break; ++ ++ /* LO2 frequency */ ++ case MT2063_LO2_FREQ: ++ { ++ /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ ++ /* Capture the Divider and Numerator portions of other LO */ ++ U8Data tempLO1CQ[2]; ++ U8Data tempLO1C[2]; ++ UData_t Div2; ++ UData_t FracN2; ++ U8Data tmpOneShot; ++ U8Data restore = 0; ++ ++ /* Buffer the queue for restoration later and get actual LO2 values. */ ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO1CQ_1, &(tempLO1CQ[0]), 2); ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO1C_1, &(tempLO1C[0]), 2); ++ ++ /* only write the queue values if they are different from the actual. */ ++ if( (tempLO1CQ[0] != tempLO1C[0]) || (tempLO1CQ[1] != tempLO1C[1]) ) ++ { ++ /* put actual LO1 value into queue */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &(tempLO1C[0]), 2); ++ ++ /* cache the bytes just written. */ ++ pInfo->reg[LO1CQ_1] = tempLO1C[0]; ++ pInfo->reg[LO1CQ_2] = tempLO1C[1]; ++ restore = 1; ++ } ++ ++ /* Calculate the Divider and Numberator components of LO2 */ ++ status |= CalcLO2Mult(&Div2, &FracN2, nValue, pInfo->AS_Data.f_ref/8191, pInfo->AS_Data.f_ref); ++ pInfo->reg[LO2CQ_1] = (U8Data)((Div2 << 1) | ((FracN2 >> 12) & 0x01) ) & 0xFF; ++ pInfo->reg[LO2CQ_2] = (U8Data)((FracN2 >> 4) & 0xFF); ++ pInfo->reg[LO2CQ_3] = (U8Data)((FracN2 & 0x0F) ); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &pInfo->reg[LO1CQ_1], 3); ++ ++ /* set the one-shot bit to load the LO values */ ++ tmpOneShot = pInfo->reg[LO2CQ_3] | 0xE0; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_3, &tmpOneShot, 1); ++ ++ /* only restore LO1 queue value if they were different from the actual. */ ++ if( restore ) ++ { ++ /* put previous LO1 queue value back into queue */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &(tempLO1CQ[0]), 2); ++ ++ /* cache the bytes just written. */ ++ pInfo->reg[LO1CQ_1] = tempLO1CQ[0]; ++ pInfo->reg[LO1CQ_2] = tempLO1CQ[1]; ++ } ++ ++ status |= MT2063_GetParam( pInfo->hUserData, MT2063_LO2_FREQ, &pInfo->AS_Data.f_LO2 ); ++ } ++ break; ++ ++ /* LO2 minimum step size */ ++ case MT2063_LO2_STEPSIZE: ++ pInfo->AS_Data.f_LO2_Step = nValue; ++ break; ++ ++ /* LO2 FracN keep-out region */ ++ case MT2063_LO2_FRACN_AVOID: ++ pInfo->AS_Data.f_LO2_FracN_Avoid = nValue; ++ break; ++ ++ /* output center frequency */ ++ case MT2063_OUTPUT_FREQ: ++ pInfo->AS_Data.f_out = nValue; ++ break; ++ ++ /* output bandwidth */ ++ case MT2063_OUTPUT_BW: ++ pInfo->AS_Data.f_out_bw = nValue + 750000; ++ break; ++ ++ /* min inter-tuner LO separation */ ++ case MT2063_LO_SEPARATION: ++ pInfo->AS_Data.f_min_LO_Separation = nValue; ++ break; ++ ++ /* max # of intra-tuner harmonics */ ++ case MT2063_MAX_HARM1: ++ pInfo->AS_Data.maxH1 = nValue; ++ break; ++ ++ /* max # of inter-tuner harmonics */ ++ case MT2063_MAX_HARM2: ++ pInfo->AS_Data.maxH2 = nValue; ++ break; ++ ++ case MT2063_RCVR_MODE: ++ status |= MT2063_SetReceiverMode(pInfo, (MT2063_RCVR_MODES)nValue); ++ break; ++ ++ /* Set LNA Rin -- nValue is desired value */ ++ case MT2063_LNA_RIN: ++ val = (U8Data)( ( pInfo->reg[CTRL_2C] & (U8Data)~0x03) | (nValue & 0x03) ); ++ if( pInfo->reg[CTRL_2C] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, CTRL_2C, val); ++ } ++ break; ++ ++ /* Set target power level at LNA -- nValue is desired value */ ++ case MT2063_LNA_TGT: ++ val = (U8Data)( ( pInfo->reg[LNA_TGT] & (U8Data)~0x3F) | (nValue & 0x3F) ); ++ if( pInfo->reg[LNA_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, LNA_TGT, val); ++ } ++ break; ++ ++ /* Set target power level at PD1 -- nValue is desired value */ ++ case MT2063_PD1_TGT: ++ val = (U8Data)( ( pInfo->reg[PD1_TGT] & (U8Data)~0x3F) | (nValue & 0x3F) ); ++ if( pInfo->reg[PD1_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD1_TGT, val); ++ } ++ break; ++ ++ /* Set target power level at PD2 -- nValue is desired value */ ++ case MT2063_PD2_TGT: ++ val = (U8Data)( ( pInfo->reg[PD2_TGT] & (U8Data)~0x3F) | (nValue & 0x3F) ); ++ if( pInfo->reg[PD2_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD2_TGT, val); ++ } ++ break; ++ ++ /* Set LNA atten limit -- nValue is desired value */ ++ case MT2063_ACLNA_MAX: ++ val = (U8Data)( ( pInfo->reg[LNA_OV] & (U8Data)~0x1F) | (nValue & 0x1F) ); ++ if( pInfo->reg[LNA_OV] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, LNA_OV, val); ++ } ++ break; ++ ++ /* Set RF atten limit -- nValue is desired value */ ++ case MT2063_ACRF_MAX: ++ val = (U8Data)( ( pInfo->reg[RF_OV] & (U8Data)~0x1F) | (nValue & 0x1F) ); ++ if( pInfo->reg[RF_OV] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, RF_OV, val); ++ } ++ break; ++ ++ /* Set FIF atten limit -- nValue is desired value, max. 5 if no B3 */ ++ case MT2063_ACFIF_MAX: ++ if ( (pInfo->tuner_id == MT2063_B0 || pInfo->tuner_id == MT2063_B1) && nValue > 5) ++ nValue = 5; ++ val = (U8Data)( ( pInfo->reg[FIF_OV] & (U8Data)~0x1F) | (nValue & 0x1F) ); ++ if( pInfo->reg[FIF_OV] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, FIF_OV, val); ++ } ++ break; ++ ++ case MT2063_DNC_OUTPUT_ENABLE: ++ /* selects, which DNC output is used */ ++ switch ((MT2063_DNC_Output_Enable)nValue) ++ { ++ case MT2063_DNC_NONE : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] & ~0x40); /* Set PD2MUX=0 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ case MT2063_DNC_1 : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] & ~0x40); /* Set PD2MUX=0 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ case MT2063_DNC_2 : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] | 0x40); /* Set PD2MUX=1 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ case MT2063_DNC_BOTH : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] | 0x40); /* Set PD2MUX=1 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ default : break; ++ } ++ break; ++ ++ case MT2063_VGAGC: ++ /* Set VGA gain code */ ++ val = (U8Data)( (pInfo->reg[VGA_GAIN] & (U8Data)~0x0C) | ( (nValue & 0x03) << 2) ); ++ if( pInfo->reg[VGA_GAIN] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, VGA_GAIN, val); ++ } ++ break; ++ ++ case MT2063_VGAOI: ++ /* Set VGA bias current */ ++ val = (U8Data)( (pInfo->reg[RSVD_31] & (U8Data)~0x07) | (nValue & 0x07) ); ++ if( pInfo->reg[RSVD_31] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, RSVD_31, val); ++ } ++ break; ++ ++ case MT2063_TAGC: ++ /* Set TAGC */ ++ val = (U8Data)( (pInfo->reg[RSVD_1E] & (U8Data)~0x03) | (nValue & 0x03) ); ++ if( pInfo->reg[RSVD_1E] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, RSVD_1E, val); ++ } ++ break; ++ ++ case MT2063_AMPGC: ++ /* Set Amp gain code */ ++ val = (U8Data)( (pInfo->reg[TEMP_SEL] & (U8Data)~0x03) | (nValue & 0x03) ); ++ if( pInfo->reg[TEMP_SEL] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, TEMP_SEL, val); ++ } ++ break; ++ ++ /* Avoid DECT Frequencies */ ++ case MT2063_AVOID_DECT: ++ { ++ MT_DECT_Avoid_Type newAvoidSetting = (MT_DECT_Avoid_Type) nValue; ++ if (newAvoidSetting <= MT_AVOID_BOTH) ++ { ++ pInfo->AS_Data.avoidDECT = newAvoidSetting; ++ } ++ } ++ break; ++ ++ /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ ++ case MT2063_CTFILT_SW: ++ pInfo->ctfilt_sw = (nValue & 0x01); ++ break; ++ ++ /* These parameters are read-only */ ++ case MT2063_VERSION: ++ case MT2063_IC_ADDR: ++ case MT2063_IC_REV: ++ case MT2063_MAX_OPEN: ++ case MT2063_NUM_OPEN: ++ case MT2063_INPUT_FREQ: ++ case MT2063_IF1_ACTUAL: ++ case MT2063_IF1_CENTER: ++ case MT2063_IF1_BW: ++ case MT2063_AS_ALG: ++ case MT2063_EXCL_ZONES: ++ case MT2063_SPUR_AVOIDED: ++ case MT2063_NUM_SPURS: ++ case MT2063_SPUR_PRESENT: ++ case MT2063_PD1: ++ case MT2063_PD2: ++ case MT2063_ACLNA: ++ case MT2063_ACRF: ++ case MT2063_ACFIF: ++ case MT2063_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetPowerMaskBits ++** ++** Description: Sets the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be set. ++** ++** See definition of MT2063_Mask_Bits type for description ++** of each of the power bits. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ Bits = (MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ ++ if ((Bits & 0xFF00) != 0) ++ { ++ pInfo->reg[PWR_2] |= (U8Data)((Bits & 0xFF00) >> 8); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_2, &pInfo->reg[PWR_2], 1); ++ } ++ if ((Bits & 0xFF) != 0) ++ { ++ pInfo->reg[PWR_1] |= ((U8Data)Bits & 0xFF); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_ClearPowerMaskBits ++** ++** Description: Clears the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be cleared. ++** ++** See definition of MT2063_Mask_Bits type for description ++** of each of the power bits. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_ClearPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ Bits = (MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ ++ if ((Bits & 0xFF00) != 0) ++ { ++ pInfo->reg[PWR_2] &= ~(U8Data)(Bits >> 8); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_2, &pInfo->reg[PWR_2], 1); ++ } ++ if ((Bits & 0xFF) != 0) ++ { ++ pInfo->reg[PWR_1] &= ~(U8Data)(Bits & 0xFF); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetPowerMaskBits ++** ++** Description: Returns a mask of the enabled power shutdown bits ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to currently set. ++** ++** See definition of MT2063_Mask_Bits type for description ++** of each of the power bits. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Output argument is NULL ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetPowerMaskBits(Handle_t h, MT2063_Mask_Bits *Bits) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ if (Bits == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 2); ++ ++ if (MT_NO_ERROR(status)) ++ { ++ *Bits = (MT2063_Mask_Bits)(((SData_t)pInfo->reg[PWR_2] << 8) + pInfo->reg[PWR_1]); ++ *Bits = (MT2063_Mask_Bits)(*Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_EnableExternalShutdown ++** ++** Description: Enables or disables the operation of the external ++** shutdown pin ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Enabled - 0 = disable the pin, otherwise enable it ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ if (Enabled == 0) ++ pInfo->reg[PWR_1] &= ~0x08; /* Turn off the bit */ ++ else ++ pInfo->reg[PWR_1] |= 0x08; /* Turn the bit on */ ++ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ } ++ ++ return (UData_t)(status); ++} ++ ++/**************************************************************************** ++** ++** Name: MT2063_SoftwareShutdown ++** ++** Description: Enables or disables software shutdown function. When ++** Shutdown==1, any section whose power mask is set will be ++** shutdown. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Shutdown - 1 = shutdown the masked sections, otherwise ++** power all sections on ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 01-03-2008 PINZ Ver 1.xx: Added a trigger of BYPATNUP for ++** correct wakeup of the LNA ++** ++****************************************************************************/ ++UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ if (Shutdown == 1) ++ pInfo->reg[PWR_1] |= 0x04; /* Turn the bit on */ ++ else ++ pInfo->reg[PWR_1] &= ~0x04; /* Turn off the bit */ ++ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ ++ if (Shutdown != 1) ++ { ++ pInfo->reg[BYP_CTRL] = (pInfo->reg[BYP_CTRL] & 0x9F) | 0x40; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, &pInfo->reg[BYP_CTRL], 1); ++ pInfo->reg[BYP_CTRL] = (pInfo->reg[BYP_CTRL] & 0x9F); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, &pInfo->reg[BYP_CTRL], 1); ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetExtSRO ++** ++** Description: Sets the external SRO driver. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Ext_SRO_Setting - external SRO drive setting ++** ++** (default) MT2063_EXT_SRO_OFF - ext driver off ++** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency ++** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency ++** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The Ext_SRO_Setting settings default to OFF ++** Use this function if you need to override the default ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 189 S 05-13-2008 RSK Ver 1.16: Correct location for ExtSRO control. ++** ++****************************************************************************/ ++UData_t MT2063_SetExtSRO(Handle_t h, ++ MT2063_Ext_SRO Ext_SRO_Setting) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ pInfo->reg[CTRL_2C] = (pInfo->reg[CTRL_2C] & 0x3F) | ((U8Data)Ext_SRO_Setting << 6); ++ status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, CTRL_2C, &pInfo->reg[CTRL_2C], 1); ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetReg ++** ++** Description: Sets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); ++ if (MT_NO_ERROR(status)) ++ pInfo->reg[reg] = val; ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++static UData_t Round_fLO(UData_t f_LO, UData_t f_LO_Step, UData_t f_ref) ++{ ++ return (UData_t)( f_ref * (f_LO / f_ref) ++ + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step) ); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: fLO_FractionalTerm ++** ++** Description: Calculates the portion contributed by FracN / denom. ++** ++** This function preserves maximum precision without ++** risk of overflow. It accurately calculates ++** f_ref * num / denom to within 1 HZ with fixed math. ++** ++** Parameters: num - Fractional portion of the multiplier ++** denom - denominator portion of the ratio ++** This routine successfully handles denom values ++** up to and including 2^18. ++** f_Ref - SRO frequency. This calculation handles ++** f_ref as two separate 14-bit fields. ++** Therefore, a maximum value of 2^28-1 ++** may safely be used for f_ref. This is ++** the genesis of the magic number "14" and the ++** magic mask value of 0x03FFF. ++** ++** Returns: f_ref * num / denom ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++static UData_t fLO_FractionalTerm( UData_t f_ref, ++ UData_t num, ++ UData_t denom ) ++{ ++ UData_t t1 = (f_ref >> 14) * num; ++ UData_t term1 = t1 / denom; ++ UData_t loss = t1 % denom; ++ UData_t term2 = ( ((f_ref & 0x00003FFF) * num + (loss<<14)) + (denom/2) ) / denom; ++ return (UData_t)( ((term1 << 14) + term2) ); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: CalcLO1Mult ++** ++** Description: Calculates Integer divider value and the numerator ++** value for a FracN PLL. ++** ++** This function assumes that the f_LO and f_Ref are ++** evenly divisible by f_LO_Step. ++** ++** Parameters: Div - OUTPUT: Whole number portion of the multiplier ++** FracN - OUTPUT: Fractional portion of the multiplier ++** f_LO - desired LO frequency. ++** f_LO_Step - Minimum step size for the LO (in Hz). ++** f_Ref - SRO frequency. ++** f_Avoid - Range of PLL frequencies to avoid near ++** integer multiples of f_Ref (in Hz). ++** ++** Returns: Recalculated LO frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++static UData_t CalcLO1Mult(UData_t *Div, ++ UData_t *FracN, ++ UData_t f_LO, ++ UData_t f_LO_Step, ++ UData_t f_Ref) ++{ ++ /* Calculate the whole number portion of the divider */ ++ *Div = f_LO / f_Ref; ++ ++ /* Calculate the numerator value (round to nearest f_LO_Step) */ ++ *FracN = (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); ++ ++ return (UData_t)( (f_Ref * (*Div)) + fLO_FractionalTerm( f_Ref, *FracN, 64 ) ); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: CalcLO2Mult ++** ++** Description: Calculates Integer divider value and the numerator ++** value for a FracN PLL. ++** ++** This function assumes that the f_LO and f_Ref are ++** evenly divisible by f_LO_Step. ++** ++** Parameters: Div - OUTPUT: Whole number portion of the multiplier ++** FracN - OUTPUT: Fractional portion of the multiplier ++** f_LO - desired LO frequency. ++** f_LO_Step - Minimum step size for the LO (in Hz). ++** f_Ref - SRO frequency. ++** f_Avoid - Range of PLL frequencies to avoid near ++** integer multiples of f_Ref (in Hz). ++** ++** Returns: Recalculated LO frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 205 M 10-01-2008 JWS Ver 1.22: Use DMAX when LO2 FracN is near 4096 ++** ++****************************************************************************/ ++static UData_t CalcLO2Mult(UData_t *Div, ++ UData_t *FracN, ++ UData_t f_LO, ++ UData_t f_LO_Step, ++ UData_t f_Ref) ++{ ++ UData_t denom = 8191; ++ ++ /* Calculate the whole number portion of the divider */ ++ *Div = f_LO / f_Ref; ++ ++ /* Calculate the numerator value (round to nearest f_LO_Step) */ ++ *FracN = (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); ++ ++ /* ++ ** FracN values close to 1/2 (4096) will be forced to 4096. The tuning code must ++ ** then set the DMAX bit for the affected LO(s). ++ */ ++ if ((*FracN >= 4083) && (*FracN <= 4107)) ++ { ++ *FracN = 4096; ++ denom = 8192; ++ } ++ ++ return (UData_t)( (f_Ref * (*Div)) + fLO_FractionalTerm( f_Ref, *FracN, denom ) ); ++} ++ ++/**************************************************************************** ++** ++** Name: FindClearTuneFilter ++** ++** Description: Calculate the corrrect ClearTune filter to be used for ++** a given input frequency. ++** ++** Parameters: pInfo - ptr to tuner data structure ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: ClearTune filter number (0-31) ++** ++** Dependencies: MUST CALL MT2064_Open BEFORE FindClearTuneFilter! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune ++** cross-over frequency values. ++** ++****************************************************************************/ ++static UData_t FindClearTuneFilter(MT2063_Info_t* pInfo, UData_t f_in) ++{ ++ UData_t RFBand; ++ UData_t idx; /* index loop */ ++ ++ /* ++ ** Find RF Band setting ++ */ ++ RFBand = 31; /* def when f_in > all */ ++ for (idx=0; idx<31; ++idx) ++ { ++ if (pInfo->CTFiltMax[idx] >= f_in) ++ { ++ RFBand = idx; ++ break; ++ } ++ } ++ return (UData_t)(RFBand); ++} ++ ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_Tune ++** ++** Description: Change the tuner's tuned frequency to RFin. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_SPUR_CNT_MASK - Count of avoided LO spurs ++** MT_SPUR_PRESENT - LO spur possible in output ++** MT_FIN_RANGE - Input freq out of range ++** MT_FOUT_RANGE - Output freq out of range ++** MT_UPC_RANGE - Upconverter freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune! ++** ++** MT_ReadSub - Read data from the two-wire serial bus ++** MT_WriteSub - Write data to the two-wire serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2063_GetLocked - Checks to see if LO1 and LO2 are locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 04-10-2008 PINZ Ver 1.05: Use software-controlled ClearTune ++** cross-over frequency values. ++** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 205 M 10-01-2008 JWS Ver 1.22: Use DMAX when LO2 FracN is near 4096 ++** M 10-24-2008 JWS Ver 1.25: Use DMAX when LO1 FracN is 32 ++** ++****************************************************************************/ ++UData_t MT2063_Tune(Handle_t h, ++ UData_t f_in) /* RF input center frequency */ ++{ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ UData_t status = MT_OK; /* status of operation */ ++ UData_t LO1; /* 1st LO register value */ ++ UData_t Num1; /* Numerator for LO1 reg. value */ ++ UData_t f_IF1; /* 1st IF requested */ ++ UData_t LO2; /* 2nd LO register value */ ++ UData_t Num2; /* Numerator for LO2 reg. value */ ++ UData_t ofLO1, ofLO2; /* last time's LO frequencies */ ++ U8Data fiffc = 0x80; /* FIFF center freq from tuner */ ++ UData_t fiffof; /* Offset from FIFF center freq */ ++ const U8Data LO1LK = 0x80; /* Mask for LO1 Lock bit */ ++ U8Data LO2LK = 0x08; /* Mask for LO2 Lock bit */ ++ U8Data val; ++ UData_t RFBand; ++ U8Data oFN; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ /* Check the input and output frequency ranges */ ++ if ((f_in < MIN_FIN_FREQ) || (f_in > MAX_FIN_FREQ)) ++ status |= MT_FIN_RANGE; ++ ++ if ((pInfo->AS_Data.f_out < MIN_FOUT_FREQ) || (pInfo->AS_Data.f_out > MAX_FOUT_FREQ)) ++ status |= MT_FOUT_RANGE; ++ ++ /* ++ ** Save original LO1 and LO2 register values ++ */ ++ ofLO1 = pInfo->AS_Data.f_LO1; ++ ofLO2 = pInfo->AS_Data.f_LO2; ++ ++ /* ++ ** Find and set RF Band setting ++ */ ++ if (pInfo->ctfilt_sw == 1) ++ { ++ val = ( pInfo->reg[CTUNE_CTRL] | 0x08 ); ++ if( pInfo->reg[CTUNE_CTRL] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, CTUNE_CTRL, val); ++ } ++ ++ RFBand = FindClearTuneFilter(pInfo, f_in); ++ val = (U8Data)( (pInfo->reg[CTUNE_OV] & ~0x1F) | RFBand ); ++ if (pInfo->reg[CTUNE_OV] != val) ++ { ++ status |= MT2063_SetReg(pInfo, CTUNE_OV, val); ++ } ++ } ++ ++ /* ++ ** Read the FIFF Center Frequency from the tuner ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, FIFFC, &pInfo->reg[FIFFC], 1); ++ fiffc = pInfo->reg[FIFFC]; ++ } ++ ++ /* ++ ** Assign in the requested values ++ */ ++ pInfo->AS_Data.f_in = f_in; ++ /* Request a 1st IF such that LO1 is on a step size */ ++ pInfo->AS_Data.f_if1_Request = Round_fLO(pInfo->AS_Data.f_if1_Request + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref) - f_in; ++ ++ /* ++ ** Calculate frequency settings. f_IF1_FREQ + f_in is the ++ ** desired LO1 frequency ++ */ ++ MT2063_ResetExclZones(&pInfo->AS_Data); ++ ++ f_IF1 = MT2063_ChooseFirstIF(&pInfo->AS_Data); ++ pInfo->AS_Data.f_LO1 = Round_fLO(f_IF1 + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref); ++ pInfo->AS_Data.f_LO2 = Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); ++ ++ /* ++ ** Check for any LO spurs in the output bandwidth and adjust ++ ** the LO settings to avoid them if needed ++ */ ++ status |= MT2063_AvoidSpurs(h, &pInfo->AS_Data); ++ ++ /* ++ ** MT_AvoidSpurs spurs may have changed the LO1 & LO2 values. ++ ** Recalculate the LO frequencies and the values to be placed ++ ** in the tuning registers. ++ */ ++ pInfo->AS_Data.f_LO1 = CalcLO1Mult(&LO1, &Num1, pInfo->AS_Data.f_LO1, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref); ++ pInfo->AS_Data.f_LO2 = Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); ++ pInfo->AS_Data.f_LO2 = CalcLO2Mult(&LO2, &Num2, pInfo->AS_Data.f_LO2, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); ++ ++ /* ++ ** Check the upconverter and downconverter frequency ranges ++ */ ++ if ((pInfo->AS_Data.f_LO1 < MIN_UPC_FREQ) || (pInfo->AS_Data.f_LO1 > MAX_UPC_FREQ)) ++ status |= MT_UPC_RANGE; ++ ++ if ((pInfo->AS_Data.f_LO2 < MIN_DNC_FREQ) || (pInfo->AS_Data.f_LO2 > MAX_DNC_FREQ)) ++ status |= MT_DNC_RANGE; ++ ++ /* LO2 Lock bit was in a different place for B0 version */ ++ if (pInfo->tuner_id == MT2063_B0) ++ LO2LK = 0x40; ++ ++ /* ++ ** If we have the same LO frequencies and we're already locked, ++ ** then skip re-programming the LO registers. ++ */ ++ if ((ofLO1 != pInfo->AS_Data.f_LO1) ++ || (ofLO2 != pInfo->AS_Data.f_LO2) ++ || ((pInfo->reg[LO_STATUS] & (LO1LK | LO2LK)) != (LO1LK | LO2LK))) ++ { ++ /* ++ ** Calculate the FIFFOF register value ++ ** ++ ** IF1_Actual ++ ** FIFFOF = ------------ - 8 * FIFFC - 4992 ++ ** f_ref/64 ++ */ ++ fiffof = (pInfo->AS_Data.f_LO1 - f_in) / (pInfo->AS_Data.f_ref / 64) - 8 * (UData_t)fiffc - 4992; ++ if (fiffof > 0xFF) ++ fiffof = 0xFF; ++ ++ /* ++ ** Place all of the calculated values into the local tuner ++ ** register fields. ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ oFN = pInfo->reg[FN_CTRL]; /* save current FN_CTRL settings */ ++ ++ /* ++ ** If either FracN is 4096 (or was rounded to there) then set its ++ ** DMAX bit, otherwise clear it. ++ */ ++ if (Num1 == 32) ++ pInfo->reg[FN_CTRL] |= 0x20; ++ else ++ pInfo->reg[FN_CTRL] &= ~0x20; ++ if (Num2 == 4096) ++ pInfo->reg[FN_CTRL] |= 0x02; ++ else ++ pInfo->reg[FN_CTRL] &= ~0x02; ++ ++ pInfo->reg[LO1CQ_1] = (U8Data)(LO1 & 0xFF); /* DIV1q */ ++ pInfo->reg[LO1CQ_2] = (U8Data)(Num1 & 0x3F); /* NUM1q */ ++ pInfo->reg[LO2CQ_1] = (U8Data)(((LO2 & 0x7F) << 1) /* DIV2q */ ++ | (Num2 >> 12)); /* NUM2q (hi) */ ++ pInfo->reg[LO2CQ_2] = (U8Data)((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */ ++ pInfo->reg[LO2CQ_3] = (U8Data)(0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */ ++ ++ /* ++ ** Now write out the computed register values ++ ** IMPORTANT: There is a required order for writing ++ ** (0x05 must follow all the others). ++ */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &pInfo->reg[LO1CQ_1], 5); /* 0x01 - 0x05 */ ++ ++ /* The FN_CTRL register is only needed if it changes */ ++ if (oFN != pInfo->reg[FN_CTRL]) ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, FN_CTRL, &pInfo->reg[FN_CTRL], 1); /* 0x34 */ ++ ++ if (pInfo->tuner_id == MT2063_B0) ++ { ++ /* Re-write the one-shot bits to trigger the tune operation */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_3, &pInfo->reg[LO2CQ_3], 1); /* 0x05 */ ++ } ++ ++ /* Write out the FIFF offset only if it's changing */ ++ if (pInfo->reg[FIFF_OFFSET] != (U8Data)fiffof) ++ { ++ pInfo->reg[FIFF_OFFSET] = (U8Data)fiffof; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, FIFF_OFFSET, &pInfo->reg[FIFF_OFFSET], 1); ++ } ++ } ++ ++ /* ++ ** Check for LO's locking ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_GetLocked(h); ++ } ++ ++ /* ++ ** If we locked OK, assign calculated data to MT2063_Info_t structure ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->f_IF1_actual = pInfo->AS_Data.f_LO1 - f_in; ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_spuravoid.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.c ++** ++** Copyright 2006-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.c ++** ++** Description: Microtune spur avoidance software module. ++** Supports Microtune tuner drivers. ++** ++** CVS ID: $Id: mt_spuravoid.c,v 1.4 2008/11/05 13:46:19 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_spuravoid.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 082 03-25-2005 JWS Original multi-tuner support - requires ++** MTxxxx_CNT declarations ++** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. ++** 094 04-06-2005 JWS Ver 1.11 Added uceil and ufloor to get rid ++** of compiler warnings ++** N/A 04-07-2005 DAD Ver 1.13: Merged single- and multi-tuner spur ++** avoidance into a single module. ++** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range ++** (f_min, f_max) < 0, ignore the entry. ++** 115 03-23-2007 DAD Fix declaration of spur due to truncation ++** errors. ++** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from ++** tuner DLL. ++** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for ++** multi-tuners that have ++** (delta IF1) > (f_out-f_outbw/2). ++** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) ++** Added logic to force f_Center within 1/2 f_Step. ++** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 ++** Type casts added to preserve correct sign. ++** 195 I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT ++** frequencies into MT_ResetExclZones(). ++** N/A I 06-20-2008 RSK Ver 1.21: New VERSION number for ver checking. ++** 199 08-06-2008 JWS Ver 1.22: Added 0x1x1 spur frequency calculations ++** and indicate success of AddExclZone operation. ++** 200 08-07-2008 JWS Ver 1.23: Moved definition of DECT avoid constants ++** so users could access them more easily. ++** ++*****************************************************************************/ ++//#include "mt_spuravoid.h" ++//#include ++//#include /* debug purposes */ ++ ++#if !defined(MT_TUNER_CNT) ++#error MT_TUNER_CNT is not defined (see mt_userdef.h) ++#endif ++ ++#if MT_TUNER_CNT == 0 ++#error MT_TUNER_CNT must be updated in mt_userdef.h ++#endif ++ ++/* Version of this module */ ++#define MT_SPURAVOID_VERSION 10203 /* Version 01.23 */ ++ ++ ++/* Implement ceiling, floor functions. */ ++#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0)) ++#define uceil(n, d) ((n)/(d) + ((n)%(d) != 0)) ++#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d)) ++#define ufloor(n, d) ((n)/(d)) ++ ++/* Macros to check for DECT exclusion options */ ++#define MT_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT_AVOID_US_DECT) != 0) ++#define MT_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT_AVOID_EURO_DECT) != 0) ++ ++ ++struct MT_FIFZone_t ++{ ++ SData_t min_; ++ SData_t max_; ++}; ++ ++#if MT_TUNER_CNT > 1 ++static MT2063_AvoidSpursData_t* TunerList[MT_TUNER_CNT]; ++static UData_t TunerCount = 0; ++#endif ++ ++UData_t MT2063_RegisterTuner(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++#if MT_TUNER_CNT == 1 ++ // pAS_Info->nAS_Algorithm = 1; ++ return MT_OK; ++#else ++ UData_t index; ++ ++ pAS_Info->nAS_Algorithm = 2; ++ ++ /* ++ ** Check to see if tuner is already registered ++ */ ++ for (index = 0; index < TunerCount; index++) ++ { ++ if (TunerList[index] == pAS_Info) ++ { ++ return MT_OK; /* Already here - no problem */ ++ } ++ } ++ ++ /* ++ ** Add tuner to list - if there is room. ++ */ ++ if (TunerCount < MT_TUNER_CNT) ++ { ++ TunerList[TunerCount] = pAS_Info; ++ TunerCount++; ++ return MT_OK; ++ } ++ else ++ return MT_TUNER_CNT_ERR; ++#endif ++} ++ ++ ++void MT2063_UnRegisterTuner(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++#if MT_TUNER_CNT == 1 ++ // pAS_Info; ++ // pAS_Info->nAS_Algorithm = 1; ++ // return MT_OK; ++#else ++ ++ UData_t index; ++ ++ for (index = 0; index < TunerCount; index++) ++ { ++ if (TunerList[index] == pAS_Info) ++ { ++ TunerList[index] = TunerList[--TunerCount]; ++ } ++ } ++#endif ++} ++ ++ ++/* ++** Reset all exclusion zones. ++** Add zones to protect the PLL FracN regions near zero ++** ++** 195 I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT ++** frequencies into MT_ResetExclZones(). ++*/ ++void MT2063_ResetExclZones(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++ UData_t center; ++#if MT_TUNER_CNT > 1 ++ UData_t index; ++ MT2063_AvoidSpursData_t* adj; ++#endif ++ ++ pAS_Info->nZones = 0; /* this clears the used list */ ++ pAS_Info->usedZones = MT_NULL; /* reset ptr */ ++ pAS_Info->freeZones = MT_NULL; /* reset ptr */ ++ ++ center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 + pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in; ++ while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO1_FracN_Avoid) ++ { ++ /* Exclude LO1 FracN */ ++ MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO1_FracN_Avoid, center-1); ++ MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO1_FracN_Avoid); ++ center += pAS_Info->f_ref; ++ } ++ ++ center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 - pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out; ++ while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO2_FracN_Avoid) ++ { ++ /* Exclude LO2 FracN */ ++ MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO2_FracN_Avoid, center-1); ++ MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO2_FracN_Avoid); ++ center += pAS_Info->f_ref; ++ } ++ ++ if( MT_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) ++ { ++ /* Exclude LO1 values that conflict with DECT channels */ ++ MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */ ++ MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */ ++ MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */ ++ MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */ ++ MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */ ++ } ++ ++ if( MT_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) ++ { ++ MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */ ++ MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */ ++ MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */ ++ MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */ ++ MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */ ++ MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */ ++ MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */ ++ MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */ ++ MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */ ++ MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */ ++ } ++ ++#if MT_TUNER_CNT > 1 ++ /* ++ ** Iterate through all adjacent tuners and exclude frequencies related to them ++ */ ++ for (index = 0; index < TunerCount; ++index) ++ { ++ adj = TunerList[index]; ++ if (pAS_Info == adj) /* skip over our own data, don't process it */ ++ continue; ++ ++ /* ++ ** Add 1st IF exclusion zone covering adjacent tuner's LO2 ++ ** at "adjfLO2 + f_out" +/- m_MinLOSpacing ++ */ ++ if (adj->f_LO2 != 0) ++ MT2063_AddExclZone(pAS_Info, ++ (adj->f_LO2 + pAS_Info->f_out) - pAS_Info->f_min_LO_Separation, ++ (adj->f_LO2 + pAS_Info->f_out) + pAS_Info->f_min_LO_Separation ); ++ ++ /* ++ ** Add 1st IF exclusion zone covering adjacent tuner's LO1 ++ ** at "adjfLO1 - f_in" +/- m_MinLOSpacing ++ */ ++ if (adj->f_LO1 != 0) ++ MT2063_AddExclZone(pAS_Info, ++ (adj->f_LO1 - pAS_Info->f_in) - pAS_Info->f_min_LO_Separation, ++ (adj->f_LO1 - pAS_Info->f_in) + pAS_Info->f_min_LO_Separation ); ++ } ++#endif ++} ++ ++ ++static struct MT2063_ExclZone_t* InsertNode(MT2063_AvoidSpursData_t* pAS_Info, ++ struct MT2063_ExclZone_t* pPrevNode) ++{ ++ struct MT2063_ExclZone_t* pNode; ++ /* Check for a node in the free list */ ++ if (pAS_Info->freeZones != MT_NULL) ++ { ++ /* Use one from the free list */ ++ pNode = pAS_Info->freeZones; ++ pAS_Info->freeZones = pNode->next_; ++ } ++ else ++ { ++ /* Grab a node from the array */ ++ pNode = &pAS_Info->MT_ExclZones[pAS_Info->nZones]; ++ } ++ ++ if (pPrevNode != MT_NULL) ++ { ++ pNode->next_ = pPrevNode->next_; ++ pPrevNode->next_ = pNode; ++ } ++ else /* insert at the beginning of the list */ ++ { ++ pNode->next_ = pAS_Info->usedZones; ++ pAS_Info->usedZones = pNode; ++ } ++ ++ pAS_Info->nZones++; ++ return pNode; ++} ++ ++ ++static struct MT2063_ExclZone_t* RemoveNode(MT2063_AvoidSpursData_t* pAS_Info, ++ struct MT2063_ExclZone_t* pPrevNode, ++ struct MT2063_ExclZone_t* pNodeToRemove) ++{ ++ struct MT2063_ExclZone_t* pNext = pNodeToRemove->next_; ++ ++ /* Make previous node point to the subsequent node */ ++ if (pPrevNode != MT_NULL) ++ pPrevNode->next_ = pNext; ++ ++ /* Add pNodeToRemove to the beginning of the freeZones */ ++ pNodeToRemove->next_ = pAS_Info->freeZones; ++ pAS_Info->freeZones = pNodeToRemove; ++ ++ /* Decrement node count */ ++ pAS_Info->nZones--; ++ ++ return pNext; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_AddExclZone ++** ++** Description: Add (and merge) an exclusion zone into the list. ++** If the range (f_min, f_max) is totally outside the ++** 1st IF BW, ignore the entry. ++** If the range (f_min, f_max) is negative, ignore the entry. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range ++** (f_min, f_max) < 0, ignore the entry. ++** 199 08-06-2008 JWS Ver 1.22: Indicate success of addition operation. ++** ++*****************************************************************************/ ++UData_t MT2063_AddExclZone(MT2063_AvoidSpursData_t* pAS_Info, ++ UData_t f_min, ++ UData_t f_max) ++{ ++ UData_t status = 1; /* Assume addition is possible */ ++ ++ /* Check to see if this overlaps the 1st IF filter */ ++ if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2))) ++ && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2))) ++ && (f_min < f_max)) ++ { ++ /* ++ ** 1 2 3 4 5 6 ++ ** ++ ** New entry: |---| |--| |--| |-| |---| |--| ++ ** or or or or or ++ ** Existing: |--| |--| |--| |---| |-| |--| ++ */ ++ struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; ++ struct MT2063_ExclZone_t* pPrev = MT_NULL; ++ struct MT2063_ExclZone_t* pNext = MT_NULL; ++ ++ /* Check for our place in the list */ ++ while ((pNode != MT_NULL) && (pNode->max_ < f_min)) ++ { ++ pPrev = pNode; ++ pNode = pNode->next_; ++ } ++ ++ if ((pNode != MT_NULL) && (pNode->min_ < f_max)) ++ { ++ /* Combine me with pNode */ ++ if (f_min < pNode->min_) ++ pNode->min_ = f_min; ++ if (f_max > pNode->max_) ++ pNode->max_ = f_max; ++ } ++ else ++ { ++ pNode = InsertNode(pAS_Info, pPrev); ++ pNode->min_ = f_min; ++ pNode->max_ = f_max; ++ } ++ ++ /* Look for merging possibilities */ ++ pNext = pNode->next_; ++ while ((pNext != MT_NULL) && (pNext->min_ < pNode->max_)) ++ { ++ if (pNext->max_ > pNode->max_) ++ pNode->max_ = pNext->max_; ++ pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */ ++ } ++ } ++ else ++ status = 0; /* Did not add the zone - caller determines whether this is a problem */ ++ ++ return status; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ChooseFirstIF ++** ++** Description: Choose the best available 1st IF ++** If f_Desired is not excluded, choose that first. ++** Otherwise, return the value closest to f_Center that is ++** not excluded ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from ++** tuner DLL. ++** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) ++** Added logic to force f_Center within 1/2 f_Step. ++** ++*****************************************************************************/ ++UData_t MT2063_ChooseFirstIF(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++ /* ++ ** Update "f_Desired" to be the nearest "combinational-multiple" of "f_LO1_Step". ++ ** The resulting number, F_LO1 must be a multiple of f_LO1_Step. And F_LO1 is the arithmetic sum ++ ** of f_in + f_Center. Neither f_in, nor f_Center must be a multiple of f_LO1_Step. ++ ** However, the sum must be. ++ */ ++ const UData_t f_Desired = pAS_Info->f_LO1_Step * ((pAS_Info->f_if1_Request + pAS_Info->f_in + pAS_Info->f_LO1_Step/2) / pAS_Info->f_LO1_Step) - pAS_Info->f_in; ++ const UData_t f_Step = (pAS_Info->f_LO1_Step > pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->f_LO2_Step; ++ UData_t f_Center; ++ ++ SData_t i; ++ SData_t j = 0; ++ UData_t bDesiredExcluded = 0; ++ UData_t bZeroExcluded = 0; ++ SData_t tmpMin, tmpMax; ++ SData_t bestDiff; ++ struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; ++ struct MT_FIFZone_t zones[MT2063_MAX_ZONES]; ++ ++ if (pAS_Info->nZones == 0) ++ return f_Desired; ++ ++ /* f_Center needs to be an integer multiple of f_Step away from f_Desired */ ++ if (pAS_Info->f_if1_Center > f_Desired) ++ f_Center = f_Desired + f_Step * ((pAS_Info->f_if1_Center - f_Desired + f_Step/2) / f_Step); ++ else ++ f_Center = f_Desired - f_Step * ((f_Desired - pAS_Info->f_if1_Center + f_Step/2) / f_Step); ++ ++// assert(abs((SData_t) f_Center - (SData_t) pAS_Info->f_if1_Center) <= (SData_t) (f_Step/2)); ++ ++ /* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */ ++ while (pNode != MT_NULL) ++ { ++ /* floor function */ ++ tmpMin = floor((SData_t) (pNode->min_ - f_Center), (SData_t) f_Step); ++ ++ /* ceil function */ ++ tmpMax = ceil((SData_t) (pNode->max_ - f_Center), (SData_t) f_Step); ++ ++ if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired)) ++ bDesiredExcluded = 1; ++ ++ if ((tmpMin < 0) && (tmpMax > 0)) ++ bZeroExcluded = 1; ++ ++ /* See if this zone overlaps the previous */ ++ if ((j>0) && (tmpMin < zones[j-1].max_)) ++ zones[j-1].max_ = tmpMax; ++ else ++ { ++ /* Add new zone */ ++// assert(jnext_; ++ } ++ ++ /* ++ ** If the desired is okay, return with it ++ */ ++ if (bDesiredExcluded == 0) ++ return f_Desired; ++ ++ /* ++ ** If the desired is excluded and the center is okay, return with it ++ */ ++ if (bZeroExcluded == 0) ++ return f_Center; ++ ++ /* Find the value closest to 0 (f_Center) */ ++ bestDiff = zones[0].min_; ++ for (i=0; i= b) ? a : b; ++} ++ ++#if MT_TUNER_CNT > 1 ++static SData_t RoundAwayFromZero(SData_t n, SData_t d) ++{ ++ return (n<0) ? floor(n, d) : ceil(n, d); ++} ++ ++/**************************************************************************** ++** ++** Name: IsSpurInAdjTunerBand ++** ++** Description: Checks to see if a spur will be present within the IF's ++** bandwidth or near the zero IF. ++** (fIFOut +/- fIFBW/2, -fIFOut +/- fIFBW/2) ++** and ++** (0 +/- fZIFBW/2) ++** ++** ma mb me mf mc md ++** <--+-+-+-----------------+-+-+-----------------+-+-+--> ++** | ^ 0 ^ | ++** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ ++** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 ++** ++** Note that some equations are doubled to prevent round-off ++** problems when calculating fIFBW/2 ++** ++** The spur frequencies are computed as: ++** ++** fSpur = n * f1 - m * f2 - fOffset ++** ++** Parameters: f1 - The 1st local oscillator (LO) frequency ++** of the tuner whose output we are examining ++** f2 - The 1st local oscillator (LO) frequency ++** of the adjacent tuner ++** fOffset - The 2nd local oscillator of the tuner whose ++** output we are examining ++** fIFOut - Output IF center frequency ++** fIFBW - Output IF Bandwidth ++** nMaxH - max # of LO harmonics to search ++** fp - If spur, positive distance to spur-free band edge (returned) ++** fm - If spur, negative distance to spur-free band edge (returned) ++** ++** Returns: 1 if an LO spur would be present, otherwise 0. ++** ++** Dependencies: None. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 01-21-2005 JWS Original, adapted from MT_DoubleConversion. ++** 115 03-23-2007 DAD Fix declaration of spur due to truncation ++** errors. ++** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for ++** multi-tuners that have ++** (delta IF1) > (f_out-f_outbw/2). ++** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 ++** Type casts added to preserve correct sign. ++** 199 08-06-2008 JWS Ver 1.22: Added 0x1x1 spur frequency calculations. ++** ++****************************************************************************/ ++static UData_t IsSpurInAdjTunerBand(UData_t bIsMyOutput, ++ UData_t f1, ++ UData_t f2, ++ UData_t fOffset, ++ UData_t fIFOut, ++ UData_t fIFBW, ++ UData_t fZIFBW, ++ UData_t nMaxH, ++ UData_t *fp, ++ UData_t *fm) ++{ ++ UData_t bSpurFound = 0; ++ ++ const UData_t fHalf_IFBW = fIFBW / 2; ++ const UData_t fHalf_ZIFBW = fZIFBW / 2; ++ ++ /* Calculate a scale factor for all frequencies, so that our ++ calculations all stay within 31 bits */ ++ const UData_t f_Scale = ((f1 + (fOffset + fIFOut + fHalf_IFBW) / nMaxH) / (MAX_UDATA/2 / nMaxH)) + 1; ++ ++ /* ++ ** After this scaling, _f1, _f2, and _f3 are guaranteed to fit into ++ ** signed data types (smaller than MAX_UDATA/2) ++ */ ++ const SData_t _f1 = (SData_t) ( f1 / f_Scale); ++ const SData_t _f2 = (SData_t) ( f2 / f_Scale); ++ const SData_t _f3 = (SData_t) (fOffset / f_Scale); ++ ++ const SData_t c = (SData_t) (fIFOut - fHalf_IFBW) / (SData_t) f_Scale; ++ const SData_t d = (SData_t) ((fIFOut + fHalf_IFBW) / f_Scale); ++ const SData_t f = (SData_t) (fHalf_ZIFBW / f_Scale); ++ ++ SData_t ma, mb, mc, md, me, mf; ++ ++ SData_t fp_ = 0; ++ SData_t fm_ = 0; ++ SData_t n; ++ ++ ++ /* ++ ** If the other tuner does not have an LO frequency defined, ++ ** assume that we cannot interfere with it ++ */ ++ if (f2 == 0) ++ return 0; ++ ++ ++ /* Check out all multiples of f1 from -nMaxH to +nMaxH */ ++ for (n = -(SData_t)nMaxH; n <= (SData_t)nMaxH; ++n) ++ { ++ const SData_t nf1 = n*_f1; ++ md = floor(_f3 + d - nf1, _f2); ++ ++ /* If # f2 harmonics > nMaxH, then no spurs present */ ++ if (md <= -(SData_t) nMaxH ) ++ break; ++ ++ ma = floor(_f3 - d - nf1, _f2); ++ if ((ma == md) || (ma >= (SData_t) (nMaxH))) ++ continue; ++ ++ mc = floor(_f3 + c - nf1, _f2); ++ if (mc != md) ++ { ++ const SData_t m = md; ++ const SData_t fspur = (nf1 + m*_f2 - _f3); ++ const SData_t den = (bIsMyOutput ? n - 1 : n); ++ if (den == 0) ++ { ++ fp_ = (d - fspur)* f_Scale; ++ fm_ = (fspur - c)* f_Scale; ++ } ++ else ++ { ++ fp_ = (SData_t) RoundAwayFromZero((d - fspur)* f_Scale, den); ++ fm_ = (SData_t) RoundAwayFromZero((fspur - c)* f_Scale, den); ++ } ++ if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) ++ { ++ bSpurFound = 1; ++ break; ++ } ++ } ++ ++ /* Location of Zero-IF-spur to be checked */ ++ mf = floor(_f3 + f - nf1, _f2); ++ me = floor(_f3 - f - nf1, _f2); ++ if (me != mf) ++ { ++ const SData_t m = mf; ++ const SData_t fspur = (nf1 + m*_f2 - _f3); ++ const SData_t den = (bIsMyOutput ? n - 1 : n); ++ if (den == 0) ++ { ++ fp_ = (d - fspur)* f_Scale; ++ fm_ = (fspur - c)* f_Scale; ++ } ++ else ++ { ++ fp_ = (SData_t) RoundAwayFromZero((f - fspur)* f_Scale, den); ++ fm_ = (SData_t) RoundAwayFromZero((fspur + f)* f_Scale, den); ++ } ++ if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) ++ { ++ bSpurFound = 1; ++ break; ++ } ++ } ++ ++ mb = floor(_f3 - c - nf1, _f2); ++ if (ma != mb) ++ { ++ const SData_t m = mb; ++ const SData_t fspur = (nf1 + m*_f2 - _f3); ++ const SData_t den = (bIsMyOutput ? n - 1 : n); ++ if (den == 0) ++ { ++ fp_ = (d - fspur)* f_Scale; ++ fm_ = (fspur - c)* f_Scale; ++ } ++ else ++ { ++ fp_ = (SData_t) RoundAwayFromZero((-c - fspur)* f_Scale, den); ++ fm_ = (SData_t) RoundAwayFromZero((fspur +d)* f_Scale, den); ++ } ++ if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) ++ { ++ bSpurFound = 1; ++ break; ++ } ++ } ++ } ++ ++ /* ++ ** Verify that fm & fp are both positive ++ ** Add one to ensure next 1st IF choice is not right on the edge ++ */ ++ if (fp_ < 0) ++ { ++ *fp = -fm_ + 1; ++ *fm = -fp_ + 1; ++ } ++ else if (fp_ > 0) ++ { ++ *fp = fp_ + 1; ++ *fm = fm_ + 1; ++ } ++ else ++ { ++ *fp = 1; ++ *fm = abs(fm_) + 1; ++ } ++ ++ return bSpurFound; ++} ++#endif ++ ++/**************************************************************************** ++** ++** Name: IsSpurInBand ++** ++** Description: Checks to see if a spur will be present within the IF's ++** bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW) ++** ++** ma mb mc md ++** <--+-+-+-------------------+-------------------+-+-+--> ++** | ^ 0 ^ | ++** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ ++** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 ++** ++** Note that some equations are doubled to prevent round-off ++** problems when calculating fIFBW/2 ++** ++** Parameters: pAS_Info - Avoid Spurs information block ++** fm - If spur, amount f_IF1 has to move negative ++** fp - If spur, amount f_IF1 has to move positive ++** ++** Global: None ++** ++** Returns: 1 if an LO spur would be present, otherwise 0. ++** ++** Dependencies: None. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 11-28-2002 DAD Implemented algorithm from applied patent ++** ++****************************************************************************/ ++static UData_t IsSpurInBand(MT2063_AvoidSpursData_t* pAS_Info, ++ UData_t* fm, ++ UData_t* fp) ++{ ++ /* ++ ** Calculate LO frequency settings. ++ */ ++ UData_t n, n0; ++ const UData_t f_LO1 = pAS_Info->f_LO1; ++ const UData_t f_LO2 = pAS_Info->f_LO2; ++ const UData_t d = pAS_Info->f_out + pAS_Info->f_out_bw/2; ++ const UData_t c = d - pAS_Info->f_out_bw; ++ const UData_t f = pAS_Info->f_zif_bw/2; ++ const UData_t f_Scale = (f_LO1 / (MAX_UDATA/2 / pAS_Info->maxH1)) + 1; ++ SData_t f_nsLO1, f_nsLO2; ++ SData_t f_Spur; ++ UData_t ma, mb, mc, md, me, mf; ++ UData_t lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs; ++#if MT_TUNER_CNT > 1 ++ UData_t index; ++ ++ MT2063_AvoidSpursData_t *adj; ++#endif ++ *fm = 0; ++ ++ /* ++ ** For each edge (d, c & f), calculate a scale, based on the gcd ++ ** of f_LO1, f_LO2 and the edge value. Use the larger of this ++ ** gcd-based scale factor or f_Scale. ++ */ ++ lo_gcd = gcd(f_LO1, f_LO2); ++ gd_Scale = umax((UData_t) gcd(lo_gcd, d), f_Scale); ++ hgds = gd_Scale/2; ++ gc_Scale = umax((UData_t) gcd(lo_gcd, c), f_Scale); ++ hgcs = gc_Scale/2; ++ gf_Scale = umax((UData_t) gcd(lo_gcd, f), f_Scale); ++ hgfs = gf_Scale/2; ++ ++ n0 = uceil(f_LO2 - d, f_LO1 - f_LO2); ++ ++ /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */ ++ for (n=n0; n<=pAS_Info->maxH1; ++n) ++ { ++ md = (n*((f_LO1+hgds)/gd_Scale) - ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); ++ ++ /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */ ++ if (md >= pAS_Info->maxH1) ++ break; ++ ++ ma = (n*((f_LO1+hgds)/gd_Scale) + ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); ++ ++ /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */ ++ if (md == ma) ++ continue; ++ ++ mc = (n*((f_LO1+hgcs)/gc_Scale) - ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); ++ if (mc != md) ++ { ++ f_nsLO1 = (SData_t) (n*(f_LO1/gc_Scale)); ++ f_nsLO2 = (SData_t) (mc*(f_LO2/gc_Scale)); ++ f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - mc*(f_LO2 % gc_Scale); ++ ++ *fp = ((f_Spur - (SData_t) c) / (mc - n)) + 1; ++ *fm = (((SData_t) d - f_Spur) / (mc - n)) + 1; ++ return 1; ++ } ++ ++ /* Location of Zero-IF-spur to be checked */ ++ me = (n*((f_LO1+hgfs)/gf_Scale) + ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); ++ mf = (n*((f_LO1+hgfs)/gf_Scale) - ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); ++ if (me != mf) ++ { ++ f_nsLO1 = n*(f_LO1/gf_Scale); ++ f_nsLO2 = me*(f_LO2/gf_Scale); ++ f_Spur = (gf_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gf_Scale) - me*(f_LO2 % gf_Scale); ++ ++ *fp = ((f_Spur + (SData_t) f) / (me - n)) + 1; ++ *fm = (((SData_t) f - f_Spur) / (me - n)) + 1; ++ return 1; ++ } ++ ++ mb = (n*((f_LO1+hgcs)/gc_Scale) + ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); ++ if (ma != mb) ++ { ++ f_nsLO1 = n*(f_LO1/gc_Scale); ++ f_nsLO2 = ma*(f_LO2/gc_Scale); ++ f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - ma*(f_LO2 % gc_Scale); ++ ++ *fp = (((SData_t) d + f_Spur) / (ma - n)) + 1; ++ *fm = (-(f_Spur + (SData_t) c) / (ma - n)) + 1; ++ return 1; ++ } ++ } ++ ++#if MT_TUNER_CNT > 1 ++ /* If no spur found, see if there are more tuners on the same board */ ++ for (index = 0; index < TunerCount; ++index) ++ { ++ adj = TunerList[index]; ++ if (pAS_Info == adj) /* skip over our own data, don't process it */ ++ continue; ++ ++ /* Look for LO-related spurs from the adjacent tuner generated into my IF output */ ++ if (IsSpurInAdjTunerBand(1, /* check my IF output */ ++ pAS_Info->f_LO1, /* my fLO1 */ ++ adj->f_LO1, /* the other tuner's fLO1 */ ++ pAS_Info->f_LO2, /* my fLO2 */ ++ pAS_Info->f_out, /* my fOut */ ++ pAS_Info->f_out_bw, /* my output IF bandwidth */ ++ pAS_Info->f_zif_bw, /* my Zero-IF bandwidth */ ++ pAS_Info->maxH2, ++ fp, /* minimum amount to move LO's positive */ ++ fm)) /* miminum amount to move LO's negative */ ++ return 1; ++ /* Look for LO-related spurs from my tuner generated into the adjacent tuner's IF output */ ++ if (IsSpurInAdjTunerBand(0, /* check his IF output */ ++ pAS_Info->f_LO1, /* my fLO1 */ ++ adj->f_LO1, /* the other tuner's fLO1 */ ++ adj->f_LO2, /* the other tuner's fLO2 */ ++ adj->f_out, /* the other tuner's fOut */ ++ adj->f_out_bw, /* the other tuner's output IF bandwidth */ ++ pAS_Info->f_zif_bw, /* the other tuner's Zero-IF bandwidth */ ++ adj->maxH2, ++ fp, /* minimum amount to move LO's positive */ ++ fm)) /* miminum amount to move LO's negative */ ++ return 1; ++ } ++#endif ++ /* No spurs found */ ++ return 0; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_AvoidSpurs ++** ++** Description: Main entry point to avoid spurs. ++** Checks for existing spurs in present LO1, LO2 freqs ++** and if present, chooses spur-free LO1, LO2 combination ++** that tunes the same input/output frequencies. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. ++** ++*****************************************************************************/ ++UData_t MT2063_AvoidSpurs(Handle_t h, ++ MT2063_AvoidSpursData_t* pAS_Info) ++{ ++ UData_t status = MT_OK; ++ UData_t fm, fp; /* restricted range on LO's */ ++ pAS_Info->bSpurAvoided = 0; ++ pAS_Info->nSpursFound = 0; ++ h; /* warning expected: code has no effect */ ++ ++ if (pAS_Info->maxH1 == 0) ++ return MT_OK; ++ ++ /* ++ ** Avoid LO Generated Spurs ++ ** ++ ** Make sure that have no LO-related spurs within the IF output ++ ** bandwidth. ++ ** ++ ** If there is an LO spur in this band, start at the current IF1 frequency ++ ** and work out until we find a spur-free frequency or run up against the ++ ** 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they ++ ** will be unchanged if a spur-free setting is not found. ++ */ ++ pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp); ++ if (pAS_Info->bSpurPresent) ++ { ++ UData_t zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */ ++ UData_t zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */ ++ UData_t zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */ ++ UData_t delta_IF1; ++ UData_t new_IF1; ++ UData_t added; /* success of Excl Zone addition */ ++ ++ /* ++ ** Spur was found, attempt to find a spur-free 1st IF ++ */ ++ do ++ { ++ pAS_Info->nSpursFound++; ++ ++ /* Raise f_IF1_upper, if needed */ ++ added = MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp); ++ ++ /* ++ ** If Exclusion Zone could NOT be added, then we'll just keep picking ++ ** the same bad point, so exit this loop and report that there is a ++ ** spur present in the output ++ */ ++ if (!added) ++ break; ++ ++ /* Choose next IF1 that is closest to f_IF1_CENTER */ ++ new_IF1 = MT2063_ChooseFirstIF(pAS_Info); ++ ++ if (new_IF1 > zfIF1) ++ { ++ pAS_Info->f_LO1 += (new_IF1 - zfIF1); ++ pAS_Info->f_LO2 += (new_IF1 - zfIF1); ++ } ++ else ++ { ++ pAS_Info->f_LO1 -= (zfIF1 - new_IF1); ++ pAS_Info->f_LO2 -= (zfIF1 - new_IF1); ++ } ++ zfIF1 = new_IF1; ++ ++ if (zfIF1 > pAS_Info->f_if1_Center) ++ delta_IF1 = zfIF1 - pAS_Info->f_if1_Center; ++ else ++ delta_IF1 = pAS_Info->f_if1_Center - zfIF1; ++ } ++ /* ++ ** Continue while the new 1st IF is still within the 1st IF bandwidth ++ ** and there is a spur in the band (again) ++ */ ++ while ((2*delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && ++ (pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp))); ++ ++ /* ++ ** Use the LO-spur free values found. If the search went all the way to ++ ** the 1st IF band edge and always found spurs, just leave the original ++ ** choice. It's as "good" as any other. ++ */ ++ if (pAS_Info->bSpurPresent == 1) ++ { ++ status |= MT_SPUR_PRESENT; ++ pAS_Info->f_LO1 = zfLO1; ++ pAS_Info->f_LO2 = zfLO2; ++ } ++ else ++ pAS_Info->bSpurAvoided = 1; ++ } ++ ++ status |= ((pAS_Info->nSpursFound << MT_SPUR_SHIFT) & MT_SPUR_CNT_MASK); ++ ++ return (status); ++} ++ ++ ++UData_t MT2063_AvoidSpursVersion(void) ++{ ++ return (MT_SPURAVOID_VERSION); ++} ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2063.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2063.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2063.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2063.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,2206 @@ ++#ifndef __TUNER_MT2063_H ++#define __TUNER_MT2063_H ++ ++/** ++ ++@file ++ ++@brief MT2063 tuner module declaration ++ ++One can manipulate MT2063 tuner through MT2063 module. ++MT2063 module is derived from tunerd module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_mt2063.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long IfFreqHz; ++ ++ ++ ... ++ ++ ++ ++ // Build MT2063 tuner module. ++ BuildMt2063Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0 // I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTunerExtra = &(pTuner->pExtra.Mt2063); ++ ++ // Open MT2063 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MT2063 IF frequency. ++ pTunerExtra->SetIfFreqHz(pTuner, IF_FREQ_36125000HZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MT2063 IF frequency. ++ pTunerExtra->SetIfFreqHz(pTuner, &IfFreqHz); ++ ++ ++ ++ ++ ++ // Close MT2063 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_errordef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_errordef.h ++** ++** Copyright 2004-2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_errordef.h ++** ++** Description: Definition of bits in status/error word used by various ++** MicroTuner control programs. ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_errordef.h,v 1.2 2008/11/05 13:46:19 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_errordef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 09-09-2004 JWS Original ++** 088 01-26-2005 DAD Added MT_TUNER_INIT_ERR. ++** N/A 12-09-2005 DAD Added MT_TUNER_TIMEOUT (info). ++** N/A 10-17-2006 JWS Updated copyright notice. ++** N/A L 02-25-2008 RSK Correcting Comment Block to match constants. ++** ++*****************************************************************************/ ++ ++/* ++** Note to users: DO NOT EDIT THIS FILE ++** ++** If you wish to rename any of the "user defined" bits, ++** it should be done in the user file that includes this ++** source file (e.g. mt_userdef.h) ++** ++*/ ++ ++ ++ ++/* ++** 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 ++** 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ++** M U <- Info Codes --> <# Spurs> < User> <----- Err Codes -----> ++** ++** 31 = MT_ERROR - Master Error Flag. If set, check Err Codes for reason. ++** 30 = MT_USER_ERROR - User-declared error flag. ++** 29 = Unused ++** 28 = Unused ++** ++** 27 = MT_DNC_RANGE ++** 26 = MT_UPC_RANGE ++** 25 = MT_FOUT_RANGE ++** 24 = MT_FIN_OUT_OF_RANGE ++** ++** 23 = MT_SPUR_PRESENT - Unavoidable spur in output ++** 22 = MT_TUNER_TIMEOUT ++** 21 = Unused ++** 20 = MT_SPUR_CNT_MASK (MSB) - Count of avoided spurs ++** ++** 19 = MT_SPUR_CNT_MASK ++** 18 = MT_SPUR_CNT_MASK ++** 17 = MT_SPUR_CNT_MASK ++** 16 = MT_SPUR_CNT_MASK (LSB) ++** ++** 15 = MT_USER_DEFINED4 - User-definable bit (see MT_Userdef.h) ++** 14 = MT_USER_DEFINED3 - User-definable bit (see MT_Userdef.h) ++** 13 = MT_USER_DEFINED2 - User-definable bit (see MT_Userdef.h) ++** 12 = MT_USER_DEFINED1 - User-definable bit (see MT_Userdef.h) ++** ++** 11 = Unused ++** 10 = Unused ++** 9 = MT_TUNER_INIT_ERR - Tuner initialization error ++** 8 = MT_TUNER_ID_ERR - Tuner Part Code / Rev Code mismatches expected value ++** ++** 7 = MT_TUNER_CNT_ERR - Attempt to open more than MT_TUNER_CNT tuners ++** 6 = MT_ARG_NULL - Null pointer passed as argument ++** 5 = MT_ARG_RANGE - Argument value out of range ++** 4 = MT_INV_HANDLE - Tuner handle is invalid ++** ++** 3 = MT_COMM_ERR - Serial bus communications error ++** 2 = MT_DNC_UNLOCK - Downconverter PLL is unlocked ++** 1 = MT_UPC_UNLOCK - Upconverter PLL is unlocked ++** 0 = MT_UNKNOWN - Unknown error ++*/ ++#define MT_ERROR (1 << 31) ++#define MT_USER_ERROR (1 << 30) ++ ++/* Macro to be used to check for errors */ ++#define MT_IS_ERROR(s) (((s) >> 30) != 0) ++#define MT_NO_ERROR(s) (((s) >> 30) == 0) ++ ++ ++#define MT_OK (0x00000000) ++ ++/* Unknown error */ ++#define MT_UNKNOWN (0x80000001) ++ ++/* Error: Upconverter PLL is not locked */ ++#define MT_UPC_UNLOCK (0x80000002) ++ ++/* Error: Downconverter PLL is not locked */ ++#define MT_DNC_UNLOCK (0x80000004) ++ ++/* Error: Two-wire serial bus communications error */ ++#define MT_COMM_ERR (0x80000008) ++ ++/* Error: Tuner handle passed to function was invalid */ ++#define MT_INV_HANDLE (0x80000010) ++ ++/* Error: Function argument is invalid (out of range) */ ++#define MT_ARG_RANGE (0x80000020) ++ ++/* Error: Function argument (ptr to return value) was NULL */ ++#define MT_ARG_NULL (0x80000040) ++ ++/* Error: Attempt to open more than MT_TUNER_CNT tuners */ ++#define MT_TUNER_CNT_ERR (0x80000080) ++ ++/* Error: Tuner Part Code / Rev Code mismatches expected value */ ++#define MT_TUNER_ID_ERR (0x80000100) ++ ++/* Error: Tuner Initialization failure */ ++#define MT_TUNER_INIT_ERR (0x80000200) ++ ++/* User-definable fields (see mt_userdef.h) */ ++#define MT_USER_DEFINED1 (0x00001000) ++#define MT_USER_DEFINED2 (0x00002000) ++#define MT_USER_DEFINED3 (0x00004000) ++#define MT_USER_DEFINED4 (0x00008000) ++#define MT_USER_MASK (0x4000f000) ++#define MT_USER_SHIFT (12) ++ ++/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */ ++#define MT_SPUR_CNT_MASK (0x001f0000) ++#define MT_SPUR_SHIFT (16) ++ ++/* Info: Tuner timeout waiting for condition */ ++#define MT_TUNER_TIMEOUT (0x00400000) ++ ++/* Info: Unavoidable LO-related spur may be present in the output */ ++#define MT_SPUR_PRESENT (0x00800000) ++ ++/* Info: Tuner input frequency is out of range */ ++#define MT_FIN_RANGE (0x01000000) ++ ++/* Info: Tuner output frequency is out of range */ ++#define MT_FOUT_RANGE (0x02000000) ++ ++/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */ ++#define MT_UPC_RANGE (0x04000000) ++ ++/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */ ++#define MT_DNC_RANGE (0x08000000) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.h ++** ++** Copyright 2006-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable and the terms of the end-user software ++** license agreement (EULA). ++** ++** Protected by US Patent 7,035,614 and additional patents pending or filed. ++** ++** BY INSTALLING, COPYING, OR USING THE MICROTUNE SOFTWARE, YOU AGREE TO BE ++** BOUND BY ALL OF THE TERMS AND CONDITIONS OF THE MICROTUNE, INC. END-USER ++** SOFTWARE LICENSE AGREEMENT (EULA), INCLUDING BUT NOT LIMITED TO, THE ++** CONFIDENTIALITY OBLIGATIONS DESCRIBED THEREIN. IF YOU DO NOT AGREE, DO NOT ++** INSTALL, COPY, OR USE THE MICROTUNE SOFTWARE AND IMMEDIATELY RETURN OR ++** DESTROY ANY COPIES OF MICROTUNE SOFTWARE OR CONFIDENTIAL INFORMATION THAT ++** YOU HAVE IN YOUR POSSESSION. ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.h ++** ++** Description: User-defined data types needed by MicroTuner source code. ++** ++** Customers must provide the code for these functions ++** in the file "mt_userdef.c". ++** ++** Customers must verify that the typedef's in the ++** "Data Types" section are correct for their platform. ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.h,v 1.2 2008/11/05 13:46:20 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_userdef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** 082 12-06-2004 JWS Multi-tuner support - requires MTxxxx_CNT ++** declarations ++** N/A 04-13-2007 JWS Added Signed 8-bit type - S8Data ++** 200 08-07-2008 JWS Included definition of DECT avoid constants. ++** ++*****************************************************************************/ ++#if !defined( __MT_USERDEF_H ) ++#define __MT_USERDEF_H ++ ++//#include "mt_errordef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++#if !defined( __MT_DATA_DEF_H ) ++#define __MT_DATA_DEF_H ++/* ++** Data Types ++*/ ++typedef unsigned char U8Data; /* type corresponds to 8 bits */ ++typedef signed char S8Data; /* type corresponds to 8 bits */ ++typedef unsigned int UData_t; /* type must be at least 32 bits */ ++typedef int SData_t; /* type must be at least 32 bits */ ++typedef void * Handle_t; /* memory pointer type */ ++typedef double FData_t; /* floating point data type */ ++#endif ++#define MAX_UDATA (4294967295) /* max value storable in UData_t */ ++ ++/* ++** Define an MTxxxx_CNT macro for each type of tuner that will be built ++** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT ++** must be set to the SUM of all of the MTxxxx_CNT macros. ++** ++** #define MT2050_CNT (1) ++** #define MT2060_CNT (1) ++** #define MT2111_CNT (1) ++** #define MT2121_CNT (3) ++*/ ++ ++ ++#if !defined( MT_TUNER_CNT ) ++#define MT_TUNER_CNT (1) /* total num of MicroTuner tuners */ ++#endif ++ ++#ifndef _MT_DECT_Avoid_Type_DEFINE_ ++#define _MT_DECT_Avoid_Type_DEFINE_ ++// ++// DECT Frequency Avoidance: ++// These constants are used to avoid interference from DECT frequencies. ++// ++typedef enum ++{ ++ MT_NO_DECT_AVOIDANCE = 0x00000000, // Do not create DECT exclusion zones. ++ MT_AVOID_US_DECT = 0x00000001, // Avoid US DECT frequencies. ++ MT_AVOID_EURO_DECT = 0x00000002, // Avoid European DECT frequencies. ++ MT_AVOID_BOTH // Avoid both regions. Not typically used. ++} MT_DECT_Avoid_Type; ++#endif ++/* ++** Optional user-defined Error/Info Codes (examples below) ++** ++** This is the area where you can define user-specific error/info return ++** codes to be returned by any of the functions you are responsible for ++** writing such as MT_WriteSub() and MT_ReadSub. There are four bits ++** available in the status field for your use. When set, these ++** bits will be returned in the status word returned by any tuner driver ++** call. If you OR in the MT_ERROR bit as well, the tuner driver code ++** will treat the code as an error. ++** ++** The following are a few examples of errors you can provide. ++** ++** Example 1: ++** You might check to see the hUserData handle is correct and issue ++** MY_USERDATA_INVALID which would be defined like this: ++** ++** #define MY_USERDATA_INVALID (MT_USER_ERROR | MT_USER_DEFINED1) ++** ++** ++** Example 2: ++** You might be able to provide more descriptive two-wire bus errors: ++** ++** #define NO_ACK (MT_USER_ERROR | MT_USER_DEFINED1) ++** #define NO_NACK (MT_USER_ERROR | MT_USER_DEFINED2) ++** #define BUS_BUSY (MT_USER_ERROR | MT_USER_DEFINED3) ++** ++** ++** Example 3: ++** You can also provide information (non-error) feedback: ++** ++** #define MY_INFO_1 (MT_USER_DEFINED1) ++** ++** ++** Example 4: ++** You can combine the fields together to make a multi-bit field. ++** This one can provide the tuner number based off of the addr ++** passed to MT_WriteSub or MT_ReadSub. It assumes that ++** MT_USER_DEFINED4 through MT_USER_DEFINED1 are contiguously. If ++** TUNER_NUM were OR'ed into the status word on an error, you could ++** use this to identify which tuner had the problem (and whether it ++** was during a read or write operation). ++** ++** #define TUNER_NUM ((addr & 0x07) >> 1) << MT_USER_SHIFT ++** ++*/ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2063_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime); ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (for MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas); ++#endif ++#endif ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt2063.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt2063.h ++** ++** Copyright 2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2063.h ++** ++** Description: Microtune MT2063 B0/B1 Tuner software interface ++** Supports tuners with Part/Rev codes: 0x9B, 0x9C. ++** ++** Functions ++** Implemented: UData_t MT2063_Open ++** UData_t MT2063_Close ++** UData_t MT2063_GetGPIO ++** UData_t MT2063_GetLocked ++** UData_t MT2063_GetParam ++** UData_t MT2063_GetPowerMaskBits ++** UData_t MT2063_GetReg ++** UData_t MT2063_GetTemp ++** UData_t MT2063_GetUserData ++** UData_t MT2063_ReInit ++** UData_t MT2063_SetGPIO ++** UData_t MT2063_SetParam ++** UData_t MT2063_SetPowerMaskBits ++** UData_t MT2063_ClearPowerMaskBits ++** UData_t MT2063_SetReg ++** UData_t MT2063_Tune ++** ++** References: AN-xxxxx: MT2063 Programming Procedures Application Note ++** MicroTune, Inc. ++** AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Enumerations ++** Defined: MT2063_Ext_SRO ++** MT2063_Param ++** MT2063_Mask_Bits ++** MT2063_GPIO_Attr; ++** MT2063_Temperature ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for nMinDelayTime milliseconds ++** ++** CVS ID: $Id: mt2063.h,v 1.5 2009/04/29 09:58:14 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt2063.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** N/A 08-01-2007 PINZ Changed Analog & DVB-T settings and added ++** SAW-less receiver mode. ++** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive ++** modulation ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have ++** the same settings as with MT Launcher ++** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI ++** Add SetParam DNC_OUTPUT_ENABLE ++** Removed VGAGC from receiver mode, ++** default now 1 ++** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode ++** Add SetParam AMPGC, removed from rcvr-mode ++** Corrected names of GCU values ++** Actualized Receiver-Mode values ++** N/A 04-18-2008 PINZ Ver 1.09: Add SetParam LNA_TGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 06-06-2008 PINZ Ver 1.10: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 175 I 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** 01-07-2009 PINZ Ver 1.27: Changed value of MT2063_ALL_SD in .h ++** 02-16-2009 PINZ Ver 1.29: Several fixes to improve compiler behavior ++** N/A I 03-19-2009 PINZ Ver 1.32: Add GetParam VERSION (of API) ++** Add GetParam IC_REV ++*****************************************************************************/ ++#if !defined( __MT2063_H ) ++#define __MT2063_H ++ ++//#include "mt_userdef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++ ++/* ++** Chip revision ++** ++*/ ++typedef enum ++{ ++ MT2063_XX = 0, ++ MT2063_B0 = 206310, ++ MT2063_B1 = 206311, ++ MT2063_B3 = 206313 ++} MT2063_REVCODE; ++ ++ ++/* ++** Values returned by the MT2063's on-chip temperature sensor ++** to be read/written. ++*/ ++typedef enum ++{ ++ MT2063_T_0C = 0, /* Temperature approx 0C */ ++ MT2063_T_10C, /* Temperature approx 10C */ ++ MT2063_T_20C, /* Temperature approx 20C */ ++ MT2063_T_30C, /* Temperature approx 30C */ ++ MT2063_T_40C, /* Temperature approx 40C */ ++ MT2063_T_50C, /* Temperature approx 50C */ ++ MT2063_T_60C, /* Temperature approx 60C */ ++ MT2063_T_70C, /* Temperature approx 70C */ ++ MT2063_T_80C, /* Temperature approx 80C */ ++ MT2063_T_90C, /* Temperature approx 90C */ ++ MT2063_T_100C, /* Temperature approx 100C */ ++ MT2063_T_110C, /* Temperature approx 110C */ ++ MT2063_T_120C, /* Temperature approx 120C */ ++ MT2063_T_130C, /* Temperature approx 130C */ ++ MT2063_T_140C, /* Temperature approx 140C */ ++ MT2063_T_150C /* Temperature approx 150C */ ++} MT2063_Temperature; ++ ++ ++/* ++** Parameters for selecting GPIO bits ++*/ ++typedef enum ++{ ++ MT2063_GPIO_IN, ++ MT2063_GPIO_DIR, ++ MT2063_GPIO_OUT ++} MT2063_GPIO_Attr; ++ ++typedef enum ++{ ++ MT2063_GPIO0, ++ MT2063_GPIO1, ++ MT2063_GPIO2 ++} MT2063_GPIO_ID; ++ ++ ++/* ++** Parameter for function MT2063_SetExtSRO that specifies the external ++** SRO drive frequency. ++** ++** MT2063_EXT_SRO_OFF is the power-up default value. ++*/ ++typedef enum ++{ ++ MT2063_EXT_SRO_OFF, /* External SRO drive off */ ++ MT2063_EXT_SRO_BY_4, /* External SRO drive divide by 4 */ ++ MT2063_EXT_SRO_BY_2, /* External SRO drive divide by 2 */ ++ MT2063_EXT_SRO_BY_1 /* External SRO drive divide by 1 */ ++} MT2063_Ext_SRO; ++ ++ ++/* ++** Parameter for function MT2063_SetPowerMask that specifies the power down ++** of various sections of the MT2063. ++*/ ++typedef enum ++{ ++ MT2063_REG_SD = 0x0040, /* Shutdown regulator */ ++ MT2063_SRO_SD = 0x0020, /* Shutdown SRO */ ++ MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */ ++ MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */ ++ MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */ ++ MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */ ++ MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */ ++ MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */ ++ MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */ ++ MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */ ++ MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */ ++ MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */ ++ MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */ ++ MT2063_ALL_SD = 0xFF13, /* All shutdown bits for this tuner */ ++ MT2063_NONE_SD = 0x0000 /* No shutdown bits */ ++} MT2063_Mask_Bits; ++ ++ ++/* ++** Parameter for function MT2063_GetParam & MT2063_SetParam that ++** specifies the tuning algorithm parameter to be read/written. ++*/ ++typedef enum ++{ ++ /* version of the API, e.g. 10302 = 1.32 */ ++ MT2063_VERSION, ++ ++ /* tuner address set by MT2063_Open() */ ++ MT2063_IC_ADDR, ++ ++ /* tuner revision code (see enum MT2063_REVCODE for values) */ ++ MT2063_IC_REV, ++ ++ /* max number of MT2063 tuners set by MT_TUNER_CNT in mt_userdef.h */ ++ MT2063_MAX_OPEN, ++ ++ /* current number of open MT2063 tuners set by MT2063_Open() */ ++ MT2063_NUM_OPEN, ++ ++ /* crystal frequency (default: 16000000 Hz) */ ++ MT2063_SRO_FREQ, ++ ++ /* min tuning step size (default: 50000 Hz) */ ++ MT2063_STEPSIZE, ++ ++ /* input center frequency set by MT2063_Tune() */ ++ MT2063_INPUT_FREQ, ++ ++ /* LO1 Frequency set by MT2063_Tune() */ ++ MT2063_LO1_FREQ, ++ ++ /* LO1 minimum step size (default: 250000 Hz) */ ++ MT2063_LO1_STEPSIZE, ++ ++ /* LO1 FracN keep-out region (default: 999999 Hz) */ ++ MT2063_LO1_FRACN_AVOID, ++ ++ /* Current 1st IF in use set by MT2063_Tune() */ ++ MT2063_IF1_ACTUAL, ++ ++ /* Requested 1st IF set by MT2063_Tune() */ ++ MT2063_IF1_REQUEST, ++ ++ /* Center of 1st IF SAW filter (default: 1218000000 Hz) */ ++ MT2063_IF1_CENTER, ++ ++ /* Bandwidth of 1st IF SAW filter (default: 20000000 Hz) */ ++ MT2063_IF1_BW, ++ ++ /* zero-IF bandwidth (default: 2000000 Hz) */ ++ MT2063_ZIF_BW, ++ ++ /* LO2 Frequency set by MT2063_Tune() */ ++ MT2063_LO2_FREQ, ++ ++ /* LO2 minimum step size (default: 50000 Hz) */ ++ MT2063_LO2_STEPSIZE, ++ ++ /* LO2 FracN keep-out region (default: 374999 Hz) */ ++ MT2063_LO2_FRACN_AVOID, ++ ++ /* output center frequency set by MT2063_Tune() */ ++ MT2063_OUTPUT_FREQ, ++ ++ /* output bandwidth set by MT2063_Tune() */ ++ MT2063_OUTPUT_BW, ++ ++ /* min inter-tuner LO separation (default: 1000000 Hz) */ ++ MT2063_LO_SEPARATION, ++ ++ /* ID of avoid-spurs algorithm in use compile-time constant */ ++ MT2063_AS_ALG, ++ ++ /* max # of intra-tuner harmonics (default: 15) */ ++ MT2063_MAX_HARM1, ++ ++ /* max # of inter-tuner harmonics (default: 7) */ ++ MT2063_MAX_HARM2, ++ ++ /* # of 1st IF exclusion zones used set by MT2063_Tune() */ ++ MT2063_EXCL_ZONES, ++ ++ /* # of spurs found/avoided set by MT2063_Tune() */ ++ MT2063_NUM_SPURS, ++ ++ /* >0 spurs avoided set by MT2063_Tune() */ ++ MT2063_SPUR_AVOIDED, ++ ++ /* >0 spurs in output (mathematically) set by MT2063_Tune() */ ++ MT2063_SPUR_PRESENT, ++ ++ /* Receiver Mode for some parameters. 1 is DVB-T */ ++ MT2063_RCVR_MODE, ++ ++ /* directly set LNA attenuation, parameter is value to set */ ++ MT2063_ACLNA, ++ ++ /* maximum LNA attenuation, parameter is value to set */ ++ MT2063_ACLNA_MAX, ++ ++ /* directly set ATN attenuation. Paremeter is value to set. */ ++ MT2063_ACRF, ++ ++ /* maxium ATN attenuation. Paremeter is value to set. */ ++ MT2063_ACRF_MAX, ++ ++ /* directly set FIF attenuation. Paremeter is value to set. */ ++ MT2063_ACFIF, ++ ++ /* maxium FIF attenuation. Paremeter is value to set. */ ++ MT2063_ACFIF_MAX, ++ ++ /* LNA Rin */ ++ MT2063_LNA_RIN, ++ ++ /* Power Detector LNA level target */ ++ MT2063_LNA_TGT, ++ ++ /* Power Detector 1 level */ ++ MT2063_PD1, ++ ++ /* Power Detector 1 level target */ ++ MT2063_PD1_TGT, ++ ++ /* Power Detector 2 level */ ++ MT2063_PD2, ++ ++ /* Power Detector 2 level target */ ++ MT2063_PD2_TGT, ++ ++ /* Selects, which DNC is activ */ ++ MT2063_DNC_OUTPUT_ENABLE, ++ ++ /* VGA gain code */ ++ MT2063_VGAGC, ++ ++ /* VGA bias current */ ++ MT2063_VGAOI, ++ ++ /* TAGC, determins the speed of the AGC */ ++ MT2063_TAGC, ++ ++ /* AMP gain code */ ++ MT2063_AMPGC, ++ ++ /* Control setting to avoid DECT freqs (default: MT_AVOID_BOTH) */ ++ MT2063_AVOID_DECT, ++ ++ /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ ++ MT2063_CTFILT_SW, ++ ++ MT2063_EOP /* last entry in enumerated list */ ++ ++} MT2063_Param; ++ ++ ++/* ++** Parameter for selecting tuner mode ++*/ ++typedef enum ++{ ++ MT2063_CABLE_QAM = 0, /* Digital cable */ ++ MT2063_CABLE_ANALOG, /* Analog cable */ ++ MT2063_OFFAIR_COFDM, /* Digital offair */ ++ MT2063_OFFAIR_COFDM_SAWLESS, /* Digital offair without SAW */ ++ MT2063_OFFAIR_ANALOG, /* Analog offair */ ++ MT2063_OFFAIR_8VSB, /* Analog offair */ ++ MT2063_NUM_RCVR_MODES ++} MT2063_RCVR_MODES; ++ ++ ++/* ++** Possible values for MT2063_DNC_OUTPUT ++*/ ++typedef enum { ++ MT2063_DNC_NONE = 0, ++ MT2063_DNC_1, ++ MT2063_DNC_2, ++ MT2063_DNC_BOTH ++} MT2063_DNC_Output_Enable; ++ ++ ++/* ====== Functions which are declared in MT2063.c File ======= */ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Usage: status = MT2063_Open(0xC0, &hMT2063, NULL); ++** if (MT_IS_ERROR(status)) ++** // Check error codes for reason ++** ++** Parameters: MT2063_Addr - Serial bus address of the tuner. ++** hMT2063 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_COMM_ERR - Serial bus communications error ++** MT_ARG_NULL - Null pointer argument passed ++** MT_TUNER_CNT_ERR - Too many tuners open ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Open(UData_t MT2063_Addr, ++ Handle_t* hMT2063, ++ Handle_t hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2063 - Handle to the MT2063 tuner ++** ++** Usage: status = MT2063_Close(hMT2063); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Close(Handle_t hMT2063); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_Tune ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** f_in - RF input center frequency (in Hz). ++** ++** Usage: status = MT2063_Tune(hMT2063, ++** f_in) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_SPUR_CNT_MASK - Count of avoided LO spurs ++** MT_SPUR_PRESENT - LO spur possible in output ++** MT_FIN_RANGE - Input freq out of range ++** MT_FOUT_RANGE - Output freq out of range ++** MT_UPC_RANGE - Upconverter freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune! ++** ++** MT_ReadSub - Read data from the two-wire serial bus ++** MT_WriteSub - Write data to the two-wire serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_Tune(Handle_t h, ++ UData_t f_in); /* RF input center frequency */ ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetGPIO ++** ++** Description: Get the current MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** attr - Selects input readback, I/O direction or ++** output value ++** bit - Selects GPIO0, GPIO1, or GPIO2 ++** *value - current setting of GPIO pin ++** ++** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO2, &value); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetGPIO(Handle_t h, MT2063_GPIO_ID gpio_id, MT2063_GPIO_Attr attr, UData_t* value); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetLocked ++** ++** Description: Checks to see if LO1 and LO2 are locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** ++** Usage: status = MT2063_GetLocked(hMT2063); ++** if (status & (MT_UPC_UNLOCK | MT_DNC_UNLOCK)) ++** // error!, one or more PLL's unlocked ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetLocked(Handle_t h); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_IC_ADDR Serial Bus address of this tuner ++** MT2063_MAX_OPEN Max # of MT2063's allowed open ++** MT2063_NUM_OPEN # of MT2063's open ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_INPUT_FREQ input center frequency ++** MT2063_LO1_FREQ LO1 Frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_ACTUAL Current 1st IF in use ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_IF1_CENTER Center of 1st IF SAW filter ++** MT2063_IF1_BW Bandwidth of 1st IF SAW filter ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 Frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_AS_ALG ID of avoid-spurs algorithm in use ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_EXCL_ZONES # of 1st IF exclusion zones ++** MT2063_NUM_SPURS # of spurs found/avoided ++** MT2063_SPUR_AVOIDED >0 spurs avoided ++** MT2063_SPUR_PRESENT >0 spurs in output (mathematically) ++** MT2063_RCVR_MODE Predefined modes. ++** MT2063_LNA_RIN Get LNA RIN value ++** MT2063_LNA_TGT Get target power level at LNA ++** MT2063_PD1_TGT Get target power level at PD1 ++** MT2063_PD2_TGT Get target power level at PD2 ++** MT2063_ACLNA LNA attenuator gain code ++** MT2063_ACRF RF attenuator gain code ++** MT2063_ACFIF FIF attenuator gain code ++** MT2063_ACLNA_MAX LNA attenuator limit ++** MT2063_ACRF_MAX RF attenuator limit ++** MT2063_ACFIF_MAX FIF attenuator limit ++** MT2063_PD1 Actual value of PD1 ++** MT2063_PD2 Actual value of PD2 ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** Usage: status |= MT2063_GetParam(hMT2063, ++** MT2063_IF1_ACTUAL, ++** &f_IF1_Actual); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_SetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW ++** in GetParam. ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** ++****************************************************************************/ ++UData_t MT2063_GetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t* pValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetReg ++** ++** Description: Gets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** *val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2063. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetTemp ++** ++** Description: Get the MT2063 Temperature register. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** *value - value read from the register ++** ++** Binary ++** Value Returned Value Approx Temp ++** --------------------------------------------- ++** MT2063_T_0C 0000 0C ++** MT2063_T_10C 0001 10C ++** MT2063_T_20C 0010 20C ++** MT2063_T_30C 0011 30C ++** MT2063_T_40C 0100 40C ++** MT2063_T_50C 0101 50C ++** MT2063_T_60C 0110 60C ++** MT2063_T_70C 0111 70C ++** MT2063_T_80C 1000 80C ++** MT2063_T_90C 1001 90C ++** MT2063_T_100C 1010 100C ++** MT2063_T_110C 1011 110C ++** MT2063_T_120C 1100 120C ++** MT2063_T_130C 1101 130C ++** MT2063_T_140C 1110 140C ++** MT2063_T_150C 1111 150C ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetTemp(Handle_t h, MT2063_Temperature* value); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Usage: status = MT2063_GetUserData(hMT2063, &hUserData); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetUserData(Handle_t h, ++ Handle_t* hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_ReInit(Handle_t h); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_SetGPIO ++** ++** Description: Modify the MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** gpio_id - Selects GPIO0, GPIO1, or GPIO2 ++** attr - Selects input readback, I/O direction or ++** output value ++** value - value to set GPIO pin ++** ++** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_SetGPIO(Handle_t h, MT2063_GPIO_ID gpio_id, MT2063_GPIO_Attr attr, UData_t value); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_LO1_FREQ LO1 frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_RCVR_MODE Predefined modes ++** MT2063_LNA_RIN Set LNA Rin (*) ++** MT2063_LNA_TGT Set target power level at LNA (*) ++** MT2063_PD1_TGT Set target power level at PD1 (*) ++** MT2063_PD2_TGT Set target power level at PD2 (*) ++** MT2063_ACLNA_MAX LNA attenuator limit (*) ++** MT2063_ACRF_MAX RF attenuator limit (*) ++** MT2063_ACFIF_MAX FIF attenuator limit (*) ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** (*) This parameter is set by MT2063_RCVR_MODE, do not call ++** additionally. ++** ++** Usage: status |= MT2063_SetParam(hMT2063, ++** MT2063_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_GetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** ++****************************************************************************/ ++UData_t MT2063_SetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t nValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetPowerMaskBits ++** ++** Description: Sets the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be set. ++** ++** MT2063_ALL_SD All shutdown bits for this tuner ++** ++** MT2063_REG_SD Shutdown regulator ++** MT2063_SRO_SD Shutdown SRO ++** MT2063_AFC_SD Shutdown AFC A/D ++** MT2063_PD_SD Enable power detector shutdown ++** MT2063_PDADC_SD Enable power detector A/D shutdown ++** MT2063_VCO_SD Enable VCO shutdown VCO ++** MT2063_UPC_SD Enable upconverter shutdown ++** MT2063_DNC_SD Enable downconverter shutdown ++** MT2063_VGA_SD Enable VGA shutdown ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_ClearPowerMaskBits ++** ++** Description: Clears the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be cleared. ++** ++** MT2063_ALL_SD All shutdown bits for this tuner ++** ++** MT2063_REG_SD Shutdown regulator ++** MT2063_SRO_SD Shutdown SRO ++** MT2063_AFC_SD Shutdown AFC A/D ++** MT2063_PD_SD Enable power detector shutdown ++** MT2063_PDADC_SD Enable power detector A/D shutdown ++** MT2063_VCO_SD Enable VCO shutdown VCO ++** MT2063_UPC_SD Enable upconverter shutdown ++** MT2063_DNC_SD Enable downconverter shutdown ++** MT2063_VGA_SD Enable VGA shutdown ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_ClearPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetPowerMaskBits ++** ++** Description: Returns a mask of the enabled power shutdown bits ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to currently set. ++** ++** MT2063_REG_SD Shutdown regulator ++** MT2063_SRO_SD Shutdown SRO ++** MT2063_AFC_SD Shutdown AFC A/D ++** MT2063_PD_SD Enable power detector shutdown ++** MT2063_PDADC_SD Enable power detector A/D shutdown ++** MT2063_VCO_SD Enable VCO shutdown VCO ++** MT2063_UPC_SD Enable upconverter shutdown ++** MT2063_DNC_SD Enable downconverter shutdown ++** MT2063_VGA_SD Enable VGA shutdown ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Output argument is NULL ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetPowerMaskBits(Handle_t h, MT2063_Mask_Bits *Bits); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_EnableExternalShutdown ++** ++** Description: Enables or disables the operation of the external ++** shutdown pin ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Enabled - 0 = disable the pin, otherwise enable it ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SoftwareShutdown ++** ++** Description: Enables or disables software shutdown function. When ++** Shutdown==1, any section whose power mask is set will be ++** shutdown. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Shutdown - 1 = shutdown the masked sections, otherwise ++** power all sections on ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetExtSRO ++** ++** Description: Sets the external SRO driver. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Ext_SRO_Setting - external SRO drive setting ++** ++** (default) MT2063_EXT_SRO_OFF - ext driver off ++** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency ++** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency ++** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The Ext_SRO_Setting settings default to OFF ++** Use this function if you need to override the default ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetExtSRO(Handle_t h, MT2063_Ext_SRO Ext_SRO_Setting); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetReg ++** ++** Description: Sets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val); ++ ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_spuravoid.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.h ++** ++** Copyright 2006-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.h ++** ++** Description: Implements spur avoidance for MicroTuners ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_spuravoid.h,v 1.4 2008/11/05 13:46:20 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_spuravoid.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** 083 02-08-2005 JWS Added separate version number for expected ++** version of MT_SpurAvoid.h ++** 083 02-08-2005 JWS Added function to return the version of the ++** MT_AvoidSpurs source file. ++** 098 04-12-2005 DAD Increased MAX_ZONES from 32 to 48. 32 is ++** sufficient for the default avoidance params. ++** 103 01-31-2005 DAD In MT_AddExclZone(), if the range ++** (f_min, f_max) < 0, ignore the entry. ++** 195 M 06-20-2008 RSK Ver 1.21: Refactoring to place DECT frequency ++** avoidance (US and Euro) in 'SpurAvoidance'. ++** 199 08-06-2008 JWS Ver 1.22: Added 0x1x1 spur frequency calculations ++** and indicate success of AddExclZone operation. ++** 200 08-07-2008 JWS Ver 1.23: Moved definition of DECT avoid constants ++** so users could access them more easily. ++** ++*****************************************************************************/ ++#if !defined(__MT2063_SPURAVOID_H) ++#define __MT2063_SPURAVOID_H ++ ++//#include "mt_userdef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++/* ++** Constant defining the version of the following structure ++** and therefore the API for this code. ++** ++** When compiling the tuner driver, the preprocessor will ++** check against this version number to make sure that ++** it matches the version that the tuner driver knows about. ++*/ ++/* Version 010201 => 1.21 */ ++#define MT2063_AVOID_SPURS_INFO_VERSION 010201 ++ ++ ++#define MT2063_MAX_ZONES 48 ++ ++struct MT2063_ExclZone_t; ++ ++struct MT2063_ExclZone_t ++{ ++ UData_t min_; ++ UData_t max_; ++ struct MT2063_ExclZone_t* next_; ++}; ++#ifndef _MT_DECT_Avoid_Type_DEFINE_ ++#define _MT_DECT_Avoid_Type_DEFINE_ ++// ++// DECT Frequency Avoidance: ++// These constants are used to avoid interference from DECT frequencies. ++// ++typedef enum ++{ ++ MT_NO_DECT_AVOIDANCE = 0x00000000, // Do not create DECT exclusion zones. ++ MT_AVOID_US_DECT = 0x00000001, // Avoid US DECT frequencies. ++ MT_AVOID_EURO_DECT = 0x00000002, // Avoid European DECT frequencies. ++ MT_AVOID_BOTH // Avoid both regions. Not typically used. ++} MT_DECT_Avoid_Type; ++#endif ++ ++/* ++** Structure of data needed for Spur Avoidance ++*/ ++typedef struct ++{ ++ UData_t nAS_Algorithm; ++ UData_t f_ref; ++ UData_t f_in; ++ UData_t f_LO1; ++ UData_t f_if1_Center; ++ UData_t f_if1_Request; ++ UData_t f_if1_bw; ++ UData_t f_LO2; ++ UData_t f_out; ++ UData_t f_out_bw; ++ UData_t f_LO1_Step; ++ UData_t f_LO2_Step; ++ UData_t f_LO1_FracN_Avoid; ++ UData_t f_LO2_FracN_Avoid; ++ UData_t f_zif_bw; ++ UData_t f_min_LO_Separation; ++ UData_t maxH1; ++ UData_t maxH2; ++ MT_DECT_Avoid_Type avoidDECT; ++ UData_t bSpurPresent; ++ UData_t bSpurAvoided; ++ UData_t nSpursFound; ++ UData_t nZones; ++ struct MT2063_ExclZone_t* freeZones; ++ struct MT2063_ExclZone_t* usedZones; ++ struct MT2063_ExclZone_t MT_ExclZones[MT2063_MAX_ZONES]; ++} MT2063_AvoidSpursData_t; ++ ++UData_t MT2063_RegisterTuner(MT2063_AvoidSpursData_t* pAS_Info); ++ ++void MT2063_UnRegisterTuner(MT2063_AvoidSpursData_t* pAS_Info); ++ ++void MT2063_ResetExclZones(MT2063_AvoidSpursData_t* pAS_Info); ++ ++UData_t MT2063_AddExclZone(MT2063_AvoidSpursData_t* pAS_Info, ++ UData_t f_min, ++ UData_t f_max); ++ ++UData_t MT2063_ChooseFirstIF(MT2063_AvoidSpursData_t* pAS_Info); ++ ++UData_t MT2063_AvoidSpurs(Handle_t h, ++ MT2063_AvoidSpursData_t* pAS_Info); ++ ++UData_t MT2063_AvoidSpursVersion(void); ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MT2063 tuner API source code ++ ++ ++ ++ ++ ++/** ++ ++@file ++ ++@brief MT2063 tuner module declaration ++ ++One can manipulate MT2063 tuner through MT2063 module. ++MT2063 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// MT2063 API option ++#define MT2063_CNT 4 ++ ++// MT2063 macro ++//#define abs(x) ((x) < 0 ? -(x) : (x)) ++ ++// MT2063 bandwidth shift ++#define MT2063_BANDWIDTH_SHIFT_HZ 1000000 ++ ++ ++ ++// Bandwidth modes ++enum MT2063_BANDWIDTH_MODE ++{ ++ MT2063_BANDWIDTH_6MHZ = 6000000, ++ MT2063_BANDWIDTH_7MHZ = 7000000, ++ MT2063_BANDWIDTH_8MHZ = 8000000, ++}; ++ ++ ++// Standard modes ++enum MT2063_STANDARD_MODE ++{ ++ MT2063_STANDARD_DVBT, ++ MT2063_STANDARD_QAM, ++}; ++ ++ ++// VGAGC settings ++enum MT2063_VGAGC_SETTINGS ++{ ++ MT2063_VGAGC_0X0 = 0x0, ++ MT2063_VGAGC_0X1 = 0x1, ++ MT2063_VGAGC_0X3 = 0x3, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMt2063Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ int StandardMode, ++ unsigned long IfVgaGainControl ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++mt2063_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++mt2063_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++mt2063_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2063_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++mt2063_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++mt2063_OpenHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2063_CloseHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++void ++mt2063_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++int ++mt2063_SetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ); ++ ++int ++mt2063_GetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++mt2063_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++int ++mt2063_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2266.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2266.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2266.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2266.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,3277 @@ ++/** ++ ++@file ++ ++@brief MT2266 tuner module definition ++ ++One can manipulate MT2266 tuner through MT2266 module. ++MT2266 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_mt2266.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MT2266 tuner module builder ++ ++Use BuildMt2266Module() to build MT2266 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MT2266 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MT2266 I2C device address ++ ++ ++@note ++ -# One should call BuildMt2266Module() to build MT2266 module before using it. ++ ++*/ ++void ++BuildMt2266Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MT2266; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = mt2266_GetTunerType; ++ pTuner->GetDeviceAddr = mt2266_GetDeviceAddr; ++ ++ pTuner->Initialize = mt2266_Initialize; ++ pTuner->SetRfFreqHz = mt2266_SetRfFreqHz; ++ pTuner->GetRfFreqHz = mt2266_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->IsBandwidthHzSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->OpenHandle = mt2266_OpenHandle; ++ pExtra->CloseHandle = mt2266_CloseHandle; ++ pExtra->GetHandle = mt2266_GetHandle; ++ pExtra->SetBandwidthHz = mt2266_SetBandwidthHz; ++ pExtra->GetBandwidthHz = mt2266_GetBandwidthHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++mt2266_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++mt2266_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++mt2266_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Re-initialize tuner. ++ Status = MT2266_ReInit(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++mt2266_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner RF frequency in Hz. ++ Status = MT2266_ChangeFreq(DeviceHandle, RfFreqHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++mt2266_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Open MT2266 tuner handle. ++ ++*/ ++int ++mt2266_OpenHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ unsigned char DeviceAddr; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner I2C device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Open MT2266 handle. ++ // Note: 1. Must take tuner extra module DeviceHandle as handle input argument. ++ // 2. Take pTuner as user-defined data input argument. ++ Status = MT2266_Open(DeviceAddr, &pExtra->DeviceHandle, pTuner); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2266_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2266_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Close MT2266 tuner handle. ++ ++*/ ++int ++mt2266_CloseHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Close MT2266 handle. ++ Status = MT2266_Close(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2266_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2266_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2266 tuner handle. ++ ++*/ ++void ++mt2266_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ *pDeviceHandle = pExtra->DeviceHandle; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MT2266 tuner bandwidth in Hz. ++ ++*/ ++int ++mt2266_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner bandwidth in Hz. ++ Status = MT2266_SetParam(DeviceHandle, MT2266_OUTPUT_BW, BandwidthHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthHz = BandwidthHz; ++ pExtra->IsBandwidthHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2266 tuner bandwidth in Hz. ++ ++*/ ++int ++mt2266_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ ++ // Get tuner bandwidth in Hz from tuner module. ++ if(pExtra->IsBandwidthHzSet != YES) ++ goto error_status_get_tuner_bandwidth; ++ ++ *pBandwidthHz = pExtra->BandwidthHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.c ++** ++** Description: User-defined MicroTuner software interface ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.c,v 1.2 2006/10/26 16:39:18 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt_userdef.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++//#include "mt_userdef.h" ++ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++// UData_t status = MT_OK; /* Status to be returned */ ++ /* ++ ** ToDo: Add code here to implement a serial-bus write ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i, j; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pWritingBytes; ++ unsigned long ByteNum; ++ ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pWritingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set tuner register bytes with writing bytes. ++ // Note: Set tuner register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + ++ // stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to implement a serial-bus read ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pReadingBytes; ++ unsigned long ByteNum; ++ ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pReadingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get tuner register bytes. ++ // Note: Get tuner register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register bytes. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2266_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime) ++{ ++ /* ++ ** ToDo: Add code here to implement a OS blocking ++ ** for a period of "nMinDelayTime" milliseconds. ++ */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get tuner module, base interface. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ // Wait nMinDelayTime milliseconds. ++ pBaseInterface->WaitMs(pBaseInterface, nMinDelayTime); ++ ++ ++ return; ++} ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to return the gain / power level measured ++ ** at the input to the demodulator. ++ */ ++ ++ ++ ++ return (status); ++} ++#endif ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt2266.c ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt2266.c ++** ++** Copyright 2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2266.c ++** ++** Description: Microtune MT2266 Tuner software interface. ++** Supports tuners with Part/Rev code: 0x85. ++** ++** Functions ++** Implemented: UData_t MT2266_Open ++** UData_t MT2266_Close ++** UData_t MT2266_ChangeFreq ++** UData_t MT2266_GetLocked ++** UData_t MT2266_GetParam ++** UData_t MT2266_GetReg ++** UData_t MT2266_GetUHFXFreqs ++** UData_t MT2266_GetUserData ++** UData_t MT2266_ReInit ++** UData_t MT2266_SetParam ++** UData_t MT2266_SetPowerModes ++** UData_t MT2266_SetReg ++** UData_t MT2266_SetUHFXFreqs ++** ++** References: AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for x milliseconds ++** ++** CVS ID: $Id: mt2266.c,v 1.5 2007/10/02 18:43:17 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt2266.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 06-08-2006 JWS Ver 1.01: Corrected problem with tuner ID check ++** N/A 11-01-2006 RSK Ver 1.02: Adding multiple-filter support ++** as well as Get/Set functions. ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification for gcc ++** N/A 12-20-2006 RSK Ver 1.04: Adding fLO_FractionalTerm() usage. ++** 118 05-09-2007 RSK Ver 1.05: Adding Standard MTxxxx_Tune() API. ++** ++*****************************************************************************/ ++//#include "mt2266.h" ++//#include /* for NULL */ ++#define MT_NULL 0 ++ ++/* Version of this module */ ++#define VERSION 10005 /* Version 01.05 */ ++ ++ ++#ifndef MT2266_CNT ++#error You must define MT2266_CNT in the "mt_userdef.h" file ++#endif ++ ++/* ++** Normally, the "reg" array in the tuner structure is used as a cache ++** containing the current value of the tuner registers. If the user's ++** application MUST change tuner registers without using the MT2266_SetReg ++** routine provided, he may compile this code with the __NO_CACHE__ ++** variable defined. ++** The PREFETCH macro will insert code code to re-read tuner registers if ++** __NO_CACHE__ is defined. If it is not defined (normal) then PREFETCH ++** does nothing. ++*/ ++ ++#if defined(__NO_CACHE__) ++#define PREFETCH(var, cnt) \ ++ if (MT_NO_ERROR(status)) \ ++ status |= MT2266_ReadSub(pInfo->hUserData, pInfo->address, (var), &pInfo->reg[(var)], (cnt)); ++#else ++#define PREFETCH(var, cnt) ++#endif ++ ++ ++ ++/* ++** Two-wire serial bus subaddresses of the tuner registers. ++** Also known as the tuner's register addresses. ++*/ ++static enum MT2266_Register_Offsets ++{ ++ MT2266_PART_REV = 0, /* 0x00 */ ++ MT2266_LO_CTRL_1, /* 0x01 */ ++ MT2266_LO_CTRL_2, /* 0x02 */ ++ MT2266_LO_CTRL_3, /* 0x03 */ ++ MT2266_SMART_ANT, /* 0x04 */ ++ MT2266_BAND_CTRL, /* 0x05 */ ++ MT2266_CLEARTUNE, /* 0x06 */ ++ MT2266_IGAIN, /* 0x07 */ ++ MT2266_BBFILT_1, /* 0x08 */ ++ MT2266_BBFILT_2, /* 0x09 */ ++ MT2266_BBFILT_3, /* 0x0A */ ++ MT2266_BBFILT_4, /* 0x0B */ ++ MT2266_BBFILT_5, /* 0x0C */ ++ MT2266_BBFILT_6, /* 0x0D */ ++ MT2266_BBFILT_7, /* 0x0E */ ++ MT2266_BBFILT_8, /* 0x0F */ ++ MT2266_RCC_CTRL, /* 0x10 */ ++ MT2266_RSVD_11, /* 0x11 */ ++ MT2266_STATUS_1, /* 0x12 */ ++ MT2266_STATUS_2, /* 0x13 */ ++ MT2266_STATUS_3, /* 0x14 */ ++ MT2266_STATUS_4, /* 0x15 */ ++ MT2266_STATUS_5, /* 0x16 */ ++ MT2266_SRO_CTRL, /* 0x17 */ ++ MT2266_RSVD_18, /* 0x18 */ ++ MT2266_RSVD_19, /* 0x19 */ ++ MT2266_RSVD_1A, /* 0x1A */ ++ MT2266_RSVD_1B, /* 0x1B */ ++ MT2266_ENABLES, /* 0x1C */ ++ MT2266_RSVD_1D, /* 0x1D */ ++ MT2266_RSVD_1E, /* 0x1E */ ++ MT2266_RSVD_1F, /* 0x1F */ ++ MT2266_GPO, /* 0x20 */ ++ MT2266_RSVD_21, /* 0x21 */ ++ MT2266_RSVD_22, /* 0x22 */ ++ MT2266_RSVD_23, /* 0x23 */ ++ MT2266_RSVD_24, /* 0x24 */ ++ MT2266_RSVD_25, /* 0x25 */ ++ MT2266_RSVD_26, /* 0x26 */ ++ MT2266_RSVD_27, /* 0x27 */ ++ MT2266_RSVD_28, /* 0x28 */ ++ MT2266_RSVD_29, /* 0x29 */ ++ MT2266_RSVD_2A, /* 0x2A */ ++ MT2266_RSVD_2B, /* 0x2B */ ++ MT2266_RSVD_2C, /* 0x2C */ ++ MT2266_RSVD_2D, /* 0x2D */ ++ MT2266_RSVD_2E, /* 0x2E */ ++ MT2266_RSVD_2F, /* 0x2F */ ++ MT2266_RSVD_30, /* 0x30 */ ++ MT2266_RSVD_31, /* 0x31 */ ++ MT2266_RSVD_32, /* 0x32 */ ++ MT2266_RSVD_33, /* 0x33 */ ++ MT2266_RSVD_34, /* 0x34 */ ++ MT2266_RSVD_35, /* 0x35 */ ++ MT2266_RSVD_36, /* 0x36 */ ++ MT2266_RSVD_37, /* 0x37 */ ++ MT2266_RSVD_38, /* 0x38 */ ++ MT2266_RSVD_39, /* 0x39 */ ++ MT2266_RSVD_3A, /* 0x3A */ ++ MT2266_RSVD_3B, /* 0x3B */ ++ MT2266_RSVD_3C, /* 0x3C */ ++ END_REGS ++}; ++ ++/* ++** DefaultsEntry points to an array of U8Data used to initialize ++** various registers (the first byte is the starting subaddress) ++** and a count of the bytes (including subaddress) in the array. ++** ++** DefaultsList is an array of DefaultsEntry elements terminated ++** by an entry with a NULL pointer for the data array. ++*/ ++typedef struct MT2266_DefaultsEntryTag ++{ ++ U8Data *data; ++ UData_t cnt; ++} MT2266_DefaultsEntry; ++ ++typedef MT2266_DefaultsEntry MT2266_DefaultsList[]; ++ ++#define DEF_LIST_ENTRY(a) {a, sizeof(a)/sizeof(U8Data) - 1} ++#define END_DEF_LIST {0,0} ++ ++/* ++** Constants used by the tuning algorithm ++*/ ++ /* REF_FREQ is now the actual crystal frequency */ ++#define REF_FREQ (30000000UL) /* Reference oscillator Frequency (in Hz) */ ++#define TUNE_STEP_SIZE (50UL) /* Tune in steps of 50 kHz */ ++#define MIN_UHF_FREQ (350000000UL) /* Minimum UHF frequency (in Hz) */ ++#define MAX_UHF_FREQ (900000000UL) /* Maximum UHF frequency (in Hz) */ ++#define MIN_VHF_FREQ (174000000UL) /* Minimum VHF frequency (in Hz) */ ++#define MAX_VHF_FREQ (230000000UL) /* Maximum VHF frequency (in Hz) */ ++#define OUTPUT_BW (8000000UL) /* Output channel bandwidth (in Hz) */ ++#define UHF_DEFAULT_FREQ (600000000UL) /* Default UHF input frequency (in Hz) */ ++ ++ ++/* ++** The number of Tuner Registers ++*/ ++static const UData_t Num_Registers = END_REGS; ++ ++/* ++** Crossover Frequency sets for 2 filters, without and with attenuation. ++*/ ++typedef struct ++{ ++ MT2266_XFreq_Set xfreq[ MT2266_NUMBER_OF_XFREQ_SETS ]; ++ ++} MT2266_XFreqs_t; ++ ++ ++MT2266_XFreqs_t MT2266_default_XFreqs = ++{ ++ /* xfreq */ ++ { ++ /* uhf0 */ ++ { /* < 0 MHz: 15+1 */ ++ 0UL, /* 0 .. 0 MHz: 15 */ ++ 0UL, /* 0 .. 443 MHz: 14 */ ++ 443000 / TUNE_STEP_SIZE, /* 443 .. 470 MHz: 13 */ ++ 470000 / TUNE_STEP_SIZE, /* 470 .. 496 MHz: 12 */ ++ 496000 / TUNE_STEP_SIZE, /* 496 .. 525 MHz: 11 */ ++ 525000 / TUNE_STEP_SIZE, /* 525 .. 552 MHz: 10 */ ++ 552000 / TUNE_STEP_SIZE, /* 552 .. 580 MHz: 9 */ ++ 580000 / TUNE_STEP_SIZE, /* 580 .. 657 MHz: 8 */ ++ 657000 / TUNE_STEP_SIZE, /* 657 .. 682 MHz: 7 */ ++ 682000 / TUNE_STEP_SIZE, /* 682 .. 710 MHz: 6 */ ++ 710000 / TUNE_STEP_SIZE, /* 710 .. 735 MHz: 5 */ ++ 735000 / TUNE_STEP_SIZE, /* 735 .. 763 MHz: 4 */ ++ 763000 / TUNE_STEP_SIZE, /* 763 .. 802 MHz: 3 */ ++ 802000 / TUNE_STEP_SIZE, /* 802 .. 840 MHz: 2 */ ++ 840000 / TUNE_STEP_SIZE, /* 840 .. 877 MHz: 1 */ ++ 877000 / TUNE_STEP_SIZE /* 877+ MHz: 0 */ ++ }, ++ ++ /* uhf1 */ ++ { /* < 443 MHz: 15+1 */ ++ 443000 / TUNE_STEP_SIZE, /* 443 .. 470 MHz: 15 */ ++ 470000 / TUNE_STEP_SIZE, /* 470 .. 496 MHz: 14 */ ++ 496000 / TUNE_STEP_SIZE, /* 496 .. 525 MHz: 13 */ ++ 525000 / TUNE_STEP_SIZE, /* 525 .. 552 MHz: 12 */ ++ 552000 / TUNE_STEP_SIZE, /* 552 .. 580 MHz: 11 */ ++ 580000 / TUNE_STEP_SIZE, /* 580 .. 605 MHz: 10 */ ++ 605000 / TUNE_STEP_SIZE, /* 605 .. 632 MHz: 9 */ ++ 632000 / TUNE_STEP_SIZE, /* 632 .. 657 MHz: 8 */ ++ 657000 / TUNE_STEP_SIZE, /* 657 .. 682 MHz: 7 */ ++ 682000 / TUNE_STEP_SIZE, /* 682 .. 710 MHz: 6 */ ++ 710000 / TUNE_STEP_SIZE, /* 710 .. 735 MHz: 5 */ ++ 735000 / TUNE_STEP_SIZE, /* 735 .. 763 MHz: 4 */ ++ 763000 / TUNE_STEP_SIZE, /* 763 .. 802 MHz: 3 */ ++ 802000 / TUNE_STEP_SIZE, /* 802 .. 840 MHz: 2 */ ++ 840000 / TUNE_STEP_SIZE, /* 840 .. 877 MHz: 1 */ ++ 877000 / TUNE_STEP_SIZE /* 877+ MHz: 0 */ ++ }, ++ ++ /* uhf0_a */ ++ { /* < 0 MHz: 15+1 */ ++ 0UL, /* 0 .. 0 MHz: 15 */ ++ 0UL, /* 0 .. 442 MHz: 14 */ ++ 442000 / TUNE_STEP_SIZE, /* 442 .. 472 MHz: 13 */ ++ 472000 / TUNE_STEP_SIZE, /* 472 .. 505 MHz: 12 */ ++ 505000 / TUNE_STEP_SIZE, /* 505 .. 535 MHz: 11 */ ++ 535000 / TUNE_STEP_SIZE, /* 535 .. 560 MHz: 10 */ ++ 560000 / TUNE_STEP_SIZE, /* 560 .. 593 MHz: 9 */ ++ 593000 / TUNE_STEP_SIZE, /* 593 .. 673 MHz: 8 */ ++ 673000 / TUNE_STEP_SIZE, /* 673 .. 700 MHz: 7 */ ++ 700000 / TUNE_STEP_SIZE, /* 700 .. 727 MHz: 6 */ ++ 727000 / TUNE_STEP_SIZE, /* 727 .. 752 MHz: 5 */ ++ 752000 / TUNE_STEP_SIZE, /* 752 .. 783 MHz: 4 */ ++ 783000 / TUNE_STEP_SIZE, /* 783 .. 825 MHz: 3 */ ++ 825000 / TUNE_STEP_SIZE, /* 825 .. 865 MHz: 2 */ ++ 865000 / TUNE_STEP_SIZE, /* 865 .. 905 MHz: 1 */ ++ 905000 / TUNE_STEP_SIZE /* 905+ MHz: 0 */ ++ }, ++ ++ /* uhf1_a */ ++ { /* < 442 MHz: 15+1 */ ++ 442000 / TUNE_STEP_SIZE, /* 442 .. 472 MHz: 15 */ ++ 472000 / TUNE_STEP_SIZE, /* 472 .. 505 MHz: 14 */ ++ 505000 / TUNE_STEP_SIZE, /* 505 .. 535 MHz: 13 */ ++ 535000 / TUNE_STEP_SIZE, /* 535 .. 560 MHz: 12 */ ++ 560000 / TUNE_STEP_SIZE, /* 560 .. 593 MHz: 11 */ ++ 593000 / TUNE_STEP_SIZE, /* 593 .. 620 MHz: 10 */ ++ 620000 / TUNE_STEP_SIZE, /* 620 .. 647 MHz: 9 */ ++ 647000 / TUNE_STEP_SIZE, /* 647 .. 673 MHz: 8 */ ++ 673000 / TUNE_STEP_SIZE, /* 673 .. 700 MHz: 7 */ ++ 700000 / TUNE_STEP_SIZE, /* 700 .. 727 MHz: 6 */ ++ 727000 / TUNE_STEP_SIZE, /* 727 .. 752 MHz: 5 */ ++ 752000 / TUNE_STEP_SIZE, /* 752 .. 783 MHz: 4 */ ++ 783000 / TUNE_STEP_SIZE, /* 783 .. 825 MHz: 3 */ ++ 825000 / TUNE_STEP_SIZE, /* 825 .. 865 MHz: 2 */ ++ 865000 / TUNE_STEP_SIZE, /* 865 .. 905 MHz: 1 */ ++ 905000 / TUNE_STEP_SIZE /* 905+ MHz: 0 */ ++ } ++ } ++}; ++ ++typedef struct ++{ ++ Handle_t handle; ++ Handle_t hUserData; ++ UData_t address; ++ UData_t version; ++ UData_t tuner_id; ++ UData_t f_Ref; ++ UData_t f_Step; ++ UData_t f_in; ++ UData_t f_LO; ++ UData_t f_bw; ++ UData_t band; ++ UData_t num_regs; ++ U8Data RC2_Value; ++ U8Data RC2_Nominal; ++ U8Data reg[END_REGS]; ++ ++ MT2266_XFreqs_t xfreqs; ++ ++} MT2266_Info_t; ++ ++static UData_t nMaxTuners = MT2266_CNT; ++static MT2266_Info_t MT2266_Info[MT2266_CNT]; ++static MT2266_Info_t *Avail[MT2266_CNT]; ++static UData_t nOpenTuners = 0; ++ ++/* ++** Constants used to write a minimal set of registers when changing bands. ++** If the user wants a total reset, they should call MT2266_Open() again. ++** Skip 01, 02, 03, 04 (get overwritten anyways) ++** Write 05 ++** Skip 06 - 18 ++** Write 19 (diff for L-Band) ++** Skip 1A 1B 1C ++** Write 1D - 2B ++** Skip 2C - 3C ++*/ ++ ++static U8Data MT2266_VHF_defaults1[] = ++{ ++ 0x05, /* address 0xC0, reg 0x05 */ ++ 0x04, /* Reg 0x05 LBANDen = 1 (that's right)*/ ++}; ++static U8Data MT2266_VHF_defaults2[] = ++{ ++ 0x19, /* address 0xC0, reg 0x19 */ ++ 0x61, /* Reg 0x19 CAPto = 3*/ ++}; ++static U8Data MT2266_VHF_defaults3[] = ++{ ++ 0x1D, /* address 0xC0, reg 0x1D */ ++ 0xFE, /* reg 0x1D */ ++ 0x00, /* reg 0x1E */ ++ 0x00, /* reg 0x1F */ ++ 0xB4, /* Reg 0x20 GPO = 1*/ ++ 0x03, /* Reg 0x21 LBIASen = 1, UBIASen = 1*/ ++ 0xA5, /* Reg 0x22 */ ++ 0xA5, /* Reg 0x23 */ ++ 0xA5, /* Reg 0x24 */ ++ 0xA5, /* Reg 0x25 */ ++ 0x82, /* Reg 0x26 CASCM = b0001 (bits reversed)*/ ++ 0xAA, /* Reg 0x27 */ ++ 0xF1, /* Reg 0x28 */ ++ 0x17, /* Reg 0x29 */ ++ 0x80, /* Reg 0x2A MIXbiasen = 1*/ ++ 0x1F, /* Reg 0x2B */ ++}; ++ ++static MT2266_DefaultsList MT2266_VHF_defaults = { ++ DEF_LIST_ENTRY(MT2266_VHF_defaults1), ++ DEF_LIST_ENTRY(MT2266_VHF_defaults2), ++ DEF_LIST_ENTRY(MT2266_VHF_defaults3), ++ END_DEF_LIST ++}; ++ ++static U8Data MT2266_UHF_defaults1[] = ++{ ++ 0x05, /* address 0xC0, reg 0x05 */ ++ 0x52, /* Reg 0x05 */ ++}; ++static U8Data MT2266_UHF_defaults2[] = ++{ ++ 0x19, /* address 0xC0, reg 0x19 */ ++ 0x61, /* Reg 0x19 CAPto = 3*/ ++}; ++static U8Data MT2266_UHF_defaults3[] = ++{ ++ 0x1D, /* address 0xC0, reg 0x1D */ ++ 0xDC, /* Reg 0x1D */ ++ 0x00, /* Reg 0x1E */ ++ 0x0A, /* Reg 0x1F */ ++ 0xD4, /* Reg 0x20 GPO = 1*/ ++ 0x03, /* Reg 0x21 LBIASen = 1, UBIASen = 1*/ ++ 0x64, /* Reg 0x22 */ ++ 0x64, /* Reg 0x23 */ ++ 0x64, /* Reg 0x24 */ ++ 0x64, /* Reg 0x25 */ ++ 0x22, /* Reg 0x26 CASCM = b0100 (bits reversed)*/ ++ 0xAA, /* Reg 0x27 */ ++ 0xF2, /* Reg 0x28 */ ++ 0x1E, /* Reg 0x29 */ ++ 0x80, /* Reg 0x2A MIXbiasen = 1*/ ++ 0x14, /* Reg 0x2B */ ++}; ++ ++static MT2266_DefaultsList MT2266_UHF_defaults = { ++ DEF_LIST_ENTRY(MT2266_UHF_defaults1), ++ DEF_LIST_ENTRY(MT2266_UHF_defaults2), ++ DEF_LIST_ENTRY(MT2266_UHF_defaults3), ++ END_DEF_LIST ++}; ++ ++ ++static UData_t UncheckedSet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data val); ++ ++static UData_t UncheckedGet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data* val); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: MT2266_Addr - Serial bus address of the tuner. ++** hMT2266 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_COMM_ERR - Serial bus communications error ++** MT_ARG_NULL - Null pointer argument passed ++** MT_TUNER_CNT_ERR - Too many tuners open ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Initialize Crossover Tables to Default ++** ++******************************************************************************/ ++UData_t MT2266_Open(UData_t MT2266_Addr, ++ Handle_t* hMT2266, ++ Handle_t hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned. */ ++ SData_t i, j; ++ MT2266_Info_t* pInfo = MT_NULL; ++ ++ /* Check the argument before using */ ++ if (hMT2266 == MT_NULL) ++ return MT_ARG_NULL; ++ *hMT2266 = MT_NULL; ++ ++ /* ++ ** If this is our first tuner, initialize the address fields and ++ ** the list of available control blocks. ++ */ ++ if (nOpenTuners == 0) ++ { ++ for (i=MT2266_CNT-1; i>=0; i--) ++ { ++ MT2266_Info[i].handle = MT_NULL; ++ MT2266_Info[i].address = MAX_UDATA; ++ MT2266_Info[i].hUserData = MT_NULL; ++ ++ /* Reset the UHF Crossover Frequency tables on open/init. */ ++ for (j=0; j< MT2266_NUM_XFREQS; j++ ) ++ { ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF0][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0][j]; ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF1][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1][j]; ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF0_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0_ATTEN][j]; ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF1_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1_ATTEN][j]; ++ } ++ ++ Avail[i] = &MT2266_Info[i]; ++ } ++ } ++ ++ /* ++ ** Look for an existing MT2266_State_t entry with this address. ++ */ ++ for (i=MT2266_CNT-1; i>=0; i--) ++ { ++ /* ++ ** If an open'ed handle provided, we'll re-initialize that structure. ++ ** ++ ** We recognize an open tuner because the address and hUserData are ++ ** the same as one that has already been opened ++ */ ++ if ((MT2266_Info[i].address == MT2266_Addr) && ++ (MT2266_Info[i].hUserData == hUserData)) ++ { ++ pInfo = &MT2266_Info[i]; ++ break; ++ } ++ } ++ ++ /* If not found, choose an empty spot. */ ++ if (pInfo == MT_NULL) ++ { ++ /* Check to see that we're not over-allocating. */ ++ if (nOpenTuners == MT2266_CNT) ++ return MT_TUNER_CNT_ERR; ++ ++ /* Use the next available block from the list */ ++ pInfo = Avail[nOpenTuners]; ++ nOpenTuners++; ++ } ++ ++ pInfo->handle = (Handle_t) pInfo; ++ pInfo->hUserData = hUserData; ++ pInfo->address = MT2266_Addr; ++ ++// status |= MT2266_ReInit((Handle_t) pInfo); ++ ++ if (MT_IS_ERROR(status)) ++ MT2266_Close((Handle_t) pInfo); ++ else ++ *hMT2266 = pInfo->handle; ++ ++ return (status); ++} ++ ++ ++static UData_t IsValidHandle(MT2266_Info_t* handle) ++{ ++ return ((handle != MT_NULL) && (handle->handle == handle)) ? 1 : 0; ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++******************************************************************************/ ++UData_t MT2266_Close(Handle_t hMT2266) ++{ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) hMT2266; ++ ++ if (!IsValidHandle(pInfo)) ++ return MT_INV_HANDLE; ++ ++ /* Remove the tuner from our list of tuners */ ++ pInfo->handle = MT_NULL; ++ pInfo->address = MAX_UDATA; ++ pInfo->hUserData = MT_NULL; ++ nOpenTuners--; ++ Avail[nOpenTuners] = pInfo; /* Return control block to available list */ ++ ++ return MT_OK; ++} ++ ++ ++/****************************************************************************** ++** ++** Name: Run_BB_RC_Cal2 ++** ++** Description: Run Base Band RC Calibration (Method 2) ++** MT2266 B0 only, others return MT_OK ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++******************************************************************************/ ++static UData_t Run_BB_RC_Cal2(Handle_t h) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data tmp_rcc; ++ U8Data dumy; ++ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* ++ ** Set the crystal frequency in the calibration register ++ ** and enable RC calibration #2 ++ */ ++ PREFETCH(MT2266_RCC_CTRL, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ tmp_rcc = pInfo->reg[MT2266_RCC_CTRL]; ++ if (pInfo->f_Ref < (36000000 /*/ TUNE_STEP_SIZE*/)) ++ tmp_rcc = (tmp_rcc & 0xDF) | 0x10; ++ else ++ tmp_rcc |= 0x30; ++ status |= UncheckedSet(pInfo, MT2266_RCC_CTRL, tmp_rcc); ++ ++ /* Read RC Calibration value */ ++ status |= UncheckedGet(pInfo, MT2266_STATUS_4, &dumy); ++ ++ /* Disable RC Cal 2 */ ++ status |= UncheckedSet(pInfo, MT2266_RCC_CTRL, pInfo->reg[MT2266_RCC_CTRL] & 0xEF); ++ ++ /* Store RC Cal 2 value */ ++ pInfo->RC2_Value = pInfo->reg[MT2266_STATUS_4]; ++ ++ if (pInfo->f_Ref < (36000000 /*/ TUNE_STEP_SIZE*/)) ++ pInfo->RC2_Nominal = (U8Data) ((pInfo->f_Ref + 77570) / 155139); ++ else ++ pInfo->RC2_Nominal = (U8Data) ((pInfo->f_Ref + 93077) / 186154); ++ ++ return (status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: Set_BBFilt ++** ++** Description: Set Base Band Filter bandwidth ++** Based on SRO frequency & BB RC Calibration ++** User stores channel bw as 5-8 MHz. This routine ++** calculates a 3 dB corner bw based on 1/2 the bandwidth ++** and a bandwidth related constant. ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++******************************************************************************/ ++static UData_t Set_BBFilt(Handle_t h) ++{ ++ UData_t f_3dB_bw; ++ U8Data BBFilt = 0; ++ U8Data Sel = 0; ++ SData_t TmpFilt; ++ SData_t i; ++ UData_t status = MT_OK; /* Status to be returned */ ++ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* Check RC2_Value value */ ++ if(pInfo->RC2_Value == 0) ++ return MT_UNKNOWN; ++ ++ /* ++ ** Convert the channel bandwidth into a 3 dB bw by dividing it by 2 ++ ** and subtracting 300, 250, 200, or 0 kHz based on 8, 7, 6, 5 MHz ++ ** channel bandwidth. ++ */ ++ f_3dB_bw = (pInfo->f_bw / 2); /* bw -> bw/2 */ ++ if (pInfo->f_bw > 7500000) ++ { ++ /* >3.75 MHz corner */ ++ f_3dB_bw -= 300000; ++ Sel = 0x00; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 81; ++ } ++ else if (pInfo->f_bw > 6500000) ++ { ++ /* >3.25 MHz .. 3.75 MHz corner */ ++ f_3dB_bw -= 250000; ++ Sel = 0x00; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 81; ++ } ++ else if (pInfo->f_bw > 5500000) ++ { ++ /* >2.75 MHz .. 3.25 MHz corner */ ++ f_3dB_bw -= 200000; ++ Sel = 0x80; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 113; ++ } ++ else ++ { ++ /* <= 2.75 MHz corner */ ++ Sel = 0xC0; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 129; ++ } ++ ++ if (TmpFilt > 63) ++ TmpFilt = 63; ++ else if (TmpFilt < 0) ++ TmpFilt = 0; ++ BBFilt = ((U8Data) TmpFilt) | Sel; ++ ++ for ( i = MT2266_BBFILT_1; i <= MT2266_BBFILT_8; i++ ) ++ pInfo->reg[i] = BBFilt; ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_BBFILT_1, ++ &pInfo->reg[MT2266_BBFILT_1], ++ 8); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetLocked ++** ++** Description: Checks to see if the PLL is locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetLocked(Handle_t h) ++{ ++ const UData_t nMaxWait = 200; /* wait a maximum of 200 msec */ ++ const UData_t nPollRate = 2; /* poll status bits every 2 ms */ ++ const UData_t nMaxLoops = nMaxWait / nPollRate; ++ UData_t status = MT_OK; /* Status to be returned */ ++ UData_t nDelays = 0; ++ U8Data statreg; ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return MT_INV_HANDLE; ++ ++ do ++ { ++ status |= UncheckedGet(pInfo, MT2266_STATUS_1, &statreg); ++ ++ if ((MT_IS_ERROR(status)) || ((statreg & 0x40) == 0x40)) ++ return (status); ++ ++ MT2266_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */ ++ } ++ while (++nDelays < nMaxLoops); ++ ++ if ((statreg & 0x40) != 0x40) ++ status |= MT_DNC_UNLOCK; ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_IC_ADDR Serial Bus address of this tuner ++** MT2266_MAX_OPEN Max number of MT2266's that can be open ++** MT2266_NUM_OPEN Number of MT2266's currently open ++** MT2266_NUM_REGS Number of tuner registers ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ input center frequency ++** MT2266_LO_FREQ LO Frequency ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RC2_VALUE Base band filter cal RC code (method 2) ++** MT2266_RC2_NOMINAL Base band filter nominal cal RC code ++** MT2266_RF_ADC RF attenuator A/D readback ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_BB_ADC BB attenuator A/D readback ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** ++** Usage: status |= MT2266_GetParam(hMT2266, ++** MT2266_OUTPUT_BW, ++** &f_bw); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t* pValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data tmp; ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ if (pValue == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ switch (param) ++ { ++ /* Serial Bus address of this tuner */ ++ case MT2266_IC_ADDR: ++ *pValue = pInfo->address; ++ break; ++ ++ /* Max # of MT2266's allowed to be open */ ++ case MT2266_MAX_OPEN: ++ *pValue = nMaxTuners; ++ break; ++ ++ /* # of MT2266's open */ ++ case MT2266_NUM_OPEN: ++ *pValue = nOpenTuners; ++ break; ++ ++ /* Number of tuner registers */ ++ case MT2266_NUM_REGS: ++ *pValue = Num_Registers; ++ break; ++ ++ /* crystal frequency */ ++ case MT2266_SRO_FREQ: ++ *pValue = pInfo->f_Ref; ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2266_STEPSIZE: ++ *pValue = pInfo->f_Step; ++ break; ++ ++ /* input center frequency */ ++ case MT2266_INPUT_FREQ: ++ *pValue = pInfo->f_in; ++ break; ++ ++ /* LO Frequency */ ++ case MT2266_LO_FREQ: ++ *pValue = pInfo->f_LO; ++ break; ++ ++ /* Output Channel Bandwidth */ ++ case MT2266_OUTPUT_BW: ++ *pValue = pInfo->f_bw; ++ break; ++ ++ /* Base band filter cal RC code */ ++ case MT2266_RC2_VALUE: ++ *pValue = (UData_t) pInfo->RC2_Value; ++ break; ++ ++ /* Base band filter nominal cal RC code */ ++ case MT2266_RC2_NOMINAL: ++ *pValue = (UData_t) pInfo->RC2_Nominal; ++ break; ++ ++ /* RF attenuator A/D readback */ ++ case MT2266_RF_ADC: ++ status |= UncheckedGet(pInfo, MT2266_STATUS_2, &tmp); ++ if (MT_NO_ERROR(status)) ++ *pValue = (UData_t) tmp; ++ break; ++ ++ /* BB attenuator A/D readback */ ++ case MT2266_BB_ADC: ++ status |= UncheckedGet(pInfo, MT2266_STATUS_3, &tmp); ++ if (MT_NO_ERROR(status)) ++ *pValue = (UData_t) tmp; ++ break; ++ ++ /* RF attenuator setting */ ++ case MT2266_RF_ATTN: ++ PREFETCH(MT2266_RSVD_1F, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ if (MT_NO_ERROR(status)) ++ *pValue = pInfo->reg[MT2266_RSVD_1F]; ++ break; ++ ++ /* BB attenuator setting */ ++ case MT2266_BB_ATTN: ++ PREFETCH(MT2266_RSVD_2C, 3); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = pInfo->reg[MT2266_RSVD_2C] ++ + pInfo->reg[MT2266_RSVD_2D] ++ + pInfo->reg[MT2266_RSVD_2E] - 3; ++ break; ++ ++ /* RF external / internal atten control */ ++ case MT2266_RF_EXT: ++ PREFETCH(MT2266_GPO, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = ((pInfo->reg[MT2266_GPO] & 0x40) != 0x00); ++ break; ++ ++ /* BB external / internal atten control */ ++ case MT2266_BB_EXT: ++ PREFETCH(MT2266_RSVD_33, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = ((pInfo->reg[MT2266_RSVD_33] & 0x10) != 0x00); ++ break; ++ ++ /* LNA gain setting (0-15) */ ++ case MT2266_LNA_GAIN: ++ PREFETCH(MT2266_IGAIN, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2); ++ break; ++ ++ case MT2266_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION - DO NOT USE OUTSIDE OF mt2266.c ++** ++** Name: UncheckedGet ++** ++** Description: Gets an MT2266 register with minimal checking ++** ++** NOTE: This is a local function that performs the same ++** steps as the MT2266_GetReg function that is available ++** in the external API. It does not do any of the standard ++** error checking that the API function provides and should ++** not be called from outside this file. ++** ++** Parameters: *pInfo - Tuner control structure ++** reg - MT2266 register/subaddress location ++** *val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2266. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++static UData_t UncheckedGet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data* val) ++{ ++ UData_t status; /* Status to be returned */ ++ ++#if defined(_DEBUG) ++ status = MT_OK; ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (val == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_IS_ERROR(status)) ++ return(status); ++#endif ++ ++ status = MT2266_ReadSub(pInfo->hUserData, pInfo->address, reg, &pInfo->reg[reg], 1); ++ ++ if (MT_NO_ERROR(status)) ++ *val = pInfo->reg[reg]; ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetReg ++** ++** Description: Gets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** *val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2266. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (val == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedGet(pInfo, reg, val); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUHFXFreqs ++** ++** Description: Retrieves the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_GetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 10-26-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ ++ if (freq_type >= MT2266_NUMBER_OF_XFREQ_SETS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ int i; ++ ++ for( i = 0; i < MT2266_NUM_XFREQS; i++ ) ++ { ++ freqs_buffer[i] = pInfo->xfreqs.xfreq[ freq_type ][i] * TUNE_STEP_SIZE / 1000; ++ } ++ } ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2266_SetUserData, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetUserData(Handle_t h, ++ Handle_t* hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ ++ if (hUserData == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (MT_NO_ERROR(status)) ++ *hUserData = pInfo->hUserData; ++ ++ return (status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 06-08-2006 JWS Ver 1.01: Corrected problem with tuner ID check ++** N/A 11-01-2006 RSK Ver 1.02: Initialize XFreq Tables to Default ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification ++** ++******************************************************************************/ ++UData_t MT2266_ReInit(Handle_t h) ++{ ++ int j; ++ ++ U8Data MT2266_Init_Defaults1[] = ++ { ++ 0x01, /* Start w/register 0x01 */ ++ 0x00, /* Reg 0x01 */ ++ 0x00, /* Reg 0x02 */ ++ 0x28, /* Reg 0x03 */ ++ 0x00, /* Reg 0x04 */ ++ 0x52, /* Reg 0x05 */ ++ 0x99, /* Reg 0x06 */ ++ 0x3F, /* Reg 0x07 */ ++ }; ++ ++ U8Data MT2266_Init_Defaults2[] = ++ { ++ 0x17, /* Start w/register 0x17 */ ++ 0x6D, /* Reg 0x17 */ ++ 0x71, /* Reg 0x18 */ ++ 0x61, /* Reg 0x19 */ ++ 0xC0, /* Reg 0x1A */ ++ 0xBF, /* Reg 0x1B */ ++ 0xFF, /* Reg 0x1C */ ++ 0xDC, /* Reg 0x1D */ ++ 0x00, /* Reg 0x1E */ ++ 0x0A, /* Reg 0x1F */ ++ 0xD4, /* Reg 0x20 */ ++ 0x03, /* Reg 0x21 */ ++ 0x64, /* Reg 0x22 */ ++ 0x64, /* Reg 0x23 */ ++ 0x64, /* Reg 0x24 */ ++ 0x64, /* Reg 0x25 */ ++ 0x22, /* Reg 0x26 */ ++ 0xAA, /* Reg 0x27 */ ++ 0xF2, /* Reg 0x28 */ ++ 0x1E, /* Reg 0x29 */ ++ 0x80, /* Reg 0x2A */ ++ 0x14, /* Reg 0x2B */ ++ 0x01, /* Reg 0x2C */ ++ 0x01, /* Reg 0x2D */ ++ 0x01, /* Reg 0x2E */ ++ 0x01, /* Reg 0x2F */ ++ 0x01, /* Reg 0x30 */ ++ 0x01, /* Reg 0x31 */ ++ 0x7F, /* Reg 0x32 */ ++ 0x5E, /* Reg 0x33 */ ++ 0x3F, /* Reg 0x34 */ ++ 0xFF, /* Reg 0x35 */ ++ 0xFF, /* Reg 0x36 */ ++ 0xFF, /* Reg 0x37 */ ++ 0x00, /* Reg 0x38 */ ++ 0x77, /* Reg 0x39 */ ++ 0x0F, /* Reg 0x3A */ ++ 0x2D, /* Reg 0x3B */ ++ }; ++ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ U8Data BBVref; ++ U8Data tmpreg = 0; ++ U8Data statusreg = 0; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* Read the Part/Rev code from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedGet(pInfo, MT2266_PART_REV, &tmpreg); ++ if (MT_NO_ERROR(status) && (tmpreg != 0x85)) // MT226? B0 ++ status |= MT_TUNER_ID_ERR; ++ else ++ { ++ /* ++ ** Read the status register 5 ++ */ ++ tmpreg = pInfo->reg[MT2266_RSVD_11] |= 0x03; ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedSet(pInfo, MT2266_RSVD_11, tmpreg); ++ tmpreg &= ~(0x02); ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedSet(pInfo, MT2266_RSVD_11, tmpreg); ++ ++ /* Get and store the status 5 register value */ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedGet(pInfo, MT2266_STATUS_5, &statusreg); ++ ++ /* MT2266 */ ++ if (MT_IS_ERROR(status) || ((statusreg & 0x30) != 0x30)) ++ status |= MT_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ ++ } ++ ++ if (MT_NO_ERROR(status)) ++ { ++ /* Initialize the tuner state. Hold off on f_in and f_LO */ ++ pInfo->version = VERSION; ++ pInfo->tuner_id = pInfo->reg[MT2266_PART_REV]; ++ pInfo->f_Ref = REF_FREQ; ++ pInfo->f_Step = TUNE_STEP_SIZE * 1000; /* kHz -> Hz */ ++ pInfo->f_in = UHF_DEFAULT_FREQ; ++ pInfo->f_LO = UHF_DEFAULT_FREQ; ++ pInfo->f_bw = OUTPUT_BW; ++ pInfo->band = MT2266_UHF_BAND; ++ pInfo->num_regs = END_REGS; ++ ++ /* Reset the UHF Crossover Frequency tables on open/init. */ ++ for (j=0; j< MT2266_NUM_XFREQS; j++ ) ++ { ++ pInfo->xfreqs.xfreq[MT2266_UHF0][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0][j]; ++ pInfo->xfreqs.xfreq[MT2266_UHF1][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1][j]; ++ pInfo->xfreqs.xfreq[MT2266_UHF0_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0_ATTEN][j]; ++ pInfo->xfreqs.xfreq[MT2266_UHF1_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1_ATTEN][j]; ++ } ++ ++ /* Write the default values to the tuner registers. Default mode is UHF */ ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_Init_Defaults1[0], ++ &MT2266_Init_Defaults1[1], ++ sizeof(MT2266_Init_Defaults1)/sizeof(U8Data)-1); ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_Init_Defaults2[0], ++ &MT2266_Init_Defaults2[1], ++ sizeof(MT2266_Init_Defaults2)/sizeof(U8Data)-1); ++ } ++ ++ /* Read back all the registers from the tuner */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2266_ReadSub(pInfo->hUserData, pInfo->address, 0, &pInfo->reg[0], END_REGS); ++ } ++ ++ /* ++ ** Set reg[0x33] based on statusreg ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ BBVref = (((statusreg >> 6) + 2) & 0x03); ++ tmpreg = (pInfo->reg[MT2266_RSVD_33] & ~(0x60)) | (BBVref << 5); ++ status |= UncheckedSet(pInfo, MT2266_RSVD_33, tmpreg); ++ } ++ ++ /* Run the baseband filter calibration */ ++ if (MT_NO_ERROR(status)) ++ status |= Run_BB_RC_Cal2(h); ++ ++ /* Set the baseband filter bandwidth to the default */ ++ if (MT_NO_ERROR(status)) ++ status |= Set_BBFilt(h); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ Center of input channel ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_LNA_GAIN_DECR Decrement LNA Gain (arg=min) ++** MT2266_LNA_GAIN_INCR Increment LNA Gain (arg=max) ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** MT2266_UHF_MAXSENS Set for UHF max sensitivity mode ++** MT2266_UHF_NORMAL Set for UHF normal mode ++** ++** Usage: status |= MT2266_SetParam(hMT2266, ++** MT2266_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_GetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification for gcc ++** ++****************************************************************************/ ++UData_t MT2266_SetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t nValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data tmpreg; ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ switch (param) ++ { ++ /* crystal frequency */ ++ case MT2266_SRO_FREQ: ++ pInfo->f_Ref = nValue; ++ if (pInfo->f_Ref < 22000000) ++ { ++ /* Turn off f_SRO divide by 2 */ ++ status |= UncheckedSet(pInfo, ++ MT2266_SRO_CTRL, ++ (U8Data) (pInfo->reg[MT2266_SRO_CTRL] &= 0xFE)); ++ } ++ else ++ { ++ /* Turn on f_SRO divide by 2 */ ++ status |= UncheckedSet(pInfo, ++ MT2266_SRO_CTRL, ++ (U8Data) (pInfo->reg[MT2266_SRO_CTRL] |= 0x01)); ++ } ++ status |= Run_BB_RC_Cal2(h); ++ if (MT_NO_ERROR(status)) ++ status |= Set_BBFilt(h); ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2266_STEPSIZE: ++ pInfo->f_Step = nValue; ++ break; ++ ++ /* Width of output channel */ ++ case MT2266_OUTPUT_BW: ++ pInfo->f_bw = nValue; ++ status |= Set_BBFilt(h); ++ break; ++ ++ /* BB attenuation (0-255) */ ++ case MT2266_BB_ATTN: ++ if (nValue > 255) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ UData_t BBA_Stage1; ++ UData_t BBA_Stage2; ++ UData_t BBA_Stage3; ++ ++ BBA_Stage3 = (nValue > 102) ? 103 : nValue + 1; ++ BBA_Stage2 = (nValue > 175) ? 75 : nValue + 2 - BBA_Stage3; ++ BBA_Stage1 = (nValue > 176) ? nValue - 175 : 1; ++ pInfo->reg[MT2266_RSVD_2C] = (U8Data) BBA_Stage1; ++ pInfo->reg[MT2266_RSVD_2D] = (U8Data) BBA_Stage2; ++ pInfo->reg[MT2266_RSVD_2E] = (U8Data) BBA_Stage3; ++ pInfo->reg[MT2266_RSVD_2F] = (U8Data) BBA_Stage1; ++ pInfo->reg[MT2266_RSVD_30] = (U8Data) BBA_Stage2; ++ pInfo->reg[MT2266_RSVD_31] = (U8Data) BBA_Stage3; ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_RSVD_2C, ++ &pInfo->reg[MT2266_RSVD_2C], ++ 6); ++ } ++ break; ++ ++ /* RF attenuation (0-255) */ ++ case MT2266_RF_ATTN: ++ if (nValue > 255) ++ status |= MT_ARG_RANGE; ++ else ++ status |= UncheckedSet(pInfo, MT2266_RSVD_1F, (U8Data) nValue); ++ break; ++ ++ /* RF external / internal atten control */ ++ case MT2266_RF_EXT: ++ if (nValue == 0) ++ tmpreg = pInfo->reg[MT2266_GPO] &= ~0x40; ++ else ++ tmpreg = pInfo->reg[MT2266_GPO] |= 0x40; ++ status |= UncheckedSet(pInfo, MT2266_GPO, tmpreg); ++ break; ++ ++ /* LNA gain setting (0-15) */ ++ case MT2266_LNA_GAIN: ++ if (nValue > 15) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ tmpreg = (pInfo->reg[MT2266_IGAIN] & 0xC3) | ((U8Data)nValue << 2); ++ status |= UncheckedSet(pInfo, MT2266_IGAIN, tmpreg); ++ } ++ break; ++ ++ /* Decrement LNA Gain setting, argument is min LNA Gain setting */ ++ case MT2266_LNA_GAIN_DECR: ++ if (nValue > 15) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ PREFETCH(MT2266_IGAIN, 1); ++ if (MT_NO_ERROR(status) && ((U8Data) ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2) > (U8Data) nValue)) ++ status |= UncheckedSet(pInfo, MT2266_IGAIN, pInfo->reg[MT2266_IGAIN] - 0x04); ++ } ++ break; ++ ++ /* Increment LNA Gain setting, argument is max LNA Gain setting */ ++ case MT2266_LNA_GAIN_INCR: ++ if (nValue > 15) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ PREFETCH(MT2266_IGAIN, 1); ++ if (MT_NO_ERROR(status) && ((U8Data) ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2) < (U8Data) nValue)) ++ status |= UncheckedSet(pInfo, MT2266_IGAIN, pInfo->reg[MT2266_IGAIN] + 0x04); ++ } ++ break; ++ ++ /* BB external / internal atten control */ ++ case MT2266_BB_EXT: ++ if (nValue == 0) ++ tmpreg = pInfo->reg[MT2266_RSVD_33] &= ~0x08; ++ else ++ tmpreg = pInfo->reg[MT2266_RSVD_33] |= 0x08; ++ status |= UncheckedSet(pInfo, MT2266_RSVD_33, tmpreg); ++ break; ++ ++ /* Set for UHF max sensitivity mode */ ++ case MT2266_UHF_MAXSENS: ++ PREFETCH(MT2266_BAND_CTRL, 1); ++ if (MT_NO_ERROR(status) && ((pInfo->reg[MT2266_BAND_CTRL] & 0x30) == 0x10)) ++ status |= UncheckedSet(pInfo, MT2266_BAND_CTRL, pInfo->reg[MT2266_BAND_CTRL] ^ 0x30); ++ break; ++ ++ /* Set for UHF normal mode */ ++ case MT2266_UHF_NORMAL: ++ if (MT_NO_ERROR(status) && ((pInfo->reg[MT2266_BAND_CTRL] & 0x30) == 0x20)) ++ status |= UncheckedSet(pInfo, MT2266_BAND_CTRL, pInfo->reg[MT2266_BAND_CTRL] ^ 0x30); ++ break; ++ ++ /* These parameters are read-only */ ++ case MT2266_IC_ADDR: ++ case MT2266_MAX_OPEN: ++ case MT2266_NUM_OPEN: ++ case MT2266_NUM_REGS: ++ case MT2266_INPUT_FREQ: ++ case MT2266_LO_FREQ: ++ case MT2266_RC2_VALUE: ++ case MT2266_RF_ADC: ++ case MT2266_BB_ADC: ++ case MT2266_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetPowerModes ++** ++** Description: Sets the bits in the MT2266_ENABLES register and the ++** SROsd bit in the MT2266_SROADC_CTRL register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** flags - Bit mask of flags to indicate enabled ++** bits. ++** ++** Usage: status = MT2266_SetPowerModes(hMT2266, flags); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The bits in the MT2266_ENABLES register and the ++** SROsd bit are set according to the supplied flags. ++** ++** The pre-defined flags are as follows: ++** MT2266_SROen ++** MT2266_LOen ++** MT2266_ADCen ++** MT2266_PDen ++** MT2266_DCOCen ++** MT2266_BBen ++** MT2266_MIXen ++** MT2266_LNAen ++** MT2266_ALL_ENABLES ++** MT2266_NO_ENABLES ++** MT2266_SROsd ++** MT2266_SRO_NOT_sd ++** ++** ONLY the enable bits (or SROsd bit) specified in the ++** flags parameter will be set. Any flag which is not ++** included, will cause that bit to be disabled. ++** ++** The ALL_ENABLES, NO_ENABLES, and SRO_NOT_sd constants ++** are for convenience. The NO_ENABLES and SRO_NOT_sd ++** do not actually have to be included, but are provided ++** for clarity. ++** ++** See Also: MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_SetPowerModes(Handle_t h, ++ UData_t flags) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ U8Data tmpreg; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ PREFETCH(MT2266_SRO_CTRL, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ if (MT_NO_ERROR(status)) ++ { ++ if (flags & MT2266_SROsd) ++ tmpreg = pInfo->reg[MT2266_SRO_CTRL] |= 0x10; /* set the SROsd bit */ ++ else ++ tmpreg = pInfo->reg[MT2266_SRO_CTRL] &= 0xEF; /* clear the SROsd bit */ ++ status |= UncheckedSet(pInfo, MT2266_SRO_CTRL, tmpreg); ++ } ++ ++ PREFETCH(MT2266_ENABLES, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= UncheckedSet(pInfo, MT2266_ENABLES, (U8Data)(flags & 0xff)); ++ } ++ ++ return status; ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION - DO NOT USE OUTSIDE OF mt2266.c ++** ++** Name: UncheckedSet ++** ++** Description: Sets an MT2266 register. ++** ++** NOTE: This is a local function that performs the same ++** steps as the MT2266_SetReg function that is available ++** in the external API. It does not do any of the standard ++** error checking that the API function provides and should ++** not be called from outside this file. ++** ++** Parameters: *pInfo - Tuner control structure ++** reg - MT2266 register/subaddress location ++** val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Sets a register value without any preliminary checking for ++** valid handles or register numbers. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++static UData_t UncheckedSet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data val) ++{ ++ UData_t status; /* Status to be returned */ ++ ++#if defined(_DEBUG) ++ status = MT_OK; ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_IS_ERROR(status)) ++ return (status); ++#endif ++ ++ status = MT2266_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); ++ ++ if (MT_NO_ERROR(status)) ++ pInfo->reg[reg] = val; ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetReg ++** ++** Description: Sets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedSet(pInfo, reg, val); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetUHFXFreqs ++** ++** Description: Assigns the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_GetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** ... ++** tmpFreqs[i] = ++** ... ++** status = MT2266_SetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 10-26-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ ++ if (freq_type >= MT2266_NUMBER_OF_XFREQ_SETS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ int i; ++ ++ for( i = 0; i < MT2266_NUM_XFREQS; i++ ) ++ { ++ pInfo->xfreqs.xfreq[ freq_type ][i] = freqs_buffer[i] * 1000 / TUNE_STEP_SIZE; ++ } ++ } ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION ++** ++** Name: RoundToStep ++** ++** Description: Rounds the given frequency to the closes f_Step value ++** given the tuner ref frequency.. ++** ++** ++** Parameters: freq - Frequency to be rounded (in Hz). ++** f_Step - Step size for the frequency (in Hz). ++** f_Ref - SRO frequency (in Hz). ++** ++** Returns: Rounded frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++static UData_t RoundToStep(UData_t freq, UData_t f_Step, UData_t f_ref) ++{ ++ return f_ref * (freq / f_ref) ++ + f_Step * (((freq % f_ref) + (f_Step / 2)) / f_Step); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: fLO_FractionalTerm ++** ++** Description: Calculates the portion contributed by FracN / denom. ++** ++** This function preserves maximum precision without ++** risk of overflow. It accurately calculates ++** f_ref * num / denom to within 1 HZ with fixed math. ++** ++** Parameters: num - Fractional portion of the multiplier ++** denom - denominator portion of the ratio ++** This routine successfully handles denom values ++** up to and including 2^18. ++** f_Ref - SRO frequency. This calculation handles ++** f_ref as two separate 14-bit fields. ++** Therefore, a maximum value of 2^28-1 ++** may safely be used for f_ref. This is ++** the genesis of the magic number "14" and the ++** magic mask value of 0x03FFF. ++** ++** Returns: f_ref * num / denom ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-20-2006 RSK Ver 1.04: Adding fLO_FractionalTerm() usage. ++** ++****************************************************************************/ ++static UData_t fLO_FractionalTerm( UData_t f_ref, ++ UData_t num, ++ UData_t denom ) ++{ ++ UData_t t1 = (f_ref >> 14) * num; ++ UData_t term1 = t1 / denom; ++ UData_t loss = t1 % denom; ++ UData_t term2 = ( ((f_ref & 0x00003FFF) * num + (loss<<14)) + (denom/2) ) / denom; ++ return ((term1 << 14) + term2); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION ++** ++** Name: CalcLOMult ++** ++** Description: Calculates Integer divider value and the numerator ++** value for LO's FracN PLL. ++** ++** This function assumes that the f_LO and f_Ref are ++** evenly divisible by f_LO_Step. ++** ++** Parameters: Div - OUTPUT: Whole number portion of the multiplier ++** FracN - OUTPUT: Fractional portion of the multiplier ++** f_LO - desired LO frequency. ++** denom - LO FracN denominator value ++** f_Ref - SRO frequency. ++** ++** Returns: Recalculated LO frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 12-20-2006 RSK Ver 1.04: Adding fLO_FractionalTerm() usage. ++** ++****************************************************************************/ ++static UData_t CalcLOMult(UData_t *Div, ++ UData_t *FracN, ++ UData_t f_LO, ++ UData_t denom, ++ UData_t f_Ref) ++{ ++ UData_t a, b, i; ++ const SData_t TwoNShift = 13; // bits to shift to obtain 2^n qty ++ const SData_t RoundShift = 18; // bits to shift before rounding ++ ++ /* Calculate the whole number portion of the divider */ ++ *Div = f_LO / f_Ref; ++ ++ /* ++ ** Calculate the FracN numerator 1 bit at a time. This keeps the ++ ** integer values from overflowing when large values are multiplied. ++ ** This loop calculates the fractional portion of F/20MHz accurate ++ ** to 32 bits. The 2^n factor is represented by the placement of ++ ** the value in the 32-bit word. Since we want as much accuracy ++ ** as possible, we'll leave it at the top of the word. ++ */ ++ *FracN = 0; ++ a = f_LO; ++ for (i=32; i>0; --i) ++ { ++ b = 2*(a % f_Ref); ++ *FracN = (*FracN * 2) + (b >= f_Ref); ++ a = b; ++ } ++ ++ /* ++ ** If the denominator is a 2^n - 1 value (the usual case) then the ++ ** value we really need is (F/20) * 2^n - (F/20). Shifting the ++ ** calculated (F/20) value to the right and subtracting produces ++ ** the desired result -- still accurate to 32 bits. ++ */ ++ if ((denom & 0x01) != 0) ++ *FracN -= (*FracN >> TwoNShift); ++ ++ /* ++ ** Now shift the result so that it is 1 bit bigger than we need, ++ ** use the low-order bit to round the remaining bits, and shift ++ ** to make the answer the desired size. ++ */ ++ *FracN >>= RoundShift; ++ *FracN = (*FracN & 0x01) + (*FracN >> 1); ++ ++ /* Check for rollover (cannot happen with 50 kHz step size) */ ++ if (*FracN == (denom | 1)) ++ { ++ *FracN = 0; ++ ++Div; ++ } ++ ++ ++ return (f_Ref * (*Div)) + fLO_FractionalTerm( f_Ref, *FracN, denom ); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION ++** ++** Name: GetCrossover ++** ++** Description: Determines the appropriate value in the set of ++** crossover frequencies. ++** ++** This function assumes that the crossover frequency table ++** ias been properly initialized in descending order. ++** ++** Parameters: f_in - The input frequency to use. ++** freqs - The array of crossover frequency entries. ++** ++** Returns: Index of crossover frequency band to use. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 10-27-2006 RSK Original ++** ++****************************************************************************/ ++static U8Data GetCrossover( UData_t f_in, UData_t* freqs ) ++{ ++ U8Data idx; ++ U8Data retVal = 0; ++ ++ for (idx=0; idx< (U8Data)MT2266_NUM_XFREQS; idx++) ++ { ++ if ( freqs[idx] >= f_in) ++ { ++ retVal = (U8Data)MT2266_NUM_XFREQS - idx; ++ break; ++ } ++ } ++ ++ return retVal; ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_ChangeFreq ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_ChangeFreq! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Added usage of UFILT0 and UFILT1. ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification ++** 118 05-09-2007 RSK Ver 1.05: Refactored to call _Tune() API. ++** ++****************************************************************************/ ++UData_t MT2266_ChangeFreq(Handle_t h, ++ UData_t f_in) /* RF input center frequency */ ++{ ++ return (MT2266_Tune(h, f_in)); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_Tune ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_Tune! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Added usage of UFILT0 and UFILT1. ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification ++** 118 05-09-2007 RSK Ver 1.05: Adding Standard MTxxxx_Tune() API. ++** ++****************************************************************************/ ++UData_t MT2266_Tune(Handle_t h, ++ UData_t f_in) /* RF input center frequency */ ++{ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ UData_t status = MT_OK; /* status of operation */ ++ UData_t LO; /* LO register value */ ++ UData_t Num; /* Numerator for LO reg. value */ ++ UData_t ofLO; /* last time's LO frequency */ ++ UData_t ofin; /* last time's input frequency */ ++ U8Data LO_Band; /* LO Mode bits */ ++ UData_t s_fRef; /* Ref Freq scaled for LO Band */ ++ UData_t this_band; /* Band for the requested freq */ ++ UData_t SROx2; /* SRO times 2 */ ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ return MT_INV_HANDLE; ++ ++ /* ++ ** Save original input and LO value ++ */ ++ ofLO = pInfo->f_LO; ++ ofin = pInfo->f_in; ++ ++ /* ++ ** Assign in the requested input value ++ */ ++ pInfo->f_in = f_in; ++ ++ /* ++ ** Get the SRO multiplier value ++ */ ++ SROx2 = (2 - (pInfo->reg[MT2266_SRO_CTRL] & 0x01)); ++ ++ /* Check f_Step value */ ++ if(pInfo->f_Step == 0) ++ return MT_UNKNOWN; ++ ++ /* Request an LO that is on a step size boundary */ ++ pInfo->f_LO = RoundToStep(f_in, pInfo->f_Step, pInfo->f_Ref); ++ ++ if (pInfo->f_LO < MIN_VHF_FREQ) ++ { ++ status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE; ++ return status; /* Does not support frequencies below MIN_VHF_FREQ */ ++ } ++ else if (pInfo->f_LO <= MAX_VHF_FREQ) ++ { ++ /* VHF Band */ ++ s_fRef = pInfo->f_Ref * SROx2 / 4; ++ LO_Band = 0; ++ this_band = MT2266_VHF_BAND; ++ } ++ else if (pInfo->f_LO < MIN_UHF_FREQ) ++ { ++ status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE; ++ return status; /* Does not support frequencies between MAX_VHF_FREQ & MIN_UHF_FREQ */ ++ } ++ else if (pInfo->f_LO <= MAX_UHF_FREQ) ++ { ++ /* UHF Band */ ++ s_fRef = pInfo->f_Ref * SROx2 / 2; ++ LO_Band = 1; ++ this_band = MT2266_UHF_BAND; ++ } ++ else ++ { ++ status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE; ++ return status; /* Does not support frequencies above MAX_UHF_FREQ */ ++ } ++ ++ /* ++ ** Calculate the LO frequencies and the values to be placed ++ ** in the tuning registers. ++ */ ++ pInfo->f_LO = CalcLOMult(&LO, &Num, pInfo->f_LO, 8191, s_fRef); ++ ++ /* ++ ** If we have the same LO frequencies and we're already locked, ++ ** then just return without writing any registers. ++ */ ++ if ((ofLO == pInfo->f_LO) ++ && ((pInfo->reg[MT2266_STATUS_1] & 0x40) == 0x40)) ++ { ++ return (status); ++ } ++ ++ /* ++ ** Reset defaults here if we're tuning into a new band ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ if (this_band != pInfo->band) ++ { ++ MT2266_DefaultsEntry *defaults = MT_NULL; ++ switch (this_band) ++ { ++ case MT2266_VHF_BAND: ++ defaults = &MT2266_VHF_defaults[0]; ++ break; ++ case MT2266_UHF_BAND: ++ defaults = &MT2266_UHF_defaults[0]; ++ break; ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ if ( MT_NO_ERROR(status)) ++ { ++ while (defaults->data && MT_NO_ERROR(status)) ++ { ++ status |= MT2266_WriteSub(pInfo->hUserData, pInfo->address, defaults->data[0], &defaults->data[1], defaults->cnt); ++ defaults++; ++ } ++ /* re-read the new registers into the cached values */ ++ status |= MT2266_ReadSub(pInfo->hUserData, pInfo->address, 0, &pInfo->reg[0], END_REGS); ++ pInfo->band = this_band; ++ } ++ } ++ } ++ ++ /* ++ ** Place all of the calculated values into the local tuner ++ ** register fields. ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->reg[MT2266_LO_CTRL_1] = (U8Data)(Num >> 8); ++ pInfo->reg[MT2266_LO_CTRL_2] = (U8Data)(Num & 0xFF); ++ pInfo->reg[MT2266_LO_CTRL_3] = (U8Data)(LO & 0xFF); ++ ++ /* ++ ** Now write out the computed register values ++ */ ++ status |= MT2266_WriteSub(pInfo->hUserData, pInfo->address, MT2266_LO_CTRL_1, &pInfo->reg[MT2266_LO_CTRL_1], 3); ++ ++ if (pInfo->band == MT2266_UHF_BAND) ++ { ++ U8Data UFilt0 = 0; /* def when f_in > all */ ++ U8Data UFilt1 = 0; /* def when f_in > all */ ++ UData_t* XFreq0; ++ UData_t* XFreq1; ++ SData_t ClearTune_Fuse; ++ SData_t f_offset; ++ UData_t f_in_; ++ ++ PREFETCH(MT2266_BAND_CTRL, 2); /* Fetch register(s) if __NO_CACHE__ defined */ ++ PREFETCH(MT2266_STATUS_5, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ ++ XFreq0 = (pInfo->reg[MT2266_BAND_CTRL] & 0x10) ? pInfo->xfreqs.xfreq[ MT2266_UHF0_ATTEN ] : pInfo->xfreqs.xfreq[ MT2266_UHF0 ]; ++ XFreq1 = (pInfo->reg[MT2266_BAND_CTRL] & 0x10) ? pInfo->xfreqs.xfreq[ MT2266_UHF1_ATTEN ] : pInfo->xfreqs.xfreq[ MT2266_UHF1 ]; ++ ++ ClearTune_Fuse = pInfo->reg[MT2266_STATUS_5] & 0x07; ++ f_offset = (10000000) * ((ClearTune_Fuse > 3) ? (ClearTune_Fuse - 8) : ClearTune_Fuse); ++ f_in_ = (f_in - f_offset) / 1000 / TUNE_STEP_SIZE; ++ ++ UFilt0 = GetCrossover( f_in_, XFreq0 ); ++ UFilt1 = GetCrossover( f_in_, XFreq1 ); ++ ++ /* If UFilt == 16, set UBANDen and set UFilt = 15 */ ++ if ( (UFilt0 == 16) || (UFilt1 == 16) ) ++ { ++ pInfo->reg[MT2266_BAND_CTRL] |= 0x01; ++ if( UFilt0 > 0 ) UFilt0--; ++ if( UFilt1 > 0 ) UFilt1--; ++ } ++ else ++ pInfo->reg[MT2266_BAND_CTRL] &= ~(0x01); ++ ++ pInfo->reg[MT2266_BAND_CTRL] = ++ (pInfo->reg[MT2266_BAND_CTRL] & 0x3F) | (LO_Band << 6); ++ ++ pInfo->reg[MT2266_CLEARTUNE] = (UFilt1 << 4) | UFilt0; ++ /* Write UBANDsel [05] & ClearTune [06] */ ++ status |= MT2266_WriteSub(pInfo->hUserData, pInfo->address, MT2266_BAND_CTRL, &pInfo->reg[MT2266_BAND_CTRL], 2); ++ } ++ } ++ ++ /* ++ ** Check for LO lock ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2266_GetLocked(h); ++ } ++ ++ return (status); ++} ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2266.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2266.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mt2266.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mt2266.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,1533 @@ ++#ifndef __TUNER_MT2266_H ++#define __TUNER_MT2266_H ++ ++/** ++ ++@file ++ ++@brief MT2266 tuner module declaration ++ ++One can manipulate MT2266 tuner through MT2266 module. ++MT2266 module is derived from tunerd module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_mt2266.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthHz; ++ ++ ++ ... ++ ++ ++ ++ // Build MT2266 tuner module. ++ BuildMt2266Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0 // I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2266 tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ ++ // Open MT2266 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MT2266 bandwidth. ++ pTunerExtra->SetBandwidthHz(pTuner, MT2266_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MT2266 bandwidth. ++ pTunerExtra->GetBandwidthHz(pTuner, &BandwidthHz); ++ ++ ++ ++ ++ ++ // Close MT2266 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_errordef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_errordef.h ++** ++** Description: Definition of bits in status/error word used by various ++** MicroTuner control programs. ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_errordef.h,v 1.1 2006/06/22 20:18:12 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt_errordef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 09-09-2004 JWS Original ++** 088 01-26-2005 DAD Added MT_TUNER_INIT_ERR. ++** N/A 12-09-2005 DAD Added MT_TUNER_TIMEOUT (info). ++** ++*****************************************************************************/ ++ ++/* ++** Note to users: DO NOT EDIT THIS FILE ++** ++** If you wish to rename any of the "user defined" bits, ++** it should be done in the user file that includes this ++** source file (e.g. mt_userdef.h) ++** ++*/ ++ ++ ++ ++/* ++** 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 ++** 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ++** M U <- Info Codes --> <# Spurs> < User> <----- Err Codes -----> ++** ++** 31 = MT_ERROR - Master Error Flag. If set, check Err Codes for reason. ++** 30 = MT_USER_ERROR - User-declared error flag. ++** 29 = Unused ++** 28 = Unused ++** 27 = MT_DNC_RANGE ++** 26 = MT_UPC_RANGE ++** 25 = MT_FOUT_RANGE ++** 24 = MT_FIN_OUT_OF_RANGE ++** 23 = MT_SPUR_PRESENT - Unavoidable spur in output ++** 22 = MT_TUNER_TIMEOUT ++** 21 = Unused ++** 20 = Unused ++** 19 = MT_SPUR_CNT_MASK (MSB) - Count of avoided spurs ++** 18 = MT_SPUR_CNT_MASK ++** 17 = MT_SPUR_CNT_MASK ++** 16 = MT_SPUR_CNT_MASK ++** 15 = MT_SPUR_CNT_MASK (LSB) ++** 14 = MT_USER_DEFINED4 - User-definable bit (see MT_Userdef.h) ++** 13 = MT_USER_DEFINED3 - User-definable bit (see MT_Userdef.h) ++** 12 = MT_USER_DEFINED2 - User-definable bit (see MT_Userdef.h) ++** 11 = MT_USER_DEFINED1 - User-definable bit (see MT_Userdef.h) ++** 10 = Unused ++** 9 = MT_TUNER_INIT_ERR - Tuner initialization error ++** 8 = MT_TUNER_ID_ERR - Tuner Part Code / Rev Code mismatches expected value ++** 7 = MT_TUNER_CNT_ERR - Attempt to open more than MT_TUNER_CNT tuners ++** 6 = MT_ARG_NULL - Null pointer passed as argument ++** 5 = MT_ARG_RANGE - Argument value out of range ++** 4 = MT_INV_HANDLE - Tuner handle is invalid ++** 3 = MT_COMM_ERR - Serial bus communications error ++** 2 = MT_DNC_UNLOCK - Downconverter PLL is unlocked ++** 1 = MT_UPC_UNLOCK - Upconverter PLL is unlocked ++** 0 = MT_UNKNOWN - Unknown error ++*/ ++#define MT_ERROR (1 << 31) ++#define MT_USER_ERROR (1 << 30) ++ ++/* Macro to be used to check for errors */ ++#define MT_IS_ERROR(s) (((s) >> 30) != 0) ++#define MT_NO_ERROR(s) (((s) >> 30) == 0) ++ ++ ++#define MT_OK (0x00000000) ++ ++/* Unknown error */ ++#define MT_UNKNOWN (0x80000001) ++ ++/* Error: Upconverter PLL is not locked */ ++#define MT_UPC_UNLOCK (0x80000002) ++ ++/* Error: Downconverter PLL is not locked */ ++#define MT_DNC_UNLOCK (0x80000004) ++ ++/* Error: Two-wire serial bus communications error */ ++#define MT_COMM_ERR (0x80000008) ++ ++/* Error: Tuner handle passed to function was invalid */ ++#define MT_INV_HANDLE (0x80000010) ++ ++/* Error: Function argument is invalid (out of range) */ ++#define MT_ARG_RANGE (0x80000020) ++ ++/* Error: Function argument (ptr to return value) was NULL */ ++#define MT_ARG_NULL (0x80000040) ++ ++/* Error: Attempt to open more than MT_TUNER_CNT tuners */ ++#define MT_TUNER_CNT_ERR (0x80000080) ++ ++/* Error: Tuner Part Code / Rev Code mismatches expected value */ ++#define MT_TUNER_ID_ERR (0x80000100) ++ ++/* Error: Tuner Initialization failure */ ++#define MT_TUNER_INIT_ERR (0x80000200) ++ ++/* User-definable fields (see mt_userdef.h) */ ++#define MT_USER_DEFINED1 (0x00001000) ++#define MT_USER_DEFINED2 (0x00002000) ++#define MT_USER_DEFINED3 (0x00004000) ++#define MT_USER_DEFINED4 (0x00008000) ++#define MT_USER_MASK (0x4000f000) ++#define MT_USER_SHIFT (12) ++ ++/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */ ++#define MT_SPUR_CNT_MASK (0x001f0000) ++#define MT_SPUR_SHIFT (16) ++ ++/* Info: Tuner timeout waiting for condition */ ++#define MT_TUNER_TIMEOUT (0x00400000) ++ ++/* Info: Unavoidable LO-related spur may be present in the output */ ++#define MT_SPUR_PRESENT (0x00800000) ++ ++/* Info: Tuner input frequency is out of range */ ++#define MT_FIN_RANGE (0x01000000) ++ ++/* Info: Tuner output frequency is out of range */ ++#define MT_FOUT_RANGE (0x02000000) ++ ++/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */ ++#define MT_UPC_RANGE (0x04000000) ++ ++/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */ ++#define MT_DNC_RANGE (0x08000000) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.h ++** ++** Description: User-defined data types needed by MicroTuner source code. ++** ++** Customers must provide the code for these functions ++** in the file "mt_userdef.c". ++** ++** Customers must verify that the typedef's in the ++** "Data Types" section are correct for their platform. ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.h,v 1.1 2006/06/22 20:18:12 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt_userdef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** 082 12-06-2004 JWS Multi-tuner support - requires MTxxxx_CNT ++** declarations ++** ++*****************************************************************************/ ++#if !defined( __MT_USERDEF_H ) ++#define __MT_USERDEF_H ++ ++//#include "mt_errordef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++/* ++** Data Types ++*/ ++typedef unsigned char U8Data; /* type corresponds to 8 bits */ ++typedef unsigned int UData_t; /* type must be at least 32 bits */ ++typedef int SData_t; /* type must be at least 32 bits */ ++typedef void * Handle_t; /* memory pointer type */ ++typedef double FData_t; /* floating point data type */ ++ ++#define MAX_UDATA (4294967295) /* max value storable in UData_t */ ++ ++/* ++** Define an MTxxxx_CNT macro for each type of tuner that will be built ++** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT ++** must be set to the SUM of all of the MTxxxx_CNT macros. ++** ++** #define MT2050_CNT (1) ++** #define MT2060_CNT (1) ++** #define MT2111_CNT (1) ++** #define MT2121_CNT (3) ++*/ ++ ++ ++#if !defined( MT_TUNER_CNT ) ++#define MT_TUNER_CNT (1) /* total num of MicroTuner tuners */ ++#endif ++ ++/* ++** Optional user-defined Error/Info Codes (examples below) ++** ++** This is the area where you can define user-specific error/info return ++** codes to be returned by any of the functions you are responsible for ++** writing such as MT_WriteSub() and MT_ReadSub. There are four bits ++** available in the status field for your use. When set, these ++** bits will be returned in the status word returned by any tuner driver ++** call. If you OR in the MT_ERROR bit as well, the tuner driver code ++** will treat the code as an error. ++** ++** The following are a few examples of errors you can provide. ++** ++** Example 1: ++** You might check to see the hUserData handle is correct and issue ++** MY_USERDATA_INVALID which would be defined like this: ++** ++** #define MY_USERDATA_INVALID (MT_USER_ERROR | MT_USER_DEFINED1) ++** ++** ++** Example 2: ++** You might be able to provide more descriptive two-wire bus errors: ++** ++** #define NO_ACK (MT_USER_ERROR | MT_USER_DEFINED1) ++** #define NO_NACK (MT_USER_ERROR | MT_USER_DEFINED2) ++** #define BUS_BUSY (MT_USER_ERROR | MT_USER_DEFINED3) ++** ++** ++** Example 3: ++** You can also provide information (non-error) feedback: ++** ++** #define MY_INFO_1 (MT_USER_DEFINED1) ++** ++** ++** Example 4: ++** You can combine the fields together to make a multi-bit field. ++** This one can provide the tuner number based off of the addr ++** passed to MT_WriteSub or MT_ReadSub. It assumes that ++** MT_USER_DEFINED4 through MT_USER_DEFINED1 are contiguously. If ++** TUNER_NUM were OR'ed into the status word on an error, you could ++** use this to identify which tuner had the problem (and whether it ++** was during a read or write operation). ++** ++** #define TUNER_NUM ((addr & 0x07) >> 1) << MT_USER_SHIFT ++** ++*/ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2266_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime); ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (for MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas); ++#endif ++#endif ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt2266.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt2266.h ++** ++** Copyright 2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2266.h ++** ++** Description: Microtune MT2266 Tuner software interface. ++** Supports tuners with Part/Rev code: 0x85. ++** ++** Functions ++** Implemented: UData_t MT2266_Open ++** UData_t MT2266_Close ++** UData_t MT2266_ChangeFreq ++** UData_t MT2266_GetLocked ++** UData_t MT2266_GetParam ++** UData_t MT2266_GetReg ++** UData_t MT2266_GetUHFXFreqs ++** UData_t MT2266_GetUserData ++** UData_t MT2266_ReInit ++** UData_t MT2266_SetParam ++** UData_t MT2266_SetPowerModes ++** UData_t MT2266_SetReg ++** UData_t MT2266_SetUHFXFreqs ++** UData_t MT2266_Tune ++** ++** References: AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for x milliseconds ++** ++** CVS ID: $Id: mt2266.h,v 1.3 2007/10/02 18:43:17 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt2266.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Adding Get/Set UHFXFreq access functions. ++** 118 05-09-2007 RSK Ver 1.05: Adding Standard MTxxxx_Tune() API. ++** ++*****************************************************************************/ ++#if !defined( __MT2266_H ) ++#define __MT2266_H ++ ++//#include "mt_userdef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++/* ++** Parameter for function MT2266_GetParam & MT2266_SetParam that ++** specifies the tuning algorithm parameter to be read/written. ++*/ ++typedef enum ++{ ++ /* tuner address set by MT2266_Open() */ ++ MT2266_IC_ADDR, ++ ++ /* max number of MT2266 tuners set by MT2266_CNT in mt_userdef.h */ ++ MT2266_MAX_OPEN, ++ ++ /* current number of open MT2266 tuners set by MT2266_Open() */ ++ MT2266_NUM_OPEN, ++ ++ /* Number of tuner registers */ ++ MT2266_NUM_REGS, ++ ++ /* crystal frequency (default: 18000000 Hz) */ ++ MT2266_SRO_FREQ, ++ ++ /* min tuning step size (default: 50000 Hz) */ ++ MT2266_STEPSIZE, ++ ++ /* input center frequency set by MT2266_ChangeFreq() */ ++ MT2266_INPUT_FREQ, ++ ++ /* LO Frequency set by MT2266_ChangeFreq() */ ++ MT2266_LO_FREQ, ++ ++ /* output channel bandwidth (default: 8000000 Hz) */ ++ MT2266_OUTPUT_BW, ++ ++ /* Base band filter calibration RC code (default: N/A) */ ++ MT2266_RC2_VALUE, ++ ++ /* Base band filter nominal cal RC code (default: N/A) */ ++ MT2266_RC2_NOMINAL, ++ ++ /* RF attenuator A/D readback (read-only) */ ++ MT2266_RF_ADC, ++ ++ /* BB attenuator A/D readback (read-only) */ ++ MT2266_BB_ADC, ++ ++ /* RF attenuator setting (default: varies) */ ++ MT2266_RF_ATTN, ++ ++ /* BB attenuator setting (default: varies) */ ++ MT2266_BB_ATTN, ++ ++ /* RF external / internal atten control (default: varies) */ ++ MT2266_RF_EXT, ++ ++ /* BB external / internal atten control (default: 1) */ ++ MT2266_BB_EXT, ++ ++ /* LNA gain setting (0-15) (default: varies) */ ++ MT2266_LNA_GAIN, ++ ++ /* Decrement LNA Gain (where arg=min LNA Gain value) */ ++ MT2266_LNA_GAIN_DECR, ++ ++ /* Increment LNA Gain (where arg=max LNA Gain value) */ ++ MT2266_LNA_GAIN_INCR, ++ ++ /* Set for UHF max sensitivity mode */ ++ MT2266_UHF_MAXSENS, ++ ++ /* Set for UHF normal mode */ ++ MT2266_UHF_NORMAL, ++ ++ MT2266_EOP /* last entry in enumerated list */ ++} MT2266_Param; ++ ++ ++/* ++** Parameter for function MT2266_GetUHFXFreqs & MT2266_SetUHFXFreqs that ++** specifies the particular frequency crossover table to be read/written. ++*/ ++typedef enum ++{ ++ /* Reference the UHF 0 filter, without any attenuation */ ++ MT2266_UHF0, ++ ++ /* Reference the UHF 1 filter, without any attenuation */ ++ MT2266_UHF1, ++ ++ /* Reference the UHF 0 filter, with attenuation */ ++ MT2266_UHF0_ATTEN, ++ ++ /* Reference the UHF 1 filter, with attenuation */ ++ MT2266_UHF1_ATTEN, ++ ++ MT2266_NUMBER_OF_XFREQ_SETS /* last entry in enumerated list */ ++ ++} MT2266_UHFXFreq_Type; ++ ++ ++#define MT2266_NUM_XFREQS (16) ++ ++typedef UData_t MT2266_XFreq_Set[ MT2266_NUM_XFREQS ]; ++ ++/* ++** Constants for Specifying Operating Band of the Tuner ++*/ ++#define MT2266_VHF_BAND (0) ++#define MT2266_UHF_BAND (1) ++#define MT2266_L_BAND (2) ++ ++/* ++** Constants for specifying power modes these values ++** are bit-mapped and can be added/OR'ed to indicate ++** multiple settings. Examples: ++** MT2266_SetPowerModes(h, MT2266_NO_ENABLES + MT22266_SROsd); ++** MT2266_SetPowerModes(h, MT2266_ALL_ENABLES | MT22266_SRO_NOT_sd); ++** MT2266_SetPowerModes(h, MT2266_NO_ENABLES + MT22266_SROsd); ++** MT2266_SetPowerModes(h, MT2266_SROen + MT22266_LOen + MT2266_ADCen); ++*/ ++#define MT2266_SROen (0x01) ++#define MT2266_LOen (0x02) ++#define MT2266_ADCen (0x04) ++#define MT2266_PDen (0x08) ++#define MT2266_DCOCen (0x10) ++#define MT2266_BBen (0x20) ++#define MT2266_MIXen (0x40) ++#define MT2266_LNAen (0x80) ++#define MT2266_ALL_ENABLES (0xFF) ++#define MT2266_NO_ENABLES (0x00) ++#define MT2266_SROsd (0x100) ++#define MT2266_SRO_NOT_sd (0x000) ++ ++/* ====== Functions which are declared in mt2266.c File ======= */ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Usage: status = MT2266_Open(0xC0, &hMT2266, NULL); ++** if (MT_IS_ERROR(status)) ++** // Check error codes for reason ++** ++** Parameters: MT2266_Addr - Serial bus address of the tuner. ++** hMT2266 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_COMM_ERR - Serial bus communications error ++** MT_ARG_NULL - Null pointer argument passed ++** MT_TUNER_CNT_ERR - Too many tuners open ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_Open(UData_t MT2266_Addr, ++ Handle_t* hMT2266, ++ Handle_t hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Usage: status = MT2266_Close(hMT2266); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_Close(Handle_t hMT2266); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_ChangeFreq ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Usage: status = MT2266_ChangeFreq(hMT2266, f_in); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_ChangeFreq! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_ChangeFreq(Handle_t h, ++ UData_t f_in); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetLocked ++** ++** Description: Checks to see if the PLL is locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: status = MT2266_GetLocked(hMT2266); ++** if (status & MT_DNC_UNLOCK) ++** // error!, PLL is unlocked ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetLocked(Handle_t h); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_IC_ADDR Serial Bus address of this tuner ++** MT2266_MAX_OPEN Max number of MT2266's that can be open ++** MT2266_NUM_OPEN Number of MT2266's currently open ++** MT2266_NUM_REGS Number of tuner registers ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ input center frequency ++** MT2266_LO_FREQ LO Frequency ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RC2_VALUE Base band filter cal RC code (method 2) ++** MT2266_RF_ADC RF attenuator A/D readback ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_BB_ADC BB attenuator A/D readback ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** ++** Usage: status |= MT2266_GetParam(hMT2266, ++** MT2266_OUTPUT_BW, ++** &f_bw); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t* pValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetReg ++** ++** Description: Gets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** *val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2266. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUHFXFreqs ++** ++** Description: Retrieves the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_GetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 11-01-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Usage: status = MT2266_GetUserData(hMT2266, &hUserData); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2266_SetUserData, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetUserData(Handle_t h, ++ Handle_t* hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_ReInit(Handle_t h); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ Center of input channel ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_LNA_GAIN_DECR Decrement LNA Gain (arg=min) ++** MT2266_LNA_GAIN_INCR Increment LNA Gain (arg=max) ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** MT2266_UHF_MAXSENS Set for UHF max sensitivity mode ++** MT2266_UHF_NORMAL Set for UHF normal mode ++** ++** Usage: status |= MT2266_SetParam(hMT2266, ++** MT2266_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_GetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t nValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetPowerModes ++** ++** Description: Sets the bits in the MT2266_ENABLES register and the ++** SROsd bit in the MT2266_SROADC_CTRL register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** flags - Bit mask of flags to indicate enabled ++** bits. ++** ++** Usage: status = MT2266_SetPowerModes(hMT2266, flags); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The bits in the MT2266_ENABLES register and the ++** SROsd bit are set according to the supplied flags. ++** ++** The pre-defined flags are as follows: ++** MT2266_SROen ++** MT2266_LOen ++** MT2266_ADCen ++** MT2266_PDen ++** MT2266_DCOCen ++** MT2266_BBen ++** MT2266_MIXen ++** MT2266_LNAen ++** MT2266_ALL_ENABLES ++** MT2266_NO_ENABLES ++** MT2266_SROsd ++** MT2266_SRO_NOT_sd ++** ++** ONLY the enable bits (or SROsd bit) specified in the ++** flags parameter will be set. Any flag which is not ++** included, will cause that bit to be disabled. ++** ++** The ALL_ENABLES, NO_ENABLES, and SRO_NOT_sd constants ++** are for convenience. The NO_ENABLES and SRO_NOT_sd ++** do not actually have to be included, but are provided ++** for clarity. ++** ++** See Also: MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetPowerModes(Handle_t h, ++ UData_t flags); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetReg ++** ++** Description: Sets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetUHFXFreqs ++** ++** Description: Retrieves the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_SetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 11_01-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_Tune ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Usage: status = MT2266_Tune(hMT2266, f_in); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_Tune! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 118 05-09-2007 RSK Original API Introduction (was ChangeFreq). ++** ++******************************************************************************/ ++UData_t MT2266_Tune(Handle_t h, ++ UData_t f_in); ++ ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MT2266 tuner API source code ++ ++ ++ ++ ++ ++/** ++ ++@file ++ ++@brief MT2266 tuner module declaration ++ ++One can manipulate MT2266 tuner through MT2266 module. ++MT2266 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// MT2266 API option ++#define __NO_CACHE__ ++#define MT2266_CNT 4 ++ ++ ++// Bandwidth modes ++enum MT2266_BANDWIDTH_HZ ++{ ++ MT2266_BANDWIDTH_5MHZ = 5000000, ++ MT2266_BANDWIDTH_6MHZ = 6000000, ++ MT2266_BANDWIDTH_7MHZ = 7000000, ++ MT2266_BANDWIDTH_8MHZ = 8000000, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMt2266Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++mt2266_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++mt2266_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++mt2266_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2266_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++mt2266_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++mt2266_OpenHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2266_CloseHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++void ++mt2266_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++int ++mt2266_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++int ++mt2266_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,1267 @@ ++/** ++ ++@file ++ ++@brief MxL5007T tuner module definition ++ ++One can manipulate MxL5007T tuner through MxL5007T module. ++MxL5007T module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_mxl5007t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MxL5007T tuner module builder ++ ++Use BuildMxl5007tModule() to build MxL5007T module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MxL5007T tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MxL5007T I2C device address ++@param [in] CrystalFreqHz MxL5007T crystal frequency in Hz ++@param [in] StandardMode MxL5007T standard mode ++@param [in] IfFreqHz MxL5007T IF frequency in Hz ++@param [in] LoopThroughMode MxL5007T loop-through mode ++@param [in] ClkOutMode MxL5007T clock output mode ++@param [in] ClkOutAmpMode MxL5007T clock output amplitude mode ++@param [in] QamIfDiffOutLevel MxL5007T QAM IF differential output level for QAM standard only ++ ++ ++@note ++ -# One should call BuildMxl5007tModule() to build MxL5007T module before using it. ++ ++*/ ++void ++BuildMxl5007tModule( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int SpectrumMode, ++ int LoopThroughMode, ++ int ClkOutMode, ++ int ClkOutAmpMode, ++ long QamIfDiffOutLevel ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Set and get MaxLinear-defined MxL5007T structure pointer. ++ pExtra->pTunerConfigS = &(pExtra->TunerConfigSMemory); ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ // Set additional definition tuner module pointer. ++ pTunerConfigS->pTuner = pTuner; ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MXL5007T; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = mxl5007t_GetTunerType; ++ pTuner->GetDeviceAddr = mxl5007t_GetDeviceAddr; ++ ++ pTuner->Initialize = mxl5007t_Initialize; ++ pTuner->SetRfFreqHz = mxl5007t_SetRfFreqHz; ++ pTuner->GetRfFreqHz = mxl5007t_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->LoopThroughMode = LoopThroughMode; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ ++ // Initialize MaxLinear-defined MxL5007T structure variables. ++ // Note: The API doesn't use I2C device address of MaxLinear-defined MxL5007T structure. ++ switch(StandardMode) ++ { ++ default: ++ case MXL5007T_STANDARD_DVBT: pTunerConfigS->Mode = MxL_MODE_DVBT; break; ++ case MXL5007T_STANDARD_ATSC: pTunerConfigS->Mode = MxL_MODE_ATSC; break; ++ case MXL5007T_STANDARD_QAM: pTunerConfigS->Mode = MxL_MODE_CABLE; break; ++ case MXL5007T_STANDARD_ISDBT: pTunerConfigS->Mode = MxL_MODE_ISDBT; break; ++ } ++ ++ pTunerConfigS->IF_Diff_Out_Level = (SINT32)QamIfDiffOutLevel; ++ ++ switch(CrystalFreqHz) ++ { ++ default: ++ case CRYSTAL_FREQ_16000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_16_MHZ; break; ++ case CRYSTAL_FREQ_24000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_24_MHZ; break; ++ case CRYSTAL_FREQ_25000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_25_MHZ; break; ++ case CRYSTAL_FREQ_27000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_27_MHZ; break; ++ case CRYSTAL_FREQ_28800000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_28_8_MHZ; break; ++ } ++ ++ switch(IfFreqHz) ++ { ++ default: ++ case IF_FREQ_4570000HZ: pTunerConfigS->IF_Freq = MxL_IF_4_57_MHZ; break; ++ case IF_FREQ_36150000HZ: pTunerConfigS->IF_Freq = MxL_IF_36_15_MHZ; break; ++ case IF_FREQ_44000000HZ: pTunerConfigS->IF_Freq = MxL_IF_44_MHZ; break; ++ } ++ ++ switch(SpectrumMode) ++ { ++ default: ++ case SPECTRUM_NORMAL: pTunerConfigS->IF_Spectrum = MxL_NORMAL_IF; break; ++ case SPECTRUM_INVERSE: pTunerConfigS->IF_Spectrum = MxL_INVERT_IF; break; ++ } ++ ++ switch(ClkOutMode) ++ { ++ default: ++ case MXL5007T_CLK_OUT_DISABLE: pTunerConfigS->ClkOut_Setting = MxL_CLKOUT_DISABLE; break; ++ case MXL5007T_CLK_OUT_ENABLE: pTunerConfigS->ClkOut_Setting = MxL_CLKOUT_ENABLE; break; ++ } ++ ++ switch(ClkOutAmpMode) ++ { ++ default: ++ case MXL5007T_CLK_OUT_AMP_0: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_0; break; ++ case MXL5007T_CLK_OUT_AMP_1: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_1; break; ++ case MXL5007T_CLK_OUT_AMP_2: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_2; break; ++ case MXL5007T_CLK_OUT_AMP_3: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_3; break; ++ case MXL5007T_CLK_OUT_AMP_4: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_4; break; ++ case MXL5007T_CLK_OUT_AMP_5: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_5; break; ++ case MXL5007T_CLK_OUT_AMP_6: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_6; break; ++ case MXL5007T_CLK_OUT_AMP_7: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_7; break; ++ } ++ ++ pTunerConfigS->BW_MHz = MXL5007T_BANDWIDTH_MODE_DEFAULT; ++ pTunerConfigS->RF_Freq_Hz = MXL5007T_RF_FREQ_HZ_DEFAULT; ++ ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = mxl5007t_SetBandwidthMode; ++ pExtra->GetBandwidthMode = mxl5007t_GetBandwidthMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++mxl5007t_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++mxl5007t_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++mxl5007t_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Get MaxLinear-defined MxL5007T structure. ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ ++ // Initialize tuner. ++ if(MxL_Tuner_Init(pTunerConfigS) != MxL_OK) ++ goto error_status_initialize_tuner; ++ ++ // Set tuner loop-through mode. ++ if(MxL_Loop_Through_On(pTunerConfigS, pExtra->LoopThroughMode) != MxL_OK) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++mxl5007t_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ UINT32 Mxl5007tRfFreqHz; ++ MxL5007_BW_MHz Mxl5007tBandwidthMhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Get MaxLinear-defined MxL5007T structure. ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ ++ // Get bandwidth. ++ Mxl5007tBandwidthMhz = pTunerConfigS->BW_MHz; ++ ++ // Set RF frequency. ++ Mxl5007tRfFreqHz = (UINT32)RfFreqHz; ++ ++ // Set MxL5007T RF frequency and bandwidth. ++ if(MxL_Tuner_RFTune(pTunerConfigS, Mxl5007tRfFreqHz, Mxl5007tBandwidthMhz) != MxL_OK) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++mxl5007t_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MxL5007T tuner bandwidth mode. ++ ++*/ ++int ++mxl5007t_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ UINT32 Mxl5007tRfFreqHz; ++ MxL5007_BW_MHz Mxl5007tBandwidthMhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Get MaxLinear-defined MxL5007T structure. ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ ++ // Get RF frequency. ++ Mxl5007tRfFreqHz = pTunerConfigS->RF_Freq_Hz; ++ ++ // Set bandwidth. ++ switch(BandwidthMode) ++ { ++ case MXL5007T_BANDWIDTH_6000000HZ: Mxl5007tBandwidthMhz = MxL_BW_6MHz; break; ++ case MXL5007T_BANDWIDTH_7000000HZ: Mxl5007tBandwidthMhz = MxL_BW_7MHz; break; ++ case MXL5007T_BANDWIDTH_8000000HZ: Mxl5007tBandwidthMhz = MxL_BW_8MHz; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ // Set MxL5007T RF frequency and bandwidth. ++ if(MxL_Tuner_RFTune(pTunerConfigS, Mxl5007tRfFreqHz, Mxl5007tBandwidthMhz) != MxL_OK) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MxL5007T tuner bandwidth mode. ++ ++*/ ++int ++mxl5007t_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by MaxLinear. ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL_User_Define.c ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL_User_Define.c ++ ++ */ ++ ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++// // ++// I2C Functions (implement by customer) // ++// // ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++ ++/****************************************************************************** ++** ++** Name: MxL_I2C_Write ++** ++** Description: I2C write operations ++** ++** Parameters: ++** DeviceAddr - MxL5007 Device address ++** pArray - Write data array pointer ++** count - total number of array ++** ++** Returns: 0 if success ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-16-2007 khuang initial release. ++** ++******************************************************************************/ ++//UINT32 MxL_I2C_Write(UINT8 DeviceAddr, UINT8* pArray, UINT32 count) ++UINT32 MxL_I2C_Write(MxL5007_TunerConfigS* myTuner, UINT8* pArray, UINT32 count) ++{ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned long WritingByteNumMax; ++ ++ unsigned long i; ++ unsigned char Buffer[I2C_BUFFER_LEN]; ++ unsigned long WritingIndex; ++ ++ unsigned char *pData; ++ unsigned long DataLen; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = myTuner->pTuner; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ // Get writing byte and byte number. ++ pData = (unsigned char *)pArray; ++ DataLen = (unsigned long)count; ++ ++ // Calculate MxL5007T maximum writing byte number. ++ // Note: MxL5007T maximum writing byte number must be a multiple of 2. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax; ++ WritingByteNumMax = ((WritingByteNumMax % 2) == 0) ? WritingByteNumMax : (WritingByteNumMax - 1); ++ ++ ++ // Set register bytes. ++ // Note: The 2 kind of I2C formats of MxL5007T is described as follows: ++ // 1. start_bit + (device_addr | writing_bit) + (register_addr + writing_byte) * n + stop_bit ++ // ... ++ // start_bit + (device_addr | writing_bit) + (register_addr + writing_byte) * m + stop_bit ++ // 2. start_bit + (device_addr | writing_bit) + 0xff + stop_bit ++ for(i = 0, WritingIndex = 0; i < DataLen; i++, WritingIndex++) ++ { ++ // Put data into buffer. ++ Buffer[WritingIndex] = pData[i]; ++ ++ // If writing buffer is full or put data into buffer completely, send the I2C writing command with buffer. ++ if( (WritingIndex == (WritingByteNumMax - 1)) || (i == (DataLen - 1)) ) ++ { ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, Buffer, (WritingIndex + LEN_1_BYTE)) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ WritingIndex = -1; ++ } ++ } ++ ++ ++ return MxL_OK; ++ ++ ++error_status_set_tuner_registers: ++ return MxL_ERR_OTHERS; ++} ++ ++/****************************************************************************** ++** ++** Name: MxL_I2C_Read ++** ++** Description: I2C read operations ++** ++** Parameters: ++** DeviceAddr - MxL5007 Device address ++** Addr - register address for read ++** *Data - data return ++** ++** Returns: 0 if success ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-16-2007 khuang initial release. ++** ++******************************************************************************/ ++//UINT32 MxL_I2C_Read(UINT8 DeviceAddr, UINT8 Addr, UINT8* mData) ++UINT32 MxL_I2C_Read(MxL5007_TunerConfigS* myTuner, UINT8 Addr, UINT8* mData) ++{ ++ TUNER_MODULE *pTuner; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned char Buffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get tuner module and I2C bridge. ++ pTuner = myTuner->pTuner; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + 0xfb + RegReadingAddr + stop_bit ++ Buffer[0] = (unsigned char)MXL5007T_I2C_READING_CONST; ++ Buffer[1] = (unsigned char)Addr; ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, Buffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register bytes. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, Buffer, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ *mData = (UINT8)Buffer[0]; ++ ++ ++ return MxL_OK; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MxL_ERR_OTHERS; ++} ++ ++/****************************************************************************** ++** ++** Name: MxL_Delay ++** ++** Description: Delay function in milli-second ++** ++** Parameters: ++** mSec - milli-second to delay ++** ++** Returns: 0 ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-16-2007 khuang initial release. ++** ++******************************************************************************/ ++//void MxL_Delay(UINT32 mSec) ++void MxL_Delay(MxL5007_TunerConfigS* myTuner, UINT32 mSec) ++{ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get tuner module and base interface. ++ pTuner = myTuner->pTuner; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Wait in ms. ++ pBaseInterface->WaitMs(pBaseInterface, mSec); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007.c ++ ++ ++/* ++ MxL5007 Source Code : V4.1.3 ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007.c ++ ++ Description: The source code is for MxL5007 user to quickly integrate MxL5007 into their software. ++ There are two functions the user can call to generate a array of I2C command that's require to ++ program the MxL5007 tuner. The user should pass an array pointer and an integer pointer in to the ++ function. The funciton will fill up the array with format like follow: ++ ++ addr1 ++ data1 ++ addr2 ++ data2 ++ ... ++ ++ The user can then pass this array to their I2C function to perform progromming the tuner. ++*/ ++//#include "StdAfx.h" ++//#include "MxL5007_Common.h" ++//#include "MxL5007.h" ++ ++ ++ ++UINT32 MxL5007_Init(UINT8* pArray, // a array pointer that store the addr and data pairs for I2C write ++ UINT32* Array_Size, // a integer pointer that store the number of element in above array ++ UINT8 Mode, ++ SINT32 IF_Diff_Out_Level, ++ UINT32 Xtal_Freq_Hz, ++ UINT32 IF_Freq_Hz, ++ UINT8 Invert_IF, ++ UINT8 Clk_Out_Enable, ++ UINT8 Clk_Out_Amp ++ ) ++{ ++ ++ UINT32 Reg_Index=0; ++ UINT32 Array_Index=0; ++ ++ IRVType IRV_Init[]= ++ { ++ //{ Addr, Data} ++ { 0x02, 0x06}, ++ { 0x03, 0x48}, ++ { 0x05, 0x04}, ++ { 0x06, 0x10}, ++ { 0x2E, 0x15}, //Override ++ { 0x30, 0x10}, //Override ++ { 0x45, 0x58}, //Override ++ { 0x48, 0x19}, //Override ++ { 0x52, 0x03}, //Override ++ { 0x53, 0x44}, //Override ++ { 0x6A, 0x4B}, //Override ++ { 0x76, 0x00}, //Override ++ { 0x78, 0x18}, //Override ++ { 0x7A, 0x17}, //Override ++ { 0x85, 0x06}, //Override ++ { 0x01, 0x01}, //TOP_MASTER_ENABLE=1 ++ { 0, 0} ++ }; ++ ++ ++ IRVType IRV_Init_Cable[]= ++ { ++ //{ Addr, Data} ++ { 0x02, 0x06}, ++ { 0x03, 0x48}, ++ { 0x05, 0x04}, ++ { 0x06, 0x10}, ++ { 0x09, 0x3F}, ++ { 0x0A, 0x3F}, ++ { 0x0B, 0x3F}, ++ { 0x2E, 0x15}, //Override ++ { 0x30, 0x10}, //Override ++ { 0x45, 0x58}, //Override ++ { 0x48, 0x19}, //Override ++ { 0x52, 0x03}, //Override ++ { 0x53, 0x44}, //Override ++ { 0x6A, 0x4B}, //Override ++ { 0x76, 0x00}, //Override ++ { 0x78, 0x18}, //Override ++ { 0x7A, 0x17}, //Override ++ { 0x85, 0x06}, //Override ++ { 0x01, 0x01}, //TOP_MASTER_ENABLE=1 ++ { 0, 0} ++ }; ++ //edit Init setting here ++ ++ PIRVType myIRV; ++ ++ switch(Mode) ++ { ++ case MxL_MODE_ISDBT: //ISDB-T Mode ++ myIRV = IRV_Init; ++ SetIRVBit(myIRV, 0x06, 0x1F, 0x10); ++ break; ++ case MxL_MODE_DVBT: //DVBT Mode ++ myIRV = IRV_Init; ++ SetIRVBit(myIRV, 0x06, 0x1F, 0x11); ++ break; ++ case MxL_MODE_ATSC: //ATSC Mode ++ myIRV = IRV_Init; ++ SetIRVBit(myIRV, 0x06, 0x1F, 0x12); ++ break; ++ case MxL_MODE_CABLE: ++ myIRV = IRV_Init_Cable; ++ SetIRVBit(myIRV, 0x09, 0xFF, 0xC1); ++ SetIRVBit(myIRV, 0x0A, 0xFF, 8-IF_Diff_Out_Level); ++ SetIRVBit(myIRV, 0x0B, 0xFF, 0x17); ++ break; ++ ++ ++ } ++ ++ switch(IF_Freq_Hz) ++ { ++ case MxL_IF_4_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x00); ++ break; ++ case MxL_IF_4_5_MHZ: //4.5MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x02); ++ break; ++ case MxL_IF_4_57_MHZ: //4.57MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x03); ++ break; ++ case MxL_IF_5_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x04); ++ break; ++ case MxL_IF_5_38_MHZ: //5.38MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x05); ++ break; ++ case MxL_IF_6_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x06); ++ break; ++ case MxL_IF_6_28_MHZ: //6.28MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x07); ++ break; ++ case MxL_IF_9_1915_MHZ: //9.1915MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x08); ++ break; ++ case MxL_IF_35_25_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x09); ++ break; ++ case MxL_IF_36_15_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x0a); ++ break; ++ case MxL_IF_44_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x0B); ++ break; ++ } ++ ++ if(Invert_IF) ++ SetIRVBit(myIRV, 0x02, 0x10, 0x10); //Invert IF ++ else ++ SetIRVBit(myIRV, 0x02, 0x10, 0x00); //Normal IF ++ ++ ++ switch(Xtal_Freq_Hz) ++ { ++ case MxL_XTAL_16_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x00); //select xtal freq & Ref Freq ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x00); ++ break; ++ case MxL_XTAL_20_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x10); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x01); ++ break; ++ case MxL_XTAL_20_25_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x20); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x02); ++ break; ++ case MxL_XTAL_20_48_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x30); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x03); ++ break; ++ case MxL_XTAL_24_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x40); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x04); ++ break; ++ case MxL_XTAL_25_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x50); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x05); ++ break; ++ case MxL_XTAL_25_14_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x60); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x06); ++ break; ++ case MxL_XTAL_27_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x70); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x07); ++ break; ++ case MxL_XTAL_28_8_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x80); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x08); ++ break; ++ case MxL_XTAL_32_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x90); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x09); ++ break; ++ case MxL_XTAL_40_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xA0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0A); ++ break; ++ case MxL_XTAL_44_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xB0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0B); ++ break; ++ case MxL_XTAL_48_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xC0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0C); ++ break; ++ case MxL_XTAL_49_3811_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xD0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0D); ++ break; ++ } ++ ++ if(!Clk_Out_Enable) //default is enable ++ SetIRVBit(myIRV, 0x03, 0x08, 0x00); ++ ++ //Clk_Out_Amp ++ SetIRVBit(myIRV, 0x03, 0x07, Clk_Out_Amp); ++ ++ //Generate one Array that Contain Data, Address ++ while (myIRV[Reg_Index].Num || myIRV[Reg_Index].Val) ++ { ++ pArray[Array_Index++] = myIRV[Reg_Index].Num; ++ pArray[Array_Index++] = myIRV[Reg_Index].Val; ++ Reg_Index++; ++ } ++ ++ *Array_Size=Array_Index; ++ return 0; ++} ++ ++ ++UINT32 MxL5007_RFTune(UINT8* pArray, UINT32* Array_Size, UINT32 RF_Freq, UINT8 BWMHz) ++{ ++ IRVType IRV_RFTune[]= ++ { ++ //{ Addr, Data} ++ { 0x0F, 0x00}, //abort tune ++ { 0x0C, 0x15}, ++ { 0x0D, 0x40}, ++ { 0x0E, 0x0E}, ++ { 0x1F, 0x87}, //Override ++ { 0x20, 0x1F}, //Override ++ { 0x21, 0x87}, //Override ++ { 0x22, 0x1F}, //Override ++ { 0x80, 0x01}, //Freq Dependent Setting ++ { 0x0F, 0x01}, //start tune ++ { 0, 0} ++ }; ++ ++ UINT32 dig_rf_freq=0; ++ UINT32 temp; ++ UINT32 Reg_Index=0; ++ UINT32 Array_Index=0; ++ UINT32 i; ++ UINT32 frac_divider = 1000000; ++ ++ switch(BWMHz) ++ { ++ case MxL_BW_6MHz: //6MHz ++ SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x15); //set DIG_MODEINDEX, DIG_MODEINDEX_A, and DIG_MODEINDEX_CSF ++ break; ++ case MxL_BW_7MHz: //7MHz ++ SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x2A); ++ break; ++ case MxL_BW_8MHz: //8MHz ++ SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x3F); ++ break; ++ } ++ ++ ++ //Convert RF frequency into 16 bits => 10 bit integer (MHz) + 6 bit fraction ++ dig_rf_freq = RF_Freq / MHz; ++ temp = RF_Freq % MHz; ++ for(i=0; i<6; i++) ++ { ++ dig_rf_freq <<= 1; ++ frac_divider /=2; ++ if(temp > frac_divider) ++ { ++ temp -= frac_divider; ++ dig_rf_freq++; ++ } ++ } ++ ++ //add to have shift center point by 7.8124 kHz ++ if(temp > 7812) ++ dig_rf_freq ++; ++ ++ SetIRVBit(IRV_RFTune, 0x0D, 0xFF, (UINT8)dig_rf_freq); ++ SetIRVBit(IRV_RFTune, 0x0E, 0xFF, (UINT8)(dig_rf_freq>>8)); ++ ++ if (RF_Freq >=333*MHz) ++ SetIRVBit(IRV_RFTune, 0x80, 0x40, 0x40); ++ ++ //Generate one Array that Contain Data, Address ++ while (IRV_RFTune[Reg_Index].Num || IRV_RFTune[Reg_Index].Val) ++ { ++ pArray[Array_Index++] = IRV_RFTune[Reg_Index].Num; ++ pArray[Array_Index++] = IRV_RFTune[Reg_Index].Val; ++ Reg_Index++; ++ } ++ ++ *Array_Size=Array_Index; ++ ++ return 0; ++} ++ ++//local functions called by Init and RFTune ++UINT32 SetIRVBit(PIRVType pIRV, UINT8 Num, UINT8 Mask, UINT8 Val) ++{ ++ while (pIRV->Num || pIRV->Val) ++ { ++ if (pIRV->Num==Num) ++ { ++ pIRV->Val&=~Mask; ++ pIRV->Val|=Val; ++ } ++ pIRV++; ++ ++ } ++ return 0; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007_API.h ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007_API.c ++ ++ Version: 4.1.3 ++*/ ++ ++ ++//#include "StdAfx.h" ++//#include "MxL5007_API.h" ++//#include "MxL_User_Define.c" ++//#include "MxL5007.c" ++ ++ ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++// // ++// Tuner Functions // ++// // ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++MxL_ERR_MSG MxL_Set_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 RegData) ++{ ++ UINT32 Status=0; ++ UINT8 pArray[2]; ++ pArray[0] = RegAddr; ++ pArray[1] = RegData; ++// Status = MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2); ++ Status = MxL_I2C_Write(myTuner, pArray, 2); ++ if(Status) return MxL_ERR_SET_REG; ++ ++ return MxL_OK; ++ ++} ++ ++MxL_ERR_MSG MxL_Get_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 *RegData) ++{ ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, RegAddr, RegData)) ++ if(MxL_I2C_Read(myTuner, RegAddr, RegData)) ++ return MxL_ERR_GET_REG; ++ return MxL_OK; ++ ++} ++ ++MxL_ERR_MSG MxL_Soft_Reset(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT32 Status=0; ++ UINT8 reg_reset; ++ reg_reset = 0xFF; ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, ®_reset, 1)) ++ if(MxL_I2C_Write(myTuner, ®_reset, 1)) ++ return MxL_ERR_OTHERS; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Loop_Through_On(MxL5007_TunerConfigS* myTuner, MxL5007_LoopThru isOn) ++{ ++ UINT8 pArray[2]; // a array pointer that store the addr and data pairs for I2C write ++ ++ pArray[0]=0x04; ++ if(isOn) ++ pArray[1]= 0x01; ++ else ++ pArray[1]= 0x0; ++ ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2)) ++ if(MxL_I2C_Write(myTuner, pArray, 2)) ++ return MxL_ERR_OTHERS; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Stand_By(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 pArray[4]; // a array pointer that store the addr and data pairs for I2C write ++ ++ pArray[0] = 0x01; ++ pArray[1] = 0x0; ++ pArray[2] = 0x0F; ++ pArray[3] = 0x0; ++ ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 4)) ++ if(MxL_I2C_Write(myTuner, pArray, 4)) ++ return MxL_ERR_OTHERS; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Wake_Up(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 pArray[2]; // a array pointer that store the addr and data pairs for I2C write ++ ++ pArray[0] = 0x01; ++ pArray[1] = 0x01; ++ ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2)) ++ if(MxL_I2C_Write(myTuner, pArray, 2)) ++ return MxL_ERR_OTHERS; ++ ++ if(MxL_Tuner_RFTune(myTuner, myTuner->RF_Freq_Hz, myTuner->BW_MHz)) ++ return MxL_ERR_RFTUNE; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Tuner_Init(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 pArray[MAX_ARRAY_SIZE]; // a array pointer that store the addr and data pairs for I2C write ++ UINT32 Array_Size; // a integer pointer that store the number of element in above array ++ ++ //Soft reset tuner ++ if(MxL_Soft_Reset(myTuner)) ++ return MxL_ERR_INIT; ++ ++ //perform initialization calculation ++ MxL5007_Init(pArray, &Array_Size, (UINT8)myTuner->Mode, myTuner->IF_Diff_Out_Level, (UINT32)myTuner->Xtal_Freq, ++ (UINT32)myTuner->IF_Freq, (UINT8)myTuner->IF_Spectrum, (UINT8)myTuner->ClkOut_Setting, (UINT8)myTuner->ClkOut_Amp); ++ ++ //perform I2C write here ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size)) ++ if(MxL_I2C_Write(myTuner, pArray, Array_Size)) ++ return MxL_ERR_INIT; ++ ++ return MxL_OK; ++} ++ ++ ++MxL_ERR_MSG MxL_Tuner_RFTune(MxL5007_TunerConfigS* myTuner, UINT32 RF_Freq_Hz, MxL5007_BW_MHz BWMHz) ++{ ++ UINT32 Status=0; ++ UINT8 pArray[MAX_ARRAY_SIZE]; // a array pointer that store the addr and data pairs for I2C write ++ UINT32 Array_Size; // a integer pointer that store the number of element in above array ++ ++ //Store information into struc ++ myTuner->RF_Freq_Hz = RF_Freq_Hz; ++ myTuner->BW_MHz = BWMHz; ++ ++ //perform Channel Change calculation ++ MxL5007_RFTune(pArray,&Array_Size,RF_Freq_Hz,BWMHz); ++ ++ //perform I2C write here ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size)) ++ if(MxL_I2C_Write(myTuner, pArray, Array_Size)) ++ return MxL_ERR_RFTUNE; ++ ++ //wait for 3ms ++// MxL_Delay(3); ++ MxL_Delay(myTuner, 3); ++ ++ return MxL_OK; ++} ++ ++MxL5007_ChipVersion MxL_Check_ChipVersion(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 Data; ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD9, &Data)) ++ if(MxL_I2C_Read(myTuner, 0xD9, &Data)) ++ return MxL_GET_ID_FAIL; ++ ++ switch(Data) ++ { ++ case 0x14: return MxL_5007T_V4; break; ++ default: return MxL_UNKNOWN_ID; ++ } ++} ++ ++MxL_ERR_MSG MxL_RFSynth_Lock_Status(MxL5007_TunerConfigS* myTuner, BOOL* isLock) ++{ ++ UINT8 Data; ++ *isLock = MxL_FALSE; ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data)) ++ if(MxL_I2C_Read(myTuner, 0xD8, &Data)) ++ return MxL_ERR_OTHERS; ++ Data &= 0x0C; ++ if (Data == 0x0C) ++ *isLock = MxL_TRUE; //RF Synthesizer is Lock ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_REFSynth_Lock_Status(MxL5007_TunerConfigS* myTuner, BOOL* isLock) ++{ ++ UINT8 Data; ++ *isLock = MxL_FALSE; ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data)) ++ if(MxL_I2C_Read(myTuner, 0xD8, &Data)) ++ return MxL_ERR_OTHERS; ++ Data &= 0x03; ++ if (Data == 0x03) ++ *isLock = MxL_TRUE; //REF Synthesizer is Lock ++ return MxL_OK; ++} ++ ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,784 @@ ++#ifndef __TUNER_MXL5007T_H ++#define __TUNER_MXL5007T_H ++ ++/** ++ ++@file ++ ++@brief MxL5007T tuner module declaration ++ ++One can manipulate MxL5007T tuner through MxL5007T module. ++MxL5007T module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_mxl5007t.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build MxL5007T tuner module. ++ BuildMxl5007tModule( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0, // I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // Crystal frequency is 16.0 MHz. ++ MXL5007T_STANDARD_DVBT, // The MxL5007T standard mode is DVB-T. ++ IF_FREQ_4570000HZ, // The MxL5007T IF frequency is 4.57 MHz. ++ SPECTRUM_NORMAL, // The MxL5007T spectrum mode is normal. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0, // The MxL5007T clock output amplitude is 0. ++ 0 // The MxL5007T QAM IF differential output level is 0 for cable only. ++ ); ++ ++ ++ ++ ++ ++ // Get MxL5007T tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MXL5007T bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, MXL5007T_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MXL5007T bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is source code provided by MaxLinear. ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007_Common.h ++ ++ ++/******************************************************************************* ++ * ++ * FILE NAME : MxL_Common.h ++ * ++ * AUTHOR : Kyle Huang ++ * DATE CREATED : May 05, 2008 ++ * ++ * DESCRIPTION : ++ * ++ ******************************************************************************* ++ * Copyright (c) 2006, MaxLinear, Inc. ++ ******************************************************************************/ ++ ++//#ifndef __MXL5007_COMMON_H ++//#define __MXL5007_COMMON_H ++ ++ ++ ++/****************************************************************************** ++* User-Defined Types (Typedefs) ++******************************************************************************/ ++ ++ ++/**************************************************************************** ++* Imports and definitions for WIN32 ++****************************************************************************/ ++//#include ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++typedef char SINT8; ++typedef short SINT16; ++typedef int SINT32; ++//typedef float REAL32; ++ ++// Additional definition ++#define BOOL int ++#define MxL_FALSE 0 ++#define MxL_TRUE 1 ++ ++/****************************************************************************\ ++* Imports and definitions for non WIN32 platforms * ++\****************************************************************************/ ++/* ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++typedef char SINT8; ++typedef short SINT16; ++typedef int SINT32; ++typedef float REAL32; ++ ++// create a boolean ++#ifndef __boolean__ ++#define __boolean__ ++typedef enum {FALSE=0,TRUE} BOOL; ++#endif //boolean ++*/ ++ ++ ++/****************************************************************************\ ++* Definitions for all platforms * ++\****************************************************************************/ ++#ifndef NULL ++#define NULL (void*)0 ++#endif ++ ++ ++ ++/******************************/ ++/* MxL5007 Err message */ ++/******************************/ ++typedef enum{ ++ MxL_OK = 0, ++ MxL_ERR_INIT = 1, ++ MxL_ERR_RFTUNE = 2, ++ MxL_ERR_SET_REG = 3, ++ MxL_ERR_GET_REG = 4, ++ MxL_ERR_OTHERS = 10 ++}MxL_ERR_MSG; ++ ++/******************************/ ++/* MxL5007 Chip verstion */ ++/******************************/ ++typedef enum{ ++ MxL_UNKNOWN_ID = 0x00, ++ MxL_5007T_V4 = 0x14, ++ MxL_GET_ID_FAIL = 0xFF ++}MxL5007_ChipVersion; ++ ++ ++/****************************************************************************** ++ CONSTANTS ++******************************************************************************/ ++ ++#ifndef MHz ++ #define MHz 1000000 ++#endif ++ ++#define MAX_ARRAY_SIZE 100 ++ ++ ++// Enumeration of Mode ++// Enumeration of Mode ++typedef enum ++{ ++ MxL_MODE_ISDBT = 0, ++ MxL_MODE_DVBT = 1, ++ MxL_MODE_ATSC = 2, ++ MxL_MODE_CABLE = 0x10 ++} MxL5007_Mode ; ++ ++typedef enum ++{ ++ MxL_IF_4_MHZ = 4000000, ++ MxL_IF_4_5_MHZ = 4500000, ++ MxL_IF_4_57_MHZ = 4570000, ++ MxL_IF_5_MHZ = 5000000, ++ MxL_IF_5_38_MHZ = 5380000, ++ MxL_IF_6_MHZ = 6000000, ++ MxL_IF_6_28_MHZ = 6280000, ++ MxL_IF_9_1915_MHZ = 9191500, ++ MxL_IF_35_25_MHZ = 35250000, ++ MxL_IF_36_15_MHZ = 36150000, ++ MxL_IF_44_MHZ = 44000000 ++} MxL5007_IF_Freq ; ++ ++typedef enum ++{ ++ MxL_XTAL_16_MHZ = 16000000, ++ MxL_XTAL_20_MHZ = 20000000, ++ MxL_XTAL_20_25_MHZ = 20250000, ++ MxL_XTAL_20_48_MHZ = 20480000, ++ MxL_XTAL_24_MHZ = 24000000, ++ MxL_XTAL_25_MHZ = 25000000, ++ MxL_XTAL_25_14_MHZ = 25140000, ++ MxL_XTAL_27_MHZ = 27000000, ++ MxL_XTAL_28_8_MHZ = 28800000, ++ MxL_XTAL_32_MHZ = 32000000, ++ MxL_XTAL_40_MHZ = 40000000, ++ MxL_XTAL_44_MHZ = 44000000, ++ MxL_XTAL_48_MHZ = 48000000, ++ MxL_XTAL_49_3811_MHZ = 49381100 ++} MxL5007_Xtal_Freq ; ++ ++typedef enum ++{ ++ MxL_BW_6MHz = 6, ++ MxL_BW_7MHz = 7, ++ MxL_BW_8MHz = 8 ++} MxL5007_BW_MHz; ++ ++typedef enum ++{ ++ MxL_NORMAL_IF = 0 , ++ MxL_INVERT_IF ++ ++} MxL5007_IF_Spectrum ; ++ ++typedef enum ++{ ++ MxL_LT_DISABLE = 0 , ++ MxL_LT_ENABLE ++ ++} MxL5007_LoopThru ; ++ ++typedef enum ++{ ++ MxL_CLKOUT_DISABLE = 0 , ++ MxL_CLKOUT_ENABLE ++ ++} MxL5007_ClkOut; ++ ++typedef enum ++{ ++ MxL_CLKOUT_AMP_0 = 0 , ++ MxL_CLKOUT_AMP_1, ++ MxL_CLKOUT_AMP_2, ++ MxL_CLKOUT_AMP_3, ++ MxL_CLKOUT_AMP_4, ++ MxL_CLKOUT_AMP_5, ++ MxL_CLKOUT_AMP_6, ++ MxL_CLKOUT_AMP_7 ++} MxL5007_ClkOut_Amp; ++ ++typedef enum ++{ ++ MxL_I2C_ADDR_96 = 96 , ++ MxL_I2C_ADDR_97 = 97 , ++ MxL_I2C_ADDR_98 = 98 , ++ MxL_I2C_ADDR_99 = 99 ++} MxL5007_I2CAddr ; ++/* ++// ++// MxL5007 TunerConfig Struct ++// ++typedef struct _MxL5007_TunerConfigS ++{ ++ MxL5007_I2CAddr I2C_Addr; ++ MxL5007_Mode Mode; ++ SINT32 IF_Diff_Out_Level; ++ MxL5007_Xtal_Freq Xtal_Freq; ++ MxL5007_IF_Freq IF_Freq; ++ MxL5007_IF_Spectrum IF_Spectrum; ++ MxL5007_ClkOut ClkOut_Setting; ++ MxL5007_ClkOut_Amp ClkOut_Amp; ++ MxL5007_BW_MHz BW_MHz; ++ UINT32 RF_Freq_Hz; ++ ++ // Additional definition ++ TUNER_MODULE *pTuner; ++ ++} MxL5007_TunerConfigS; ++*/ ++ ++ ++ ++//#endif /* __MXL5007_COMMON_H__*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007.h ++ ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007.h ++ ++ */ ++ ++ ++//#include "MxL5007_Common.h" ++ ++ ++typedef struct ++{ ++ UINT8 Num; //Register number ++ UINT8 Val; //Register value ++} IRVType, *PIRVType; ++ ++ ++UINT32 MxL5007_Init(UINT8* pArray, // a array pointer that store the addr and data pairs for I2C write ++ UINT32* Array_Size, // a integer pointer that store the number of element in above array ++ UINT8 Mode, ++ SINT32 IF_Diff_Out_Level, ++ UINT32 Xtal_Freq_Hz, ++ UINT32 IF_Freq_Hz, ++ UINT8 Invert_IF, ++ UINT8 Clk_Out_Enable, ++ UINT8 Clk_Out_Amp ++ ); ++UINT32 MxL5007_RFTune(UINT8* pArray, UINT32* Array_Size, ++ UINT32 RF_Freq, // RF Frequency in Hz ++ UINT8 BWMHz // Bandwidth in MHz ++ ); ++UINT32 SetIRVBit(PIRVType pIRV, UINT8 Num, UINT8 Mask, UINT8 Val); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007.h ++ ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007_API.h ++ ++ */ ++//#ifndef __MxL5007_API_H ++//#define __MxL5007_API_H ++ ++//#include "MxL5007_Common.h" ++ ++/****************************************************************************** ++** ++** Name: MxL_Set_Register ++** ++** Description: Write one register to MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** RegAddr - Register address to be written ++** RegData - Data to be written ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_SET_REG if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Set_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 RegData); ++ ++/****************************************************************************** ++** ++** Name: MxL_Get_Register ++** ++** Description: Read one register from MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** RegAddr - Register address to be read ++** RegData - Pointer to register read ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_GET_REG if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Get_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 *RegData); ++ ++/****************************************************************************** ++** ++** Name: MxL_Tuner_Init ++** ++** Description: MxL5007 Initialization ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_INIT if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Tuner_Init(MxL5007_TunerConfigS* ); ++ ++/****************************************************************************** ++** ++** Name: MxL_Tuner_RFTune ++** ++** Description: Frequency tunning for channel ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** RF_Freq_Hz - RF Frequency in Hz ++** BWMHz - Bandwidth 6, 7 or 8 MHz ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_RFTUNE if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Tuner_RFTune(MxL5007_TunerConfigS*, UINT32 RF_Freq_Hz, MxL5007_BW_MHz BWMHz); ++ ++/****************************************************************************** ++** ++** Name: MxL_Soft_Reset ++** ++** Description: Software Reset the MxL5007 Tuner ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Soft_Reset(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_Loop_Through_On ++** ++** Description: Turn On/Off on-chip Loop-through ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** isOn - True to turn On Loop Through ++** - False to turn off Loop Through ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Loop_Through_On(MxL5007_TunerConfigS*, MxL5007_LoopThru); ++ ++/****************************************************************************** ++** ++** Name: MxL_Standby ++** ++** Description: Enter Standby Mode ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Stand_By(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_Wakeup ++** ++** Description: Wakeup from Standby Mode (Note: after wake up, please call RF_Tune again) ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Wake_Up(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_Check_ChipVersion ++** ++** Description: Return the MxL5007 Chip ID ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ChipVersion ++** ++******************************************************************************/ ++MxL5007_ChipVersion MxL_Check_ChipVersion(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_RFSynth_Lock_Status ++** ++** Description: RF synthesizer lock status of MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** isLock - Pointer to Lock Status ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_RFSynth_Lock_Status(MxL5007_TunerConfigS* , BOOL* isLock); ++ ++/****************************************************************************** ++** ++** Name: MxL_REFSynth_Lock_Status ++** ++** Description: REF synthesizer lock status of MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** isLock - Pointer to Lock Status ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_REFSynth_Lock_Status(MxL5007_TunerConfigS* , BOOL* isLock); ++ ++//#endif //__MxL5007_API_H ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MxL5007T tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Standard mode ++enum MXL5007T_STANDARD_MODE ++{ ++ MXL5007T_STANDARD_DVBT, ++ MXL5007T_STANDARD_ATSC, ++ MXL5007T_STANDARD_QAM, ++ MXL5007T_STANDARD_ISDBT, ++}; ++ ++ ++// Loop-through mode ++enum MXL5007T_LOOP_THROUGH_MODE ++{ ++ MXL5007T_LOOP_THROUGH_DISABLE = MxL_LT_DISABLE, ++ MXL5007T_LOOP_THROUGH_ENABLE = MxL_LT_ENABLE, ++}; ++ ++ ++// Clock output mode ++enum MXL5007T_CLK_OUT_MODE ++{ ++ MXL5007T_CLK_OUT_DISABLE, ++ MXL5007T_CLK_OUT_ENABLE, ++}; ++ ++ ++// Clock output amplitude mode ++enum MXL5007T_CLK_OUT_AMP_MODE ++{ ++ MXL5007T_CLK_OUT_AMP_0, ++ MXL5007T_CLK_OUT_AMP_1, ++ MXL5007T_CLK_OUT_AMP_2, ++ MXL5007T_CLK_OUT_AMP_3, ++ MXL5007T_CLK_OUT_AMP_4, ++ MXL5007T_CLK_OUT_AMP_5, ++ MXL5007T_CLK_OUT_AMP_6, ++ MXL5007T_CLK_OUT_AMP_7, ++}; ++ ++ ++// Bandwidth mode ++enum MXL5007T_BANDWIDTH_MODE ++{ ++ MXL5007T_BANDWIDTH_6000000HZ, ++ MXL5007T_BANDWIDTH_7000000HZ, ++ MXL5007T_BANDWIDTH_8000000HZ, ++}; ++ ++ ++ ++// Constant ++#define MXL5007T_I2C_READING_CONST 0xfb ++ ++// Default value ++#define MXL5007T_RF_FREQ_HZ_DEFAULT 44000000; ++#define MXL5007T_BANDWIDTH_MODE_DEFAULT MxL_BW_6MHz; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMxl5007tModule( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int SpectrumMode, ++ int LoopThroughMode, ++ int ClkOutMode, ++ int ClkOutAmpMode, ++ long QamIfDiffOutLevel ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++mxl5007t_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++mxl5007t_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++mxl5007t_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mxl5007t_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++mxl5007t_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++mxl5007t_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++mxl5007t_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_tua9001.c linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_tua9001.c +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_tua9001.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_tua9001.c 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,1245 @@ ++/** ++ ++@file ++ ++@brief TUA9001 tuner module definition ++ ++One can manipulate TUA9001 tuner through TUA9001 module. ++TUA9001 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_tua9001.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief TUA9001 tuner module builder ++ ++Use BuildTua9001Module() to build TUA9001 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to TUA9001 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr TUA9001 I2C device address ++ ++ ++@note ++ -# One should call BuildTua9001Module() to build TUA9001 module before using it. ++ ++*/ ++void ++BuildTua9001Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_TUA9001; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ // Initialize tuner module variables. ++ // Note: Need to give both RF frequency and bandwidth for TUA9001 tuning function, ++ // so we have to give a default RF frequncy. ++ pTuner->RfFreqHz = TUA9001_RF_FREQ_HZ_DEFAULT; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = tua9001_GetTunerType; ++ pTuner->GetDeviceAddr = tua9001_GetDeviceAddr; ++ ++ pTuner->Initialize = tua9001_Initialize; ++ pTuner->SetRfFreqHz = tua9001_SetRfFreqHz; ++ pTuner->GetRfFreqHz = tua9001_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ // Note: Need to give both RF frequency and bandwidth for TUA9001 tuning function, ++ // so we have to give a default bandwidth. ++ pExtra->BandwidthMode = TUA9001_BANDWIDTH_MODE_DEFAULT; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = tua9001_SetBandwidthMode; ++ pExtra->GetBandwidthMode = tua9001_GetBandwidthMode; ++ pExtra->GetRegBytesWithRegAddr = tua9001_GetRegBytesWithRegAddr; ++ pExtra->SetSysRegByte = tua9001_SetSysRegByte; ++ pExtra->GetSysRegByte = tua9001_GetSysRegByte; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++tua9001_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++tua9001_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++tua9001_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Initialize TUA9001 tuner. ++ if(initializeTua9001(pTuner) != TUA9001_TUNER_OK) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++tua9001_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ long RfFreqKhz; ++ int BandwidthMode; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get bandwidth mode. ++ BandwidthMode = pExtra->BandwidthMode; ++ ++ // Calculate RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (long)((RfFreqHz + 500) / 1000); ++ ++ // Set TUA9001 RF frequency and bandwidth. ++ if(tuneTua9001(pTuner, RfFreqKhz, BandwidthMode) != TUA9001_TUNER_OK) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = (unsigned long)(RfFreqKhz * 1000); ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++tua9001_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set TUA9001 tuner bandwidth mode. ++ ++*/ ++int ++tua9001_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get RF frequncy in KHz. ++ // Note: Doesn't need to take round() of RfFreqHz, because its value unit is 1000 Hz. ++ RfFreqKhz = (long)(pTuner->RfFreqHz / 1000); ++ ++ // Set TUA9001 RF frequency and bandwidth. ++ if(tuneTua9001(pTuner, RfFreqKhz, BandwidthMode) != TUA9001_TUNER_OK) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get TUA9001 tuner bandwidth mode. ++ ++*/ ++int ++tua9001_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ // Get tuner bandwidth in Hz from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get register bytes with address. ++ ++*/ ++int ++tua9001_GetRegBytesWithRegAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ // Get tuner register byte. ++ //if(rtl2832usb_ReadWithRegAddr(DeviceAddr, RegAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ // goto error_status_get_tuner_registers_with_address; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char TunerDeviceAddr; ++ ++ struct dvb_usb_device *d; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner,&TunerDeviceAddr); ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ if( read_rtl2832_tuner_register( d, TunerDeviceAddr, RegAddr, pReadingBytes, ByteNum ) ) ++ goto error_status_get_tuner_registers_with_address; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers_with_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set system register byte. ++ ++*/ ++int ++tua9001_SetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char WritingByte ++ ) ++{ ++ // Set demod system register byte. ++// if(RTK_SYS_Byte_Write(RegAddr, LEN_1_BYTE, &WritingByte) != TRUE) ++// goto error_status_set_system_registers; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ if ( write_usb_sys_char_bytes( d, RTD2832U_SYS, RegAddr, &WritingByte, LEN_1_BYTE) ) ++ goto error_status_set_system_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_system_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get system register byte. ++ ++*/ ++int ++tua9001_GetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char *pReadingByte ++ ) ++{ ++ // Get demod system register byte. ++// if(RTK_SYS_Byte_Read(RegAddr, LEN_1_BYTE, pReadingByte) != TRUE) ++// goto error_status_get_system_registers; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ if ( read_usb_sys_char_bytes(d, RTD2832U_SYS, RegAddr, pReadingByte, LEN_1_BYTE) ) ++ goto error_status_get_system_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_system_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// TUA9001 custom-implement functions ++ ++ ++int tua9001setRESETN (TUNER_MODULE *pTuner, unsigned int i_state) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ unsigned char Byte; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get GPO value. ++ ++ if(pExtra->GetSysRegByte(pTuner, GPO_ADDR, &Byte) != FUNCTION_SUCCESS) ++ goto error_status_get_system_registers; ++ ++ // Note: Hardware PCB has inverter in this pin, should give inverted value on GPIO3. ++ if (i_state == TUA9001_H_LEVEL) ++ { ++ /* set tuner RESETN pin to "H" */ ++ // Note: The GPIO3 output value should be '0'. ++ Byte &= ~BIT_3_MASK; ++ } ++ else ++ { ++ /* set tuner RESETN pin to "L" */ ++ // Note: The GPIO3 output value should be '1'. ++ Byte |= BIT_3_MASK; ++ } ++ ++ // Set GPO value. ++ if(pExtra->SetSysRegByte(pTuner, GPO_ADDR, Byte) != FUNCTION_SUCCESS) ++ goto error_status_set_system_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_system_registers: ++error_status_get_system_registers: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++int tua9001setRXEN (TUNER_MODULE *pTuner, unsigned int i_state) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ unsigned char Byte; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get GPO value. ++ if(pExtra->GetSysRegByte(pTuner, GPO_ADDR, &Byte) != FUNCTION_SUCCESS) ++ goto error_status_get_system_registers; ++ ++ if (i_state == TUA9001_H_LEVEL) ++ { ++ /* set tuner RXEN pin to "H" */ ++ // Note: The GPIO1 output value should be '1'. ++ Byte |= BIT_1_MASK; ++ } ++ else ++ { ++ /* set tuner RXEN pin to "L" */ ++ // Note: The GPIO1 output value should be '0'. ++ Byte &= ~BIT_1_MASK; ++ } ++ ++ // Set GPO value. ++ if(pExtra->SetSysRegByte(pTuner, GPO_ADDR, Byte) != FUNCTION_SUCCESS) ++ goto error_status_set_system_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_system_registers: ++error_status_get_system_registers: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++int tua9001setCEN (TUNER_MODULE *pTuner, unsigned int i_state) ++{ ++ // Do nothing. ++ // Note: Hardware PCB always gives 'H' to tuner CEN pin. ++ return TUA9001_TUNER_OK; ++} ++ ++ ++ ++int tua9001waitloop (TUNER_MODULE *pTuner, unsigned int i_looptime) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ unsigned long WaitTimeMs; ++ ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ /* wait time = i_looptime * 1 uS */ ++ // Note: 1. The unit of WaitMs() function is ms. ++ // 2. WaitTimeMs = ceil(i_looptime / 1000) ++ WaitTimeMs = i_looptime / 1000; ++ ++ if((i_looptime % 1000) > 0) ++ WaitTimeMs += 1; ++ ++ pBaseInterface->WaitMs(pBaseInterface, WaitTimeMs); ++ ++ ++ return TUA9001_TUNER_OK; ++} ++ ++ ++ ++int tua9001i2cBusWrite (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length) ++{ ++ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char ByteNum; ++ unsigned char WritingBytes[I2C_BUFFER_LEN]; ++ unsigned int i; ++ ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ /* I2C write data format */ ++ /* STA device_address ACK register_address ACK H_Byte-Data ACK L_Byte-Data !ACK STO */ ++ ++ /* STA = start condition, ACK = Acknowledge, STO = stop condition */ ++ /* *data = pointer to data source */ ++ /* length = number of bytes to write */ ++ ++ // Determine byte number. ++ ByteNum = length + LEN_1_BYTE; ++ ++ // Determine writing bytes. ++ WritingBytes[0] = registerAddress; ++ ++ for(i = 0; i < length; i++) ++ WritingBytes[LEN_1_BYTE + i] = data[i]; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, deviceAddress, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_tuner_registers: ++ return TUA9001_TUNER_ERR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char ByteNum; ++ unsigned char WritingBytes[I2C_BUFFER_LEN]; ++ unsigned int i=0; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ // Determine byte number. ++ ByteNum = length; ++ ++ // Determine writing bytes. ++ //WritingBytes[0] = registerAddress; ++ ++ for(i = 0; i < length; i++) ++ WritingBytes[i] = data[i]; ++ ++ // Send I2C writing command. ++ if( write_rtl2832_tuner_register( d, deviceAddress, registerAddress, WritingBytes, ByteNum ) ) ++ goto error_status_set_tuner_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_tuner_registers: ++ return TUA9001_TUNER_ERR; ++ ++} ++ ++ ++ ++int tua9001i2cBusRead (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ /* I2C read data format */ ++ /* STA device_address ACK register_address ACK STA H_Byte-Data ACK device_address_read ACK H_Byte-Data ACK L_Byte-Data ACKH STO */ ++ ++ /* STA = start condition, ACK = Acknowledge (generated by TUA9001), ACKH = Acknowledge (generated by Host), STO = stop condition */ ++ /* *data = pointer to data destination */ ++ /* length = number of bytes to read */ ++ ++ // Get tuner register bytes with address. ++ // Note: We must use re-start I2C reading format for TUA9001 tuner register reading. ++ if(pExtra->GetRegBytesWithRegAddr(pTuner, deviceAddress, registerAddress, data, length) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_get_tuner_registers: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Infineon. ++ ++ ++ ++ ++ ++// Infineon source code - driver_tua9001.c ++ ++ ++/* ============================================================================ ++** Copyright (C) 1997-2007 Infineon AG All rights reserved. ++** ============================================================================ ++** ++** ============================================================================ ++** Revision Information : ++** File name: driver_tua9001.c ++** Version: V 1.01 ++** Date: ++** ++** ============================================================================ ++** History: ++** ++** Date Author Comment ++** ---------------------------------------------------------------------------- ++** ++** 2007.11.06 Walter Pichler created. ++** 2008.04.08 Walter Pichler adaption to TUA 9001E ++** ++** ============================================================================ ++*/ ++ ++/*============================================================================ ++Includes ++============================================================================*/ ++ ++//#include "driver_tua9001.h" ++//#include "driver_tua9001_NeededFunctions.h" /* Note: This function have to be provided by the user */ ++ ++/*============================================================================ ++Local compiler keeys ( usage depends on the application ) ++============================================================================*/ ++ ++#define CRYSTAL_26_0_MHZ ++//#define CRYSTAL_19_2_MHZ ++//#define CRYSTAL_20_48_MHZ ++ ++//#define AGC_BY_IIC ++//#define AGC_BY_AGC_BUS ++#define AGC_BY_EXT_PIN ++ ++ ++/*============================================================================ ++Named Constants Definitions ( usage depends on the application ) ++============================================================================*/ ++ ++#define TUNERs_TUA9001_DEVADDR 0xC0 ++ ++/* Note: The correct device address depends hardware settings. See Datasheet ++ and User Manual for details. */ ++ ++/*============================================================================ ++Local Named Constants Definitions ++============================================================================*/ ++#define OPERATIONAL_MODE 0x03 ++#define CHANNEL_BANDWITH 0x04 ++#define SW_CONTR_TIME_SLICING 0x05 ++#define BASEBAND_GAIN_CONTROL 0x06 ++#define MANUAL_BASEBAND_GAIN 0x0b ++#define REFERENCE_FREQUENCY 0x1d ++#define CHANNEL_WORD 0x1f ++#define CHANNEL_OFFSET 0x20 ++#define CHANNEL_FILTER_TRIMMING 0x2f ++#define OUTPUT_BUFFER 0x32 ++#define RF_AGC_CONFIG_A 0x36 ++#define RF_AGC_CONFIG_B 0x37 ++#define UHF_LNA_SELECT 0x39 ++#define LEVEL_DETECTOR 0x3a ++#define MIXER_CURRENT 0x3b ++#define PORT_CONTROL 0x3e ++#define CRYSTAL_TRIMMING 0x41 ++#define CHANNEL_FILTER_STATUS 0x60 ++#define SIG_STRENGHT_INDICATION 0x62 ++#define PLL_LOCK 0x69 ++#define RECEIVER_STATE 0x70 ++#define RF_INPUT 0x71 ++#define BASEBAND_GAIN 0x72 ++#define CHIP_IDENT_CODE 0x7e ++#define CHIP_REVISION 0x7f ++ ++#define TUNERs_TUA9001_BW_8 0xcf ++#define TUNERs_TUA9001_BW_7 0x10 ++#define TUNERs_TUA9001_BW_6 0x20 ++#define TUNERs_TUA9001_BW_5 0x30 ++ ++ ++ ++ ++/*============================================================================ ++ Types definition ++============================================================================*/ ++ ++ ++ ++ ++/*============================================================================ ++ Public Functions ++============================================================================*/ ++ ++ ++/** ++ * tuner initialisation ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int initializeTua9001 (TUNER_MODULE *pTuner) ++{ ++// unsigned int counter; ++ char i2cseq[2]; ++// tua9001tunerReceiverState_t tunerState; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ /* Note: CEN may also be hard wired in the application*/ ++ if(tua9001setCEN (pTuner, TUA9001_H_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* asserting Chip enable */ ++ ++ if(tua9001setRESETN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* asserting RESET */ ++ ++ if(tua9001setRXEN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* RXEN to low >> IDLE STATE */ ++ ++ /* Note: 20ms assumes that all external power supplies are settled. If not, add more time here */ ++ tua9001waitloop (pTuner, 20); /* wait for 20 uS */ ++ ++ if(tua9001setRESETN (pTuner, TUA9001_H_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* de-asserting RESET */ ++ ++ /* This is to wait for the Crystal Oscillator to settle .. wait until IDLE mode is reached */ ++// counter = 6; ++// do ++// { ++// counter --; ++// tua9001waitloop (pTuner, 1000); /* wait for 1 mS */ ++// if(getReceiverStateTua9001 (pTuner, &tunerState) != TUA9001_TUNER_OK) goto error_status; ++// }while ((tunerState != TUA9001_IDLE) && (counter)); ++ ++// if (tunerState != TUA9001_IDLE) ++// return TUA9001_TUNER_ERR; /* error >> break initialization */ ++ ++ // Replace the above check loop with 6 ms delay. ++ // Because maybe there are undefined cases in getReceiverStateTua9001(), we have to avoid using the function. ++ tua9001waitloop (pTuner, 6000); /* wait for 6 mS */ ++ ++ /**** Overwrite default register value ****/ ++ i2cseq[0] = 0x65; /* Waiting time before PLL cal. start */ ++ i2cseq[1] = 0x12; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1e, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0xB8; /* VCO Varactor bias fine tuning */ ++ i2cseq[1] = 0x88; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x25, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x54; /* LNA switching Threshold for UHF1/2 */ ++ i2cseq[1] = 0x60; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x39, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; ++ i2cseq[1] = 0xC0; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x3b, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0xF0; /* LO- Path Set LDO output voltage */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x3a, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* Set EXTAGC interval */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x08, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* Set max. capacitive load */ ++ i2cseq[1] = 0x30; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x32, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ ++ /**** Set Crystal Reference Frequency an Trim value ****/ ++ ++#if defined(CRYSTAL_26_0_MHZ) // Frequency 26 MHz ++ i2cseq[0] = 0x01; ++ i2cseq[1] = 0xB0; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x70; // NDK 3225 series 26 MHz XTAL ++ i2cseq[1] = 0x3a; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x41, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ i2cseq[0] = 0x1C; ++ i2cseq[1] = 0x78; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x40, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++#elif defined(CRYSTAL_19_2_MHZ) // Frequency 19.2 MHz ++ i2cseq[0] = 0x01; ++ i2cseq[1] = 0xA0; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ // Note: Insert optimised register values for 0x40 / 0x41 for used crystal ++ // contact application support for further information ++#elif defined(CRYSTAL_20_48_MHZ) // Frequency 20,48 MHz ++ i2cseq[0] = 0x01; ++ i2cseq[1] = 0xA8; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ // Note: Insert optimised register values for 0x40 / 0x41 for used crystal ++ // contact application support for further information ++#endif ++ ++ ++ ++ /**** Set desired Analog Baseband AGC mode ****/ ++#if defined (AGC_BY_IIC) ++ i2cseq[0] = 0x00; /* Bypass AGC controller >> IIC based AGC */ ++ i2cseq[1] = 0x40; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++#elif defined(AGC_BY_AGC_BUS) ++ i2cseq[0] = 0x00; /* Digital AGC bus */ ++ i2cseq[1] = 0x00; /* 0,5 dB steps */ ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++#elif defined(AGC_BY_EXT_PIN) ++ i2cseq[0] = 0x40; /* Ext. AGC pin */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++#endif ++ ++ ++ /**** set desired RF AGC parameter *****/ ++ i2cseq[0] = 0x1c; /* Set Wideband Detector Current (100 uA) */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x2c, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0xC0; /* Set RF AGC Threshold (-32.5dBm) */ ++ i2cseq[1] = 0x13; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x36, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x6f; /* RF AGC Parameter */ ++ i2cseq[1] = 0x18; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x37, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* aditional VCO settings */ ++ i2cseq[1] = 0x08; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x27, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* aditional PLL settings */ ++ i2cseq[1] = 0x01; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x2a, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x0a; /* VCM correction */ ++ i2cseq[1] = 0x40; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x34, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++/** ++ * tuner tune ++ * @param i_freq tuning frequency ++ * @param i_bandwidth channel bandwidth ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tuneTua9001 (TUNER_MODULE *pTuner, long i_freq, tua9001tunerDriverBW_t i_bandwidth) ++{ ++ char i2cseq[2]; ++ unsigned int divider_factor; ++ unsigned int ch_offset; ++// unsigned int counter; ++ unsigned int lo_path_settings; ++// tua9001tunerReceiverState_t tunerState; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ ++ /* de-assert RXEN >> IDLE STATE */ ++ if(tua9001setRXEN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; ++ ++ ++ /* calculate divider factor */ ++ if (i_freq < 1000000) /* divider factor and channel offset for UHF/VHF III */ ++ { ++ ch_offset = 0x1C20; /* channel offset 150 MHz */ ++ divider_factor = (unsigned int) (((i_freq - 150000) * 48) / 1000); ++ lo_path_settings = 0xb6de; ++ } ++ ++ else /* calculate divider factor for L-Band Frequencies */ ++ { ++ ch_offset = 0x5460; /* channel offset 450 MHz */ ++ divider_factor = (unsigned int) (((i_freq - 450000) * 48) / 1000); ++ lo_path_settings = 0xbede; ++ } ++ ++ ++ // Set LO Path ++ i2cseq[0] = lo_path_settings >> 8; ++ i2cseq[1] = lo_path_settings & 0xff; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x2b, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ // Set channel offset ++ i2cseq [0] = ch_offset >> 8; ++ i2cseq [1] = ch_offset & 0xff; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x20, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ // Set Frequency ++ i2cseq [0] = divider_factor >> 8; ++ i2cseq [1] = divider_factor & 0xff; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1f, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ // Set bandwidth ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x04, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; /* get current register value */ ++ i2cseq [0] &= TUNERs_TUA9001_BW_8; ++ ++ switch (i_bandwidth) ++ { ++ case TUA9001_TUNER_BANDWIDTH_8MHZ: ++ // Do nothing. ++ break; ++ case TUA9001_TUNER_BANDWIDTH_7MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_7; ++ break; ++ case TUA9001_TUNER_BANDWIDTH_6MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_6; ++ break; ++ case TUA9001_TUNER_BANDWIDTH_5MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_5; ++ break; ++ default: ++ goto error_status; ++ break; ++ } ++ ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x04, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ /* assert RXEN >> RX STATE */ ++ if(tua9001setRXEN (pTuner, TUA9001_H_LEVEL) != TUA9001_TUNER_OK) goto error_status; ++ ++ /* This is to wait for the RX state to settle .. wait until RX mode is reached */ ++// counter = 3; ++// do ++// { ++// counter --; ++// tua9001waitloop (pTuner, 1000); /* wait for 1 mS */ ++// if(getReceiverStateTua9001 (pTuner, &tunerState) != TUA9001_TUNER_OK) goto error_status; ++// }while ((tunerState != TUA9001_RX) && (counter)); ++ ++// if (tunerState != TUA9001_RX) ++// { ++// if(tua9001setRXEN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* d-assert RXEN >> IDLE STATE */ ++// return TUA9001_TUNER_ERR; /* error >> tuning fail */ ++// } ++ ++ // Replace the above check loop with 3 ms delay. ++ // Because maybe there are undefined cases in getReceiverStateTua9001(), we have to avoid using the function. ++ tua9001waitloop (pTuner, 3000); /* wait for 3 mS */ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++/** ++ * Get pll locked state ++ * @param o_pll pll locked state ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int getPllLockedStateTua9001 (TUNER_MODULE *pTuner, tua9001tunerPllLocked_t *o_pll) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x69, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; /* get current register value */ ++ ++ o_pll[0] = (i2cseq[1] & 0x08) ? TUA9001_PLL_LOCKED : TUA9001_PLL_NOT_LOCKED; ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++/** ++ * Get tuner state ++ * @param o_tunerState tuner state ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++/* ++int getReceiverStateTua9001 (TUNER_MODULE *pTuner, tua9001tunerReceiverState_t *o_tunerState) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x70, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; // get current register value ++ ++// switch (i2cseq[1] & ~0x1f) ++ // Note: Maybe the MSB byte is i2cseq[0] ++ // The original code looks like the MSB byte is i2cseq[1] ++ // Note: ~0x1f = 0xffffffe0, not 0xe0 --> i2cseq[0] & ~0x1f result is wrong. ++ switch (i2cseq[0] & 0xe0) ++ { ++ case 0x80: o_tunerState [0] = TUA9001_IDLE; break; ++ case 0x40: o_tunerState [0] = TUA9001_RX; break; ++ case 0x20: o_tunerState [0] = TUA9001_STANDBY; break; ++ default: goto error_status; break; ++ } ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++*/ ++ ++/** ++ * Get active input ++ * @param o_activeInput active input info ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++/* ++int getActiveInputTua9001 (TUNER_MODULE *pTuner, tua9001tunerActiveInput_t *o_activeInput) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x71, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; // get current register value ++ ++// switch (i2cseq[1] & ~0x0f) ++ // Note: Maybe the MSB byte is i2cseq[0] ++ // The original code looks like the MSB byte is i2cseq[1] ++ // Note: ~0x0f = 0xfffffff0, not 0xf0 --> i2cseq[0] & ~0x0f result is wrong. ++ switch (i2cseq[0] & 0xf0) ++ { ++ case 0x80: o_activeInput [0] = TUA9001_L_INPUT_ACTIVE; break; ++ case 0x20: o_activeInput [0] = TUA9001_UHF_INPUT_ACTIVE; break; ++ case 0x10: o_activeInput [0] = TUA9001_VHF_INPUT_ACTIVE; break; ++ default: goto error_status; break; ++ } ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++*/ ++ ++/** ++ * Get baseband gain value ++ * @param o_basebandGain baseband gain value ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int getBasebandGainTua9001 (TUNER_MODULE *pTuner, char *o_basebandGain) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x72, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; /* get current register value */ ++// o_basebandGain [0] = i2cseq [1]; ++ // Note: Maybe the MSB byte is i2cseq[0] ++ // The original code looks like the MSB byte is i2cseq[1] ++ o_basebandGain [0] = i2cseq [0]; ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_tua9001.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_tua9001.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/tuner_tua9001.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/tuner_tua9001.h 2010-10-27 08:17:28.000000000 +0200 +@@ -0,0 +1,493 @@ ++#ifndef __TUNER_TUA9001_H ++#define __TUNER_TUA9001_H ++ ++/** ++ ++@file ++ ++@brief TUA9001 tuner module declaration ++ ++One can manipulate TUA9001 tuner through TUA9001 module. ++TUA9001 module is derived from tunerd module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_tua9001.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ TUA9001_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ int BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build TUA9001 tuner module. ++ BuildTua9001Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0 // I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get TUA9001 tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set TUA9001 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, TUA9001_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get TUA9001 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "tuner_base.h" ++//#include "i2c_rtl2832usb.h" ++ ++ ++ ++ ++ ++// The following context is source code provided by Infineon. ++ ++ ++ ++ ++ ++// Infineon source code - driver_tua9001.h ++ ++ ++ ++/* ============================================================================ ++** Copyright (C) 1997-2007 Infineon AG All rights reserved. ++** ============================================================================ ++** ++** ============================================================================ ++** Revision Information : ++** File name: driver_tua9001.h ++** Version: ++** Date: ++** ++** ============================================================================ ++** History: ++** ++** Date Author Comment ++** ---------------------------------------------------------------------------- ++** ++** 2007.11.06 Walter Pichler created. ++** ============================================================================ ++*/ ++ ++ ++/*============================================================================ ++ Named Constants Definitions ++============================================================================*/ ++ ++#define TUA9001_TUNER_OK 0 ++#define TUA9001_TUNER_ERR 0xff ++ ++#define TUA9001_H_LEVEL 1 ++#define TUA9001_L_LEVEL 0 ++ ++ ++/*============================================================================ ++ Types definition ++============================================================================*/ ++ ++ ++typedef enum { ++ TUA9001_TUNER_BANDWIDTH_8MHZ, ++ TUA9001_TUNER_BANDWIDTH_7MHZ, ++ TUA9001_TUNER_BANDWIDTH_6MHZ, ++ TUA9001_TUNER_BANDWIDTH_5MHZ, ++ } tua9001tunerDriverBW_t; ++ ++ ++typedef enum { ++ TUA9001_PLL_LOCKED, ++ TUA9001_PLL_NOT_LOCKED ++ }tua9001tunerPllLocked_t; ++ ++ ++typedef enum { ++ TUA9001_STANDBY, ++ TUA9001_IDLE, ++ TUA9001_RX ++ } tua9001tunerReceiverState_t; ++ ++ ++typedef enum { ++ TUA9001_L_INPUT_ACTIVE, ++ TUA9001_UHF_INPUT_ACTIVE, ++ TUA9001_VHF_INPUT_ACTIVE ++ } tua9001tunerActiveInput_t; ++ ++ ++ ++/*============================================================================ ++ Public functions ++============================================================================*/ ++ ++/** ++ * tuner initialisation ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int initializeTua9001 (TUNER_MODULE *pTuner); ++ ++ ++/** ++ * tuner tune ++ * @param i_freq tuning frequency ++ * @param i_bandwidth channel bandwidth ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int tuneTua9001 (TUNER_MODULE *pTuner, long i_freq, tua9001tunerDriverBW_t i_bandwidth); ++ ++ ++/** ++ * Get tuner state ++ * @param o_tunerState tuner state ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int getReceiverStateTua9001 (TUNER_MODULE *pTuner, tua9001tunerReceiverState_t *o_tunerState); ++ ++/** ++ * Get active input ++ * @param o_activeInput active input info ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int getActiveInputTua9001 (TUNER_MODULE *pTuner, tua9001tunerActiveInput_t *o_activeInput); ++ ++ ++/** ++ * Get baseband gain value ++ * @param o_basebandGain baseband gain value ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int getBasebandGainTua9001 (TUNER_MODULE *pTuner, char *o_basebandGain); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Infineon source code - driver_tua9001_NeededFunctions.h ++ ++ ++ ++/*======================================================================================================================== ++ additional needed external funtions ( have to be provided by the user! ) ++========================================================================================================================*/ ++ ++/** ++ * set / reset tuner reset input ++ * @param i_state level ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001setRESETN (TUNER_MODULE *pTuner, unsigned int i_state); ++ ++ ++/** ++ * set / reset tuner receive enable input ++ * @param i_state level ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001setRXEN (TUNER_MODULE *pTuner, unsigned int i_state); ++ ++ ++/** ++ * set / reset tuner chiop enable input ++ * @param i_state level ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001setCEN (TUNER_MODULE *pTuner, unsigned int i_state); ++ ++ ++/** ++ * waitloop ++ * @param i_looptime * 1uS ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001waitloop (TUNER_MODULE *pTuner, unsigned int i_looptime); ++ ++ ++/** ++ * i2cBusWrite ++ * @param deviceAdress chip address ++ * @param registerAdress register address ++ * @param *data pointer to data source ++ * @param length number of bytes to transmit ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++ int tua9001i2cBusWrite (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length); ++ ++ ++/** ++ * i2cBusRead ++ * @param deviceAdress chip address ++ * @param registerAdress register address ++ * @param *data pointer to data destination ++ * @param length number of bytes to read ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++ int tua9001i2cBusRead (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length); ++ ++/*======================================================================================================================== ++ end of additional needed external funtions ++========================================================================================================================*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is TUA9001 tuner API source code ++ ++ ++ ++ ++ ++/** ++ ++@file ++ ++@brief TUA9001 tuner module declaration ++ ++One can manipulate TUA9001 tuner through TUA9001 module. ++TUA9001 module is derived from tuner module. ++ ++*/ ++ ++ ++ ++ ++ ++// Definitions ++ ++// Constant ++#define GPO_ADDR 0x1 ++ ++// Bandwidth modes ++enum TUA9001_BANDWIDTH_MODE ++{ ++ TUA9001_BANDWIDTH_5MHZ = TUA9001_TUNER_BANDWIDTH_5MHZ, ++ TUA9001_BANDWIDTH_6MHZ = TUA9001_TUNER_BANDWIDTH_6MHZ, ++ TUA9001_BANDWIDTH_7MHZ = TUA9001_TUNER_BANDWIDTH_7MHZ, ++ TUA9001_BANDWIDTH_8MHZ = TUA9001_TUNER_BANDWIDTH_8MHZ, ++}; ++ ++// Default value ++#define TUA9001_RF_FREQ_HZ_DEFAULT 50000000; ++#define TUA9001_BANDWIDTH_MODE_DEFAULT TUA9001_BANDWIDTH_5MHZ; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildTua9001Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++tua9001_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++tua9001_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++tua9001_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++tua9001_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++tua9001_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++tua9001_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++tua9001_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++int ++tua9001_GetRegBytesWithRegAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ); ++ ++int ++tua9001_SetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char WritingByte ++ ); ++ ++int ++tua9001_GetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif diff --git a/projects/ATV/linux/linux.i386.conf b/projects/ATV/linux/linux.i386.conf index 0c4fe1fe31..115bc522c6 100644 --- a/projects/ATV/linux/linux.i386.conf +++ b/projects/ATV/linux/linux.i386.conf @@ -98,7 +98,6 @@ CONFIG_IRQ_FORCED_THREADING=y # RCU Subsystem # CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set # CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 @@ -1419,6 +1418,7 @@ CONFIG_DVB_USB_DW2102=m # CONFIG_DVB_USB_CINERGY_T2 is not set CONFIG_DVB_USB_ANYSEE=m # CONFIG_DVB_USB_DTV5100 is not set +CONFIG_DVB_USB_RTL2832U=m CONFIG_DVB_USB_AF9015=m # CONFIG_DVB_USB_CE6230 is not set # CONFIG_DVB_USB_FRIIO is not set diff --git a/projects/Fusion/linux/linux.i386.conf b/projects/Fusion/linux/linux.i386.conf index f91ab5f6a6..15ffb52772 100644 --- a/projects/Fusion/linux/linux.i386.conf +++ b/projects/Fusion/linux/linux.i386.conf @@ -99,7 +99,6 @@ CONFIG_IRQ_FORCED_THREADING=y # RCU Subsystem # CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set # CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 @@ -1589,6 +1588,7 @@ CONFIG_DVB_USB_DW2102=m # CONFIG_DVB_USB_CINERGY_T2 is not set CONFIG_DVB_USB_ANYSEE=m # CONFIG_DVB_USB_DTV5100 is not set +CONFIG_DVB_USB_RTL2832U=m CONFIG_DVB_USB_AF9015=m # CONFIG_DVB_USB_CE6230 is not set # CONFIG_DVB_USB_FRIIO is not set diff --git a/projects/Generic/linux/linux.i386.conf b/projects/Generic/linux/linux.i386.conf index 43a4e7e939..d9875c3300 100644 --- a/projects/Generic/linux/linux.i386.conf +++ b/projects/Generic/linux/linux.i386.conf @@ -1765,6 +1765,7 @@ CONFIG_DVB_USB_DW2102=m # CONFIG_DVB_USB_CINERGY_T2 is not set CONFIG_DVB_USB_ANYSEE=m # CONFIG_DVB_USB_DTV5100 is not set +CONFIG_DVB_USB_RTL2832U=m CONFIG_DVB_USB_AF9015=m # CONFIG_DVB_USB_CE6230 is not set # CONFIG_DVB_USB_FRIIO is not set diff --git a/projects/ION/linux/linux.i386.conf b/projects/ION/linux/linux.i386.conf index 95df940999..0aa90cef31 100644 --- a/projects/ION/linux/linux.i386.conf +++ b/projects/ION/linux/linux.i386.conf @@ -99,7 +99,6 @@ CONFIG_IRQ_FORCED_THREADING=y # RCU Subsystem # CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set # CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 @@ -1609,6 +1608,7 @@ CONFIG_DVB_USB_DW2102=m # CONFIG_DVB_USB_CINERGY_T2 is not set CONFIG_DVB_USB_ANYSEE=m # CONFIG_DVB_USB_DTV5100 is not set +CONFIG_DVB_USB_RTL2832U=m CONFIG_DVB_USB_AF9015=m # CONFIG_DVB_USB_CE6230 is not set # CONFIG_DVB_USB_FRIIO is not set diff --git a/projects/ION/linux/linux.x86_64.conf b/projects/ION/linux/linux.x86_64.conf index 23838310b0..b86b527057 100644 --- a/projects/ION/linux/linux.x86_64.conf +++ b/projects/ION/linux/linux.x86_64.conf @@ -99,7 +99,6 @@ CONFIG_IRQ_FORCED_THREADING=y # RCU Subsystem # CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set # CONFIG_PREEMPT_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 @@ -1552,6 +1551,7 @@ CONFIG_DVB_USB_DW2102=m # CONFIG_DVB_USB_CINERGY_T2 is not set CONFIG_DVB_USB_ANYSEE=m # CONFIG_DVB_USB_DTV5100 is not set +CONFIG_DVB_USB_RTL2832U=m CONFIG_DVB_USB_AF9015=m # CONFIG_DVB_USB_CE6230 is not set # CONFIG_DVB_USB_FRIIO is not set diff --git a/projects/Intel/linux/linux.i386.conf b/projects/Intel/linux/linux.i386.conf index 7b7e59d5a2..22ddfdcbc0 100644 --- a/projects/Intel/linux/linux.i386.conf +++ b/projects/Intel/linux/linux.i386.conf @@ -1641,6 +1641,7 @@ CONFIG_DVB_USB_DW2102=m # CONFIG_DVB_USB_CINERGY_T2 is not set CONFIG_DVB_USB_ANYSEE=m CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_RTL2832U=m # CONFIG_DVB_USB_AF9015 is not set # CONFIG_DVB_USB_CE6230 is not set # CONFIG_DVB_USB_FRIIO is not set diff --git a/projects/Intel/linux/linux.x86_64.conf b/projects/Intel/linux/linux.x86_64.conf index d461a1d86d..6b09445d3c 100644 --- a/projects/Intel/linux/linux.x86_64.conf +++ b/projects/Intel/linux/linux.x86_64.conf @@ -1588,6 +1588,7 @@ CONFIG_DVB_USB_DW2102=m # CONFIG_DVB_USB_CINERGY_T2 is not set CONFIG_DVB_USB_ANYSEE=m # CONFIG_DVB_USB_DTV5100 is not set +CONFIG_DVB_USB_RTL2832U=m CONFIG_DVB_USB_AF9015=m # CONFIG_DVB_USB_CE6230 is not set # CONFIG_DVB_USB_FRIIO is not set From 5f73eab95ebfe25db3c50cda744b87c665331268 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Wed, 15 Jun 2011 18:34:40 +0200 Subject: [PATCH 08/17] linux: change value of USB_PID_GTEK_WARM in RTL2832U driver, thanks to vpeter Signed-off-by: Stephan Raue --- ...832u_change_value_of_USB_PID_GTEK_WARM-0.1.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 packages/linux/patches/linux-2.6.39.1-059-rtl2832u_change_value_of_USB_PID_GTEK_WARM-0.1.patch diff --git a/packages/linux/patches/linux-2.6.39.1-059-rtl2832u_change_value_of_USB_PID_GTEK_WARM-0.1.patch b/packages/linux/patches/linux-2.6.39.1-059-rtl2832u_change_value_of_USB_PID_GTEK_WARM-0.1.patch new file mode 100644 index 0000000000..1c2ed1bba0 --- /dev/null +++ b/packages/linux/patches/linux-2.6.39.1-059-rtl2832u_change_value_of_USB_PID_GTEK_WARM-0.1.patch @@ -0,0 +1,13 @@ +diff -Naur linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u.h linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u.h +--- linux-2.6.39.1/drivers/media/dvb/dvb-usb/rtl2832u.h 2010-10-27 08:17:30.000000000 +0200 ++++ linux-2.6.39.1.patch/drivers/media/dvb/dvb-usb/rtl2832u.h 2011-06-15 18:22:30.416756439 +0200 +@@ -39,7 +39,8 @@ + #define USB_PID_DEXATEK_WARM_4 0x1104 + + #define USB_VID_GTEK 0x1F4D +-#define USB_PID_GTEK_WARM 0x0837 ++//#define USB_PID_GTEK_WARM 0x0837 ++#define USB_PID_GTEK_WARM 0xC803 + #define USB_PID_GTEK_WARM_A 0xA803 + #define USB_PID_GTEK_WARM_B 0xB803 + #define USB_PID_GTEK_WARM_C 0xC803 From 17582c74a2fb1b7a694a290189b590460c940553 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Thu, 16 Jun 2011 02:52:20 +0200 Subject: [PATCH 09/17] xbmc: update to xbmc-ec08d63 Signed-off-by: Stephan Raue --- packages/mediacenter/xbmc/meta | 2 +- ...> xbmc-ec08d63-001-add_support_to_specify_GIT_REV-0.1.patch} | 0 ...patch => xbmc-ec08d63-201-let_select_XBMCProjectM-0.1.patch} | 0 ...SXS-0.1.patch => xbmc-ec08d63-202-let_select_RSXS-0.1.patch} | 0 ...S-0.1.patch => xbmc-ec08d63-303-fix_libdvd_xFLAGS-0.1.patch} | 0 ...ch => xbmc-ec08d63-321-CrystalHD_use_yuy2_to_yv12-0.1.patch} | 0 ...1.patch => xbmc-ec08d63-402-enable_yasm_in_ffmpeg-0.1.patch} | 0 ...heck-0.6.patch => xbmc-ec08d63-404-add_lame_check-0.6.patch} | 0 ...-0.1.patch => xbmc-ec08d63-452-change_lcd_content-0.1.patch} | 0 ...atch => xbmc-ec08d63-453-add_openelec.tv_RSS_news-0.1.patch} | 0 ...atch => xbmc-ec08d63-453-ps3_remote_be_more_quiet-0.1.patch} | 0 ...> xbmc-ec08d63-462-add_remote_irtrans_mediacenter-0.1.patch} | 0 ...0.1.patch => xbmc-ec08d63-463-add_remote_devinput-0.1.patch} | 0 ... xbmc-ec08d63-901-advancedsettings_alwaysextractflags.patch} | 0 14 files changed, 1 insertion(+), 1 deletion(-) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-001-add_support_to_specify_GIT_REV-0.1.patch => xbmc-ec08d63-001-add_support_to_specify_GIT_REV-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-201-let_select_XBMCProjectM-0.1.patch => xbmc-ec08d63-201-let_select_XBMCProjectM-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-202-let_select_RSXS-0.1.patch => xbmc-ec08d63-202-let_select_RSXS-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-303-fix_libdvd_xFLAGS-0.1.patch => xbmc-ec08d63-303-fix_libdvd_xFLAGS-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-321-CrystalHD_use_yuy2_to_yv12-0.1.patch => xbmc-ec08d63-321-CrystalHD_use_yuy2_to_yv12-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-402-enable_yasm_in_ffmpeg-0.1.patch => xbmc-ec08d63-402-enable_yasm_in_ffmpeg-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-404-add_lame_check-0.6.patch => xbmc-ec08d63-404-add_lame_check-0.6.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-452-change_lcd_content-0.1.patch => xbmc-ec08d63-452-change_lcd_content-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch => xbmc-ec08d63-453-add_openelec.tv_RSS_news-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-453-ps3_remote_be_more_quiet-0.1.patch => xbmc-ec08d63-453-ps3_remote_be_more_quiet-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-462-add_remote_irtrans_mediacenter-0.1.patch => xbmc-ec08d63-462-add_remote_irtrans_mediacenter-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-463-add_remote_devinput-0.1.patch => xbmc-ec08d63-463-add_remote_devinput-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ae07638-901-advancedsettings_alwaysextractflags.patch => xbmc-ec08d63-901-advancedsettings_alwaysextractflags.patch} (100%) diff --git a/packages/mediacenter/xbmc/meta b/packages/mediacenter/xbmc/meta index 72e3e0e039..69dba956be 100644 --- a/packages/mediacenter/xbmc/meta +++ b/packages/mediacenter/xbmc/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc" -PKG_VERSION="ae07638" +PKG_VERSION="ec08d63" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-001-add_support_to_specify_GIT_REV-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-001-add_support_to_specify_GIT_REV-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-001-add_support_to_specify_GIT_REV-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-001-add_support_to_specify_GIT_REV-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-201-let_select_XBMCProjectM-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-201-let_select_XBMCProjectM-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-201-let_select_XBMCProjectM-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-201-let_select_XBMCProjectM-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-202-let_select_RSXS-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-202-let_select_RSXS-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-202-let_select_RSXS-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-202-let_select_RSXS-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-303-fix_libdvd_xFLAGS-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-303-fix_libdvd_xFLAGS-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-303-fix_libdvd_xFLAGS-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-303-fix_libdvd_xFLAGS-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-321-CrystalHD_use_yuy2_to_yv12-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-321-CrystalHD_use_yuy2_to_yv12-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-321-CrystalHD_use_yuy2_to_yv12-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-321-CrystalHD_use_yuy2_to_yv12-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-402-enable_yasm_in_ffmpeg-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-402-enable_yasm_in_ffmpeg-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-402-enable_yasm_in_ffmpeg-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-402-enable_yasm_in_ffmpeg-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-404-add_lame_check-0.6.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-404-add_lame_check-0.6.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-404-add_lame_check-0.6.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-404-add_lame_check-0.6.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-452-change_lcd_content-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-452-change_lcd_content-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-452-change_lcd_content-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-452-change_lcd_content-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-add_openelec.tv_RSS_news-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-10.1-Dharma-453-add_openelec.tv_RSS_news-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-add_openelec.tv_RSS_news-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-453-ps3_remote_be_more_quiet-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-ps3_remote_be_more_quiet-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-453-ps3_remote_be_more_quiet-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-ps3_remote_be_more_quiet-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-462-add_remote_irtrans_mediacenter-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-462-add_remote_irtrans_mediacenter-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-462-add_remote_irtrans_mediacenter-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-462-add_remote_irtrans_mediacenter-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-463-add_remote_devinput-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-463-add_remote_devinput-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-463-add_remote_devinput-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-463-add_remote_devinput-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ae07638-901-advancedsettings_alwaysextractflags.patch b/packages/mediacenter/xbmc/patches/xbmc-ec08d63-901-advancedsettings_alwaysextractflags.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ae07638-901-advancedsettings_alwaysextractflags.patch rename to packages/mediacenter/xbmc/patches/xbmc-ec08d63-901-advancedsettings_alwaysextractflags.patch From 1c8562be834fc1e8453b91dc9bb76aaa113a0a88 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Thu, 16 Jun 2011 02:52:46 +0200 Subject: [PATCH 10/17] xbmc-theme-Confluence: update to xbmc-theme-Confluence-ec08d63 Signed-off-by: Stephan Raue --- packages/mediacenter/xbmc-theme-Confluence/meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mediacenter/xbmc-theme-Confluence/meta b/packages/mediacenter/xbmc-theme-Confluence/meta index 46ba7f56a2..8f7c6c7d43 100644 --- a/packages/mediacenter/xbmc-theme-Confluence/meta +++ b/packages/mediacenter/xbmc-theme-Confluence/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc-theme-Confluence" -PKG_VERSION="ae07638" +PKG_VERSION="ec08d63" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" From ecf6da50e67261133ed31f2b75292e6289f13679 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Thu, 16 Jun 2011 03:36:49 +0200 Subject: [PATCH 11/17] yajl: update to yajl-2.0.1 Signed-off-by: Stephan Raue --- packages/devel/yajl/meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devel/yajl/meta b/packages/devel/yajl/meta index 1e85ef428a..b84cef5f18 100644 --- a/packages/devel/yajl/meta +++ b/packages/devel/yajl/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="yajl" -PKG_VERSION="1.0.12" +PKG_VERSION="2.0.1" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="ISC" From 543f8da17032e885a18e1e1ce9b80c1d541a2dca Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Thu, 16 Jun 2011 11:45:10 +0200 Subject: [PATCH 12/17] xbmc: update to xbmc-68d6946 Signed-off-by: Stephan Raue --- packages/mediacenter/xbmc/meta | 2 +- ...> xbmc-68d6946-001-add_support_to_specify_GIT_REV-0.1.patch} | 0 ...patch => xbmc-68d6946-201-let_select_XBMCProjectM-0.1.patch} | 0 ...SXS-0.1.patch => xbmc-68d6946-202-let_select_RSXS-0.1.patch} | 0 ...S-0.1.patch => xbmc-68d6946-303-fix_libdvd_xFLAGS-0.1.patch} | 0 ...ch => xbmc-68d6946-321-CrystalHD_use_yuy2_to_yv12-0.1.patch} | 0 ...1.patch => xbmc-68d6946-402-enable_yasm_in_ffmpeg-0.1.patch} | 0 ...heck-0.6.patch => xbmc-68d6946-404-add_lame_check-0.6.patch} | 0 ...-0.1.patch => xbmc-68d6946-452-change_lcd_content-0.1.patch} | 0 ...atch => xbmc-68d6946-453-add_openelec.tv_RSS_news-0.1.patch} | 0 ...atch => xbmc-68d6946-453-ps3_remote_be_more_quiet-0.1.patch} | 0 ...> xbmc-68d6946-462-add_remote_irtrans_mediacenter-0.1.patch} | 0 ...0.1.patch => xbmc-68d6946-463-add_remote_devinput-0.1.patch} | 0 ... xbmc-68d6946-901-advancedsettings_alwaysextractflags.patch} | 0 14 files changed, 1 insertion(+), 1 deletion(-) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-001-add_support_to_specify_GIT_REV-0.1.patch => xbmc-68d6946-001-add_support_to_specify_GIT_REV-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-201-let_select_XBMCProjectM-0.1.patch => xbmc-68d6946-201-let_select_XBMCProjectM-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-202-let_select_RSXS-0.1.patch => xbmc-68d6946-202-let_select_RSXS-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-303-fix_libdvd_xFLAGS-0.1.patch => xbmc-68d6946-303-fix_libdvd_xFLAGS-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-321-CrystalHD_use_yuy2_to_yv12-0.1.patch => xbmc-68d6946-321-CrystalHD_use_yuy2_to_yv12-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-402-enable_yasm_in_ffmpeg-0.1.patch => xbmc-68d6946-402-enable_yasm_in_ffmpeg-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-404-add_lame_check-0.6.patch => xbmc-68d6946-404-add_lame_check-0.6.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-452-change_lcd_content-0.1.patch => xbmc-68d6946-452-change_lcd_content-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-453-add_openelec.tv_RSS_news-0.1.patch => xbmc-68d6946-453-add_openelec.tv_RSS_news-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-453-ps3_remote_be_more_quiet-0.1.patch => xbmc-68d6946-453-ps3_remote_be_more_quiet-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-462-add_remote_irtrans_mediacenter-0.1.patch => xbmc-68d6946-462-add_remote_irtrans_mediacenter-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-463-add_remote_devinput-0.1.patch => xbmc-68d6946-463-add_remote_devinput-0.1.patch} (100%) rename packages/mediacenter/xbmc/patches/{xbmc-ec08d63-901-advancedsettings_alwaysextractflags.patch => xbmc-68d6946-901-advancedsettings_alwaysextractflags.patch} (100%) diff --git a/packages/mediacenter/xbmc/meta b/packages/mediacenter/xbmc/meta index 69dba956be..82ed4d7203 100644 --- a/packages/mediacenter/xbmc/meta +++ b/packages/mediacenter/xbmc/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc" -PKG_VERSION="ec08d63" +PKG_VERSION="68d6946" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-001-add_support_to_specify_GIT_REV-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-001-add_support_to_specify_GIT_REV-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-001-add_support_to_specify_GIT_REV-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-001-add_support_to_specify_GIT_REV-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-201-let_select_XBMCProjectM-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-201-let_select_XBMCProjectM-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-201-let_select_XBMCProjectM-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-201-let_select_XBMCProjectM-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-202-let_select_RSXS-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-202-let_select_RSXS-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-202-let_select_RSXS-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-202-let_select_RSXS-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-303-fix_libdvd_xFLAGS-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-303-fix_libdvd_xFLAGS-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-303-fix_libdvd_xFLAGS-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-303-fix_libdvd_xFLAGS-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-321-CrystalHD_use_yuy2_to_yv12-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-321-CrystalHD_use_yuy2_to_yv12-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-321-CrystalHD_use_yuy2_to_yv12-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-321-CrystalHD_use_yuy2_to_yv12-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-402-enable_yasm_in_ffmpeg-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-402-enable_yasm_in_ffmpeg-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-402-enable_yasm_in_ffmpeg-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-402-enable_yasm_in_ffmpeg-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-404-add_lame_check-0.6.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-404-add_lame_check-0.6.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-404-add_lame_check-0.6.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-404-add_lame_check-0.6.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-452-change_lcd_content-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-452-change_lcd_content-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-452-change_lcd_content-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-452-change_lcd_content-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-add_openelec.tv_RSS_news-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-453-add_openelec.tv_RSS_news-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-add_openelec.tv_RSS_news-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-453-add_openelec.tv_RSS_news-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-ps3_remote_be_more_quiet-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-453-ps3_remote_be_more_quiet-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-453-ps3_remote_be_more_quiet-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-453-ps3_remote_be_more_quiet-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-462-add_remote_irtrans_mediacenter-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-462-add_remote_irtrans_mediacenter-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-462-add_remote_irtrans_mediacenter-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-462-add_remote_irtrans_mediacenter-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-463-add_remote_devinput-0.1.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-463-add_remote_devinput-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-463-add_remote_devinput-0.1.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-463-add_remote_devinput-0.1.patch diff --git a/packages/mediacenter/xbmc/patches/xbmc-ec08d63-901-advancedsettings_alwaysextractflags.patch b/packages/mediacenter/xbmc/patches/xbmc-68d6946-901-advancedsettings_alwaysextractflags.patch similarity index 100% rename from packages/mediacenter/xbmc/patches/xbmc-ec08d63-901-advancedsettings_alwaysextractflags.patch rename to packages/mediacenter/xbmc/patches/xbmc-68d6946-901-advancedsettings_alwaysextractflags.patch From e20100244def1bd48a186b1f855269741eca96e3 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Thu, 16 Jun 2011 11:45:29 +0200 Subject: [PATCH 13/17] xbmc-theme-Confluence: update to xbmc-theme-Confluence-68d6946 Signed-off-by: Stephan Raue --- packages/mediacenter/xbmc-theme-Confluence/meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mediacenter/xbmc-theme-Confluence/meta b/packages/mediacenter/xbmc-theme-Confluence/meta index 8f7c6c7d43..7e41115f9d 100644 --- a/packages/mediacenter/xbmc-theme-Confluence/meta +++ b/packages/mediacenter/xbmc-theme-Confluence/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc-theme-Confluence" -PKG_VERSION="ec08d63" +PKG_VERSION="68d6946" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" From 7d2b3bdbbf81c55e173e7b93c9a29f115c811f05 Mon Sep 17 00:00:00 2001 From: hennr Date: Thu, 16 Jun 2011 04:54:38 -0700 Subject: [PATCH 14/17] Fix for issue #8 in the issue tracker. The script ignore if the first md5sum failed, both are now checked and the script will exit properly if one of the check does not succeed. --- config/release/create_installstick | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) mode change 100755 => 100644 config/release/create_installstick diff --git a/config/release/create_installstick b/config/release/create_installstick old mode 100755 new mode 100644 index f82a792952..73634bec48 --- a/config/release/create_installstick +++ b/config/release/create_installstick @@ -56,14 +56,9 @@ echo "# Please read the instructions and use very carefully.. #" echo "# #" echo "#########################################################" -# check MD5 sums - echo "checking MD5 sum..." - md5sum -c target/KERNEL.md5 - MD5_ERROR="$?" - md5sum -c target/SYSTEM.md5 - MD5_ERROR="$?" - -if [ "$MD5_ERROR" = "1" ]; then +md5sumFailed() +{ + clear echo "#########################################################" echo "# #" echo "# OpenELEC.tv failed md5 check - Installation will quit #" @@ -73,7 +68,19 @@ if [ "$MD5_ERROR" = "1" ]; then echo "# #" echo "#########################################################" exit 1 -fi +} + + +# check MD5 sums + echo "checking MD5 sum..." + md5sum -c target/KERNEL.md5 + if [ "$?" = "1" ]; then + md5sumFailed + fi + md5sum -c target/SYSTEM.md5 + if [ "$?" = "1" ]; then + md5sumFailed + fi # (TODO) umount anything umount "$PART" From 1266653b80e518051ef44f86c18396f59176fdf6 Mon Sep 17 00:00:00 2001 From: hennr Date: Thu, 16 Jun 2011 05:36:59 -0700 Subject: [PATCH 15/17] Some typos. Added a second "sync" command because umount is not patient and will cancel the unmounting process if there is too much left to write to the stick. --- config/release/create_installstick | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) mode change 100755 => 100644 config/release/create_installstick diff --git a/config/release/create_installstick b/config/release/create_installstick old mode 100755 new mode 100644 index f82a792952..a87f9d2fd9 --- a/config/release/create_installstick +++ b/config/release/create_installstick @@ -136,6 +136,10 @@ fi cp README /tmp/usb_install cp RELEASE /tmp/usb_install +# syncing disk + echo "syncing disk..." + sync + # unmount partition echo "unmounting partition $PART..." umount "$PART" @@ -143,11 +147,11 @@ fi # write mbr echo "writing mbr..." if [ -f /usr/lib/syslinux/mbr.bin ]; then - MBR="/usr/lib/syslinux/mbr.bin" # example: ubuntu + MBR="/usr/lib/syslinux/mbr.bin" # example: debian, ubuntu elif [ -f /usr/share/syslinux/mbr.bin ]; then MBR="/usr/share/syslinux/mbr.bin" # example: fedora else - echo "Dont find mbr.bin on Host OS" + echo "Can't find mbr.bin on Host OS" fi if [ -n "$MBR" ]; then @@ -162,4 +166,4 @@ fi echo "cleaning tempdir..." rmdir /tmp/usb_install -echo "...ready" +echo "...finished installation" From 74c14056076f8f0fb1415db6eb30b254edca286c Mon Sep 17 00:00:00 2001 From: hennr Date: Thu, 16 Jun 2011 05:43:36 -0700 Subject: [PATCH 16/17] Adds three checks for tools needed by the installer --- config/release/create_installstick | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) mode change 100755 => 100644 config/release/create_installstick diff --git a/config/release/create_installstick b/config/release/create_installstick old mode 100755 new mode 100644 index f82a792952..fb8ddb3691 --- a/config/release/create_installstick +++ b/config/release/create_installstick @@ -56,6 +56,58 @@ echo "# Please read the instructions and use very carefully.. #" echo "# #" echo "#########################################################" +# check for some required tools + + # this is needed to create a bootloader + which syslinux > /dev/null + if [ "$?" = "1" ]; then + clear + echo "#########################################################" + echo "# #" + echo "# OpenELEC.tv missing tool - Installation will quit #" + echo "# #" + echo "# We can't find the required tool \"syslinux\" #" + echo "# on your system. #" + echo "# Please install it via your package manager. #" + echo "# #" + echo "#########################################################" + exit 1 + fi + + # this is needed by syslinux + which mcopy > /dev/null + if [ "$?" = "1" ]; then + clear + echo "#########################################################" + echo "# #" + echo "# OpenELEC.tv missing tool - Installation will quit #" + echo "# #" + echo "# We can't find the required tool \"mcopy\" #" + echo "# on your system. #" + echo "# Please install it via your package manager. #" + echo "# NOTE: Some distributions call this package #" + echo "# \"mtools\". #" + echo "# #" + echo "#########################################################" + exit 1 + fi + + # this is needed to partion the stick + which parted > /dev/null + if [ "$?" = "1" ]; then + clear + echo "#########################################################" + echo "# #" + echo "# OpenELEC.tv missing tool - Installation will quit #" + echo "# #" + echo "# We can't find the required tool \"parted\" #" + echo "# on your system. #" + echo "# Please install it via your package manager. #" + echo "# #" + echo "#########################################################" + exit 1 + fi + # check MD5 sums echo "checking MD5 sum..." md5sum -c target/KERNEL.md5 From ccbf221c87e6b824167ea13764ca3b354d70b9e9 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Fri, 17 Jun 2011 07:04:03 +0200 Subject: [PATCH 17/17] projects/*/linux: enable CONFIG_PREEMPT_VOLUNTARY Signed-off-by: Stephan Raue --- projects/ATV/linux/linux.i386.conf | 4 ++-- projects/Fusion/linux/linux.i386.conf | 4 ++-- projects/Generic/linux/linux.i386.conf | 4 ++-- projects/ION/linux/linux.i386.conf | 4 ++-- projects/ION/linux/linux.x86_64.conf | 4 ++-- projects/Intel/linux/linux.i386.conf | 4 ++-- projects/Intel/linux/linux.x86_64.conf | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/projects/ATV/linux/linux.i386.conf b/projects/ATV/linux/linux.i386.conf index 115bc522c6..f3679dc57b 100644 --- a/projects/ATV/linux/linux.i386.conf +++ b/projects/ATV/linux/linux.i386.conf @@ -329,8 +329,8 @@ CONFIG_NR_CPUS=2 # CONFIG_SCHED_SMT is not set # CONFIG_SCHED_MC is not set CONFIG_IRQ_TIME_ACCOUNTING=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y diff --git a/projects/Fusion/linux/linux.i386.conf b/projects/Fusion/linux/linux.i386.conf index 15ffb52772..e6c93f127f 100644 --- a/projects/Fusion/linux/linux.i386.conf +++ b/projects/Fusion/linux/linux.i386.conf @@ -322,8 +322,8 @@ CONFIG_NR_CPUS=4 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_IRQ_TIME_ACCOUNTING is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y diff --git a/projects/Generic/linux/linux.i386.conf b/projects/Generic/linux/linux.i386.conf index d9875c3300..a76ae93ad2 100644 --- a/projects/Generic/linux/linux.i386.conf +++ b/projects/Generic/linux/linux.i386.conf @@ -324,8 +324,8 @@ CONFIG_NR_CPUS=8 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_IRQ_TIME_ACCOUNTING is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y diff --git a/projects/ION/linux/linux.i386.conf b/projects/ION/linux/linux.i386.conf index 0aa90cef31..b97571f360 100644 --- a/projects/ION/linux/linux.i386.conf +++ b/projects/ION/linux/linux.i386.conf @@ -322,8 +322,8 @@ CONFIG_NR_CPUS=4 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_IRQ_TIME_ACCOUNTING is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y diff --git a/projects/ION/linux/linux.x86_64.conf b/projects/ION/linux/linux.x86_64.conf index b86b527057..d1b3db2bc2 100644 --- a/projects/ION/linux/linux.x86_64.conf +++ b/projects/ION/linux/linux.x86_64.conf @@ -295,8 +295,8 @@ CONFIG_NR_CPUS=4 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_IRQ_TIME_ACCOUNTING is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y diff --git a/projects/Intel/linux/linux.i386.conf b/projects/Intel/linux/linux.i386.conf index 22ddfdcbc0..a55a215e0d 100644 --- a/projects/Intel/linux/linux.i386.conf +++ b/projects/Intel/linux/linux.i386.conf @@ -323,8 +323,8 @@ CONFIG_NR_CPUS=8 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_IRQ_TIME_ACCOUNTING is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y diff --git a/projects/Intel/linux/linux.x86_64.conf b/projects/Intel/linux/linux.x86_64.conf index 6b09445d3c..960b520715 100644 --- a/projects/Intel/linux/linux.x86_64.conf +++ b/projects/Intel/linux/linux.x86_64.conf @@ -297,8 +297,8 @@ CONFIG_NR_CPUS=8 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_IRQ_TIME_ACCOUNTING is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y