drxj.c 350 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389
  1. /*
  2. Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are met:
  6. * Redistributions of source code must retain the above copyright notice,
  7. this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright notice,
  9. this list of conditions and the following disclaimer in the documentation
  10. and/or other materials provided with the distribution.
  11. * Neither the name of Trident Microsystems nor Hauppauge Computer Works
  12. nor the names of its contributors may be used to endorse or promote
  13. products derived from this software without specific prior written
  14. permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  19. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. POSSIBILITY OF SUCH DAMAGE.
  26. DRXJ specific implementation of DRX driver
  27. authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
  28. The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
  29. written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
  30. This program is free software; you can redistribute it and/or modify
  31. it under the terms of the GNU General Public License as published by
  32. the Free Software Foundation; either version 2 of the License, or
  33. (at your option) any later version.
  34. This program is distributed in the hope that it will be useful,
  35. but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37. GNU General Public License for more details.
  38. You should have received a copy of the GNU General Public License
  39. along with this program; if not, write to the Free Software
  40. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  41. */
  42. /*-----------------------------------------------------------------------------
  43. INCLUDE FILES
  44. ----------------------------------------------------------------------------*/
  45. #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
  46. #include <linux/module.h>
  47. #include <linux/init.h>
  48. #include <linux/string.h>
  49. #include <linux/slab.h>
  50. #include <asm/div64.h>
  51. #include "dvb_frontend.h"
  52. #include "drx39xxj.h"
  53. #include "drxj.h"
  54. #include "drxj_map.h"
  55. /*============================================================================*/
  56. /*=== DEFINES ================================================================*/
  57. /*============================================================================*/
  58. #define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
  59. /**
  60. * \brief Maximum u32 value.
  61. */
  62. #ifndef MAX_U32
  63. #define MAX_U32 ((u32) (0xFFFFFFFFL))
  64. #endif
  65. /* Customer configurable hardware settings, etc */
  66. #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
  67. #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
  68. #endif
  69. #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
  70. #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
  71. #endif
  72. #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
  73. #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
  74. #endif
  75. #ifndef OOB_CRX_DRIVE_STRENGTH
  76. #define OOB_CRX_DRIVE_STRENGTH 0x02
  77. #endif
  78. #ifndef OOB_DRX_DRIVE_STRENGTH
  79. #define OOB_DRX_DRIVE_STRENGTH 0x02
  80. #endif
  81. /**** START DJCOMBO patches to DRXJ registermap constants *********************/
  82. /**** registermap 200706071303 from drxj **************************************/
  83. #define ATV_TOP_CR_AMP_TH_FM 0x0
  84. #define ATV_TOP_CR_AMP_TH_L 0xA
  85. #define ATV_TOP_CR_AMP_TH_LP 0xA
  86. #define ATV_TOP_CR_AMP_TH_BG 0x8
  87. #define ATV_TOP_CR_AMP_TH_DK 0x8
  88. #define ATV_TOP_CR_AMP_TH_I 0x8
  89. #define ATV_TOP_CR_CONT_CR_D_MN 0x18
  90. #define ATV_TOP_CR_CONT_CR_D_FM 0x0
  91. #define ATV_TOP_CR_CONT_CR_D_L 0x20
  92. #define ATV_TOP_CR_CONT_CR_D_LP 0x20
  93. #define ATV_TOP_CR_CONT_CR_D_BG 0x18
  94. #define ATV_TOP_CR_CONT_CR_D_DK 0x18
  95. #define ATV_TOP_CR_CONT_CR_D_I 0x18
  96. #define ATV_TOP_CR_CONT_CR_I_MN 0x80
  97. #define ATV_TOP_CR_CONT_CR_I_FM 0x0
  98. #define ATV_TOP_CR_CONT_CR_I_L 0x80
  99. #define ATV_TOP_CR_CONT_CR_I_LP 0x80
  100. #define ATV_TOP_CR_CONT_CR_I_BG 0x80
  101. #define ATV_TOP_CR_CONT_CR_I_DK 0x80
  102. #define ATV_TOP_CR_CONT_CR_I_I 0x80
  103. #define ATV_TOP_CR_CONT_CR_P_MN 0x4
  104. #define ATV_TOP_CR_CONT_CR_P_FM 0x0
  105. #define ATV_TOP_CR_CONT_CR_P_L 0x4
  106. #define ATV_TOP_CR_CONT_CR_P_LP 0x4
  107. #define ATV_TOP_CR_CONT_CR_P_BG 0x4
  108. #define ATV_TOP_CR_CONT_CR_P_DK 0x4
  109. #define ATV_TOP_CR_CONT_CR_P_I 0x4
  110. #define ATV_TOP_CR_OVM_TH_MN 0xA0
  111. #define ATV_TOP_CR_OVM_TH_FM 0x0
  112. #define ATV_TOP_CR_OVM_TH_L 0xA0
  113. #define ATV_TOP_CR_OVM_TH_LP 0xA0
  114. #define ATV_TOP_CR_OVM_TH_BG 0xA0
  115. #define ATV_TOP_CR_OVM_TH_DK 0xA0
  116. #define ATV_TOP_CR_OVM_TH_I 0xA0
  117. #define ATV_TOP_EQU0_EQU_C0_FM 0x0
  118. #define ATV_TOP_EQU0_EQU_C0_L 0x3
  119. #define ATV_TOP_EQU0_EQU_C0_LP 0x3
  120. #define ATV_TOP_EQU0_EQU_C0_BG 0x7
  121. #define ATV_TOP_EQU0_EQU_C0_DK 0x0
  122. #define ATV_TOP_EQU0_EQU_C0_I 0x3
  123. #define ATV_TOP_EQU1_EQU_C1_FM 0x0
  124. #define ATV_TOP_EQU1_EQU_C1_L 0x1F6
  125. #define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
  126. #define ATV_TOP_EQU1_EQU_C1_BG 0x197
  127. #define ATV_TOP_EQU1_EQU_C1_DK 0x198
  128. #define ATV_TOP_EQU1_EQU_C1_I 0x1F6
  129. #define ATV_TOP_EQU2_EQU_C2_FM 0x0
  130. #define ATV_TOP_EQU2_EQU_C2_L 0x28
  131. #define ATV_TOP_EQU2_EQU_C2_LP 0x28
  132. #define ATV_TOP_EQU2_EQU_C2_BG 0xC5
  133. #define ATV_TOP_EQU2_EQU_C2_DK 0xB0
  134. #define ATV_TOP_EQU2_EQU_C2_I 0x28
  135. #define ATV_TOP_EQU3_EQU_C3_FM 0x0
  136. #define ATV_TOP_EQU3_EQU_C3_L 0x192
  137. #define ATV_TOP_EQU3_EQU_C3_LP 0x192
  138. #define ATV_TOP_EQU3_EQU_C3_BG 0x12E
  139. #define ATV_TOP_EQU3_EQU_C3_DK 0x18E
  140. #define ATV_TOP_EQU3_EQU_C3_I 0x192
  141. #define ATV_TOP_STD_MODE_MN 0x0
  142. #define ATV_TOP_STD_MODE_FM 0x1
  143. #define ATV_TOP_STD_MODE_L 0x0
  144. #define ATV_TOP_STD_MODE_LP 0x0
  145. #define ATV_TOP_STD_MODE_BG 0x0
  146. #define ATV_TOP_STD_MODE_DK 0x0
  147. #define ATV_TOP_STD_MODE_I 0x0
  148. #define ATV_TOP_STD_VID_POL_MN 0x0
  149. #define ATV_TOP_STD_VID_POL_FM 0x0
  150. #define ATV_TOP_STD_VID_POL_L 0x2
  151. #define ATV_TOP_STD_VID_POL_LP 0x2
  152. #define ATV_TOP_STD_VID_POL_BG 0x0
  153. #define ATV_TOP_STD_VID_POL_DK 0x0
  154. #define ATV_TOP_STD_VID_POL_I 0x0
  155. #define ATV_TOP_VID_AMP_MN 0x380
  156. #define ATV_TOP_VID_AMP_FM 0x0
  157. #define ATV_TOP_VID_AMP_L 0xF50
  158. #define ATV_TOP_VID_AMP_LP 0xF50
  159. #define ATV_TOP_VID_AMP_BG 0x380
  160. #define ATV_TOP_VID_AMP_DK 0x394
  161. #define ATV_TOP_VID_AMP_I 0x3D8
  162. #define IQM_CF_OUT_ENA_OFDM__M 0x4
  163. #define IQM_FS_ADJ_SEL_B_QAM 0x1
  164. #define IQM_FS_ADJ_SEL_B_OFF 0x0
  165. #define IQM_FS_ADJ_SEL_B_VSB 0x2
  166. #define IQM_RC_ADJ_SEL_B_OFF 0x0
  167. #define IQM_RC_ADJ_SEL_B_QAM 0x1
  168. #define IQM_RC_ADJ_SEL_B_VSB 0x2
  169. /**** END DJCOMBO patches to DRXJ registermap *********************************/
  170. #include "drx_driver_version.h"
  171. /* #define DRX_DEBUG */
  172. #ifdef DRX_DEBUG
  173. #include <stdio.h>
  174. #endif
  175. /*-----------------------------------------------------------------------------
  176. ENUMS
  177. ----------------------------------------------------------------------------*/
  178. /*-----------------------------------------------------------------------------
  179. DEFINES
  180. ----------------------------------------------------------------------------*/
  181. #ifndef DRXJ_WAKE_UP_KEY
  182. #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
  183. #endif
  184. /**
  185. * \def DRXJ_DEF_I2C_ADDR
  186. * \brief Default I2C address of a demodulator instance.
  187. */
  188. #define DRXJ_DEF_I2C_ADDR (0x52)
  189. /**
  190. * \def DRXJ_DEF_DEMOD_DEV_ID
  191. * \brief Default device identifier of a demodultor instance.
  192. */
  193. #define DRXJ_DEF_DEMOD_DEV_ID (1)
  194. /**
  195. * \def DRXJ_SCAN_TIMEOUT
  196. * \brief Timeout value for waiting on demod lock during channel scan (millisec).
  197. */
  198. #define DRXJ_SCAN_TIMEOUT 1000
  199. /**
  200. * \def HI_I2C_DELAY
  201. * \brief HI timing delay for I2C timing (in nano seconds)
  202. *
  203. * Used to compute HI_CFG_DIV
  204. */
  205. #define HI_I2C_DELAY 42
  206. /**
  207. * \def HI_I2C_BRIDGE_DELAY
  208. * \brief HI timing delay for I2C timing (in nano seconds)
  209. *
  210. * Used to compute HI_CFG_BDL
  211. */
  212. #define HI_I2C_BRIDGE_DELAY 750
  213. /**
  214. * \brief Time Window for MER and SER Measurement in Units of Segment duration.
  215. */
  216. #define VSB_TOP_MEASUREMENT_PERIOD 64
  217. #define SYMBOLS_PER_SEGMENT 832
  218. /**
  219. * \brief bit rate and segment rate constants used for SER and BER.
  220. */
  221. /* values taken from the QAM microcode */
  222. #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
  223. #define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
  224. #define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
  225. #define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
  226. #define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
  227. #define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
  228. #define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
  229. #define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
  230. /**
  231. * \brief Min supported symbolrates.
  232. */
  233. #ifndef DRXJ_QAM_SYMBOLRATE_MIN
  234. #define DRXJ_QAM_SYMBOLRATE_MIN (520000)
  235. #endif
  236. /**
  237. * \brief Max supported symbolrates.
  238. */
  239. #ifndef DRXJ_QAM_SYMBOLRATE_MAX
  240. #define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
  241. #endif
  242. /**
  243. * \def DRXJ_QAM_MAX_WAITTIME
  244. * \brief Maximal wait time for QAM auto constellation in ms
  245. */
  246. #ifndef DRXJ_QAM_MAX_WAITTIME
  247. #define DRXJ_QAM_MAX_WAITTIME 900
  248. #endif
  249. #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
  250. #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
  251. #endif
  252. #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
  253. #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
  254. #endif
  255. /**
  256. * \def SCU status and results
  257. * \brief SCU
  258. */
  259. #define DRX_SCU_READY 0
  260. #define DRXJ_MAX_WAITTIME 100 /* ms */
  261. #define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
  262. #define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
  263. /**
  264. * \def DRX_AUD_MAX_DEVIATION
  265. * \brief Needed for calculation of prescale feature in AUD
  266. */
  267. #ifndef DRXJ_AUD_MAX_FM_DEVIATION
  268. #define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
  269. #endif
  270. /**
  271. * \brief Needed for calculation of NICAM prescale feature in AUD
  272. */
  273. #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
  274. #define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
  275. #endif
  276. /**
  277. * \brief Needed for calculation of NICAM prescale feature in AUD
  278. */
  279. #ifndef DRXJ_AUD_MAX_WAITTIME
  280. #define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
  281. #endif
  282. /* ATV config changed flags */
  283. #define DRXJ_ATV_CHANGED_COEF (0x00000001UL)
  284. #define DRXJ_ATV_CHANGED_PEAK_FLT (0x00000008UL)
  285. #define DRXJ_ATV_CHANGED_NOISE_FLT (0x00000010UL)
  286. #define DRXJ_ATV_CHANGED_OUTPUT (0x00000020UL)
  287. #define DRXJ_ATV_CHANGED_SIF_ATT (0x00000040UL)
  288. /* UIO define */
  289. #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
  290. #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
  291. /*
  292. * MICROCODE RELATED DEFINES
  293. */
  294. /* Magic word for checking correct Endianness of microcode data */
  295. #define DRX_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
  296. /* CRC flag in ucode header, flags field. */
  297. #define DRX_UCODE_CRC_FLAG (0x0001)
  298. /*
  299. * Maximum size of buffer used to verify the microcode.
  300. * Must be an even number
  301. */
  302. #define DRX_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
  303. #if DRX_UCODE_MAX_BUF_SIZE & 1
  304. #error DRX_UCODE_MAX_BUF_SIZE must be an even number
  305. #endif
  306. /*
  307. * Power mode macros
  308. */
  309. #define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
  310. (mode == DRX_POWER_MODE_10) || \
  311. (mode == DRX_POWER_MODE_11) || \
  312. (mode == DRX_POWER_MODE_12) || \
  313. (mode == DRX_POWER_MODE_13) || \
  314. (mode == DRX_POWER_MODE_14) || \
  315. (mode == DRX_POWER_MODE_15) || \
  316. (mode == DRX_POWER_MODE_16) || \
  317. (mode == DRX_POWER_DOWN))
  318. /* Pin safe mode macro */
  319. #define DRXJ_PIN_SAFE_MODE 0x0000
  320. /*============================================================================*/
  321. /*=== GLOBAL VARIABLEs =======================================================*/
  322. /*============================================================================*/
  323. /**
  324. */
  325. /**
  326. * \brief Temporary register definitions.
  327. * (register definitions that are not yet available in register master)
  328. */
  329. /******************************************************************************/
  330. /* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
  331. /* RAM adresses directly. This must be READ ONLY to avoid problems. */
  332. /* Writing to the interface adresses is more than only writing the RAM */
  333. /* locations */
  334. /******************************************************************************/
  335. /**
  336. * \brief RAM location of MODUS registers
  337. */
  338. #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
  339. #define AUD_DEM_RAM_MODUS_HI__M 0xF000
  340. #define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
  341. #define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
  342. /**
  343. * \brief RAM location of I2S config registers
  344. */
  345. #define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
  346. #define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
  347. /**
  348. * \brief RAM location of DCO config registers
  349. */
  350. #define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
  351. #define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
  352. #define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
  353. #define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
  354. /**
  355. * \brief RAM location of Threshold registers
  356. */
  357. #define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
  358. #define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
  359. #define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
  360. /**
  361. * \brief RAM location of Carrier Threshold registers
  362. */
  363. #define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
  364. #define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
  365. /**
  366. * \brief FM Matrix register fix
  367. */
  368. #ifdef AUD_DEM_WR_FM_MATRIX__A
  369. #undef AUD_DEM_WR_FM_MATRIX__A
  370. #endif
  371. #define AUD_DEM_WR_FM_MATRIX__A 0x105006F
  372. /*============================================================================*/
  373. /**
  374. * \brief Defines required for audio
  375. */
  376. #define AUD_VOLUME_ZERO_DB 115
  377. #define AUD_VOLUME_DB_MIN -60
  378. #define AUD_VOLUME_DB_MAX 12
  379. #define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
  380. #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
  381. #define AUD_MAX_AVC_REF_LEVEL 15
  382. #define AUD_I2S_FREQUENCY_MAX 48000UL
  383. #define AUD_I2S_FREQUENCY_MIN 12000UL
  384. #define AUD_RDS_ARRAY_SIZE 18
  385. /**
  386. * \brief Needed for calculation of prescale feature in AUD
  387. */
  388. #ifndef DRX_AUD_MAX_FM_DEVIATION
  389. #define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
  390. #endif
  391. /**
  392. * \brief Needed for calculation of NICAM prescale feature in AUD
  393. */
  394. #ifndef DRX_AUD_MAX_NICAM_PRESCALE
  395. #define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
  396. #endif
  397. /*============================================================================*/
  398. /* Values for I2S Master/Slave pin configurations */
  399. #define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
  400. #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
  401. #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
  402. #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
  403. #define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
  404. #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
  405. #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
  406. #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
  407. #define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
  408. #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
  409. #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
  410. #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
  411. /*============================================================================*/
  412. /*=== REGISTER ACCESS MACROS =================================================*/
  413. /*============================================================================*/
  414. /**
  415. * This macro is used to create byte arrays for block writes.
  416. * Block writes speed up I2C traffic between host and demod.
  417. * The macro takes care of the required byte order in a 16 bits word.
  418. * x -> lowbyte(x), highbyte(x)
  419. */
  420. #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
  421. ((u8)((((u16)x)>>8)&0xFF))
  422. /**
  423. * This macro is used to convert byte array to 16 bit register value for block read.
  424. * Block read speed up I2C traffic between host and demod.
  425. * The macro takes care of the required byte order in a 16 bits word.
  426. */
  427. #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
  428. /*============================================================================*/
  429. /*=== MISC DEFINES ===========================================================*/
  430. /*============================================================================*/
  431. /*============================================================================*/
  432. /*=== HI COMMAND RELATED DEFINES =============================================*/
  433. /*============================================================================*/
  434. /**
  435. * \brief General maximum number of retries for ucode command interfaces
  436. */
  437. #define DRXJ_MAX_RETRIES (100)
  438. /*============================================================================*/
  439. /*=== STANDARD RELATED MACROS ================================================*/
  440. /*============================================================================*/
  441. #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
  442. (std == DRX_STANDARD_PAL_SECAM_DK) || \
  443. (std == DRX_STANDARD_PAL_SECAM_I) || \
  444. (std == DRX_STANDARD_PAL_SECAM_L) || \
  445. (std == DRX_STANDARD_PAL_SECAM_LP) || \
  446. (std == DRX_STANDARD_NTSC) || \
  447. (std == DRX_STANDARD_FM))
  448. #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
  449. (std == DRX_STANDARD_ITU_B) || \
  450. (std == DRX_STANDARD_ITU_C) || \
  451. (std == DRX_STANDARD_ITU_D))
  452. /*-----------------------------------------------------------------------------
  453. GLOBAL VARIABLES
  454. ----------------------------------------------------------------------------*/
  455. /*
  456. * DRXJ DAP structures
  457. */
  458. static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
  459. u32 addr,
  460. u16 datasize,
  461. u8 *data, u32 flags);
  462. static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
  463. u32 waddr,
  464. u32 raddr,
  465. u16 wdata, u16 *rdata);
  466. static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
  467. u32 addr,
  468. u16 *data, u32 flags);
  469. static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
  470. u32 addr,
  471. u32 *data, u32 flags);
  472. static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
  473. u32 addr,
  474. u16 datasize,
  475. u8 *data, u32 flags);
  476. static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
  477. u32 addr,
  478. u16 data, u32 flags);
  479. static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
  480. u32 addr,
  481. u32 data, u32 flags);
  482. static struct drxj_data drxj_data_g = {
  483. false, /* has_lna : true if LNA (aka PGA) present */
  484. false, /* has_oob : true if OOB supported */
  485. false, /* has_ntsc: true if NTSC supported */
  486. false, /* has_btsc: true if BTSC supported */
  487. false, /* has_smatx: true if SMA_TX pin is available */
  488. false, /* has_smarx: true if SMA_RX pin is available */
  489. false, /* has_gpio : true if GPIO pin is available */
  490. false, /* has_irqn : true if IRQN pin is available */
  491. 0, /* mfx A1/A2/A... */
  492. /* tuner settings */
  493. false, /* tuner mirrors RF signal */
  494. /* standard/channel settings */
  495. DRX_STANDARD_UNKNOWN, /* current standard */
  496. DRX_CONSTELLATION_AUTO, /* constellation */
  497. 0, /* frequency in KHz */
  498. DRX_BANDWIDTH_UNKNOWN, /* curr_bandwidth */
  499. DRX_MIRROR_NO, /* mirror */
  500. /* signal quality information: */
  501. /* default values taken from the QAM Programming guide */
  502. /* fec_bits_desired should not be less than 4000000 */
  503. 4000000, /* fec_bits_desired */
  504. 5, /* fec_vd_plen */
  505. 4, /* qam_vd_prescale */
  506. 0xFFFF, /* qamVDPeriod */
  507. 204 * 8, /* fec_rs_plen annex A */
  508. 1, /* fec_rs_prescale */
  509. FEC_RS_MEASUREMENT_PERIOD, /* fec_rs_period */
  510. true, /* reset_pkt_err_acc */
  511. 0, /* pkt_err_acc_start */
  512. /* HI configuration */
  513. 0, /* hi_cfg_timing_div */
  514. 0, /* hi_cfg_bridge_delay */
  515. 0, /* hi_cfg_wake_up_key */
  516. 0, /* hi_cfg_ctrl */
  517. 0, /* HICfgTimeout */
  518. /* UIO configuartion */
  519. DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */
  520. DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */
  521. DRX_UIO_MODE_DISABLE, /* uioASELMode */
  522. DRX_UIO_MODE_DISABLE, /* uio_irqn_mode */
  523. /* FS setting */
  524. 0UL, /* iqm_fs_rate_ofs */
  525. false, /* pos_image */
  526. /* RC setting */
  527. 0UL, /* iqm_rc_rate_ofs */
  528. /* AUD information */
  529. /* false, * flagSetAUDdone */
  530. /* false, * detectedRDS */
  531. /* true, * flagASDRequest */
  532. /* false, * flagHDevClear */
  533. /* false, * flagHDevSet */
  534. /* (u16) 0xFFF, * rdsLastCount */
  535. /* ATV configuartion */
  536. 0UL, /* flags cfg changes */
  537. /* shadow of ATV_TOP_EQU0__A */
  538. {-5,
  539. ATV_TOP_EQU0_EQU_C0_FM,
  540. ATV_TOP_EQU0_EQU_C0_L,
  541. ATV_TOP_EQU0_EQU_C0_LP,
  542. ATV_TOP_EQU0_EQU_C0_BG,
  543. ATV_TOP_EQU0_EQU_C0_DK,
  544. ATV_TOP_EQU0_EQU_C0_I},
  545. /* shadow of ATV_TOP_EQU1__A */
  546. {-50,
  547. ATV_TOP_EQU1_EQU_C1_FM,
  548. ATV_TOP_EQU1_EQU_C1_L,
  549. ATV_TOP_EQU1_EQU_C1_LP,
  550. ATV_TOP_EQU1_EQU_C1_BG,
  551. ATV_TOP_EQU1_EQU_C1_DK,
  552. ATV_TOP_EQU1_EQU_C1_I},
  553. /* shadow of ATV_TOP_EQU2__A */
  554. {210,
  555. ATV_TOP_EQU2_EQU_C2_FM,
  556. ATV_TOP_EQU2_EQU_C2_L,
  557. ATV_TOP_EQU2_EQU_C2_LP,
  558. ATV_TOP_EQU2_EQU_C2_BG,
  559. ATV_TOP_EQU2_EQU_C2_DK,
  560. ATV_TOP_EQU2_EQU_C2_I},
  561. /* shadow of ATV_TOP_EQU3__A */
  562. {-160,
  563. ATV_TOP_EQU3_EQU_C3_FM,
  564. ATV_TOP_EQU3_EQU_C3_L,
  565. ATV_TOP_EQU3_EQU_C3_LP,
  566. ATV_TOP_EQU3_EQU_C3_BG,
  567. ATV_TOP_EQU3_EQU_C3_DK,
  568. ATV_TOP_EQU3_EQU_C3_I},
  569. false, /* flag: true=bypass */
  570. ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
  571. ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
  572. true, /* flag CVBS ouput enable */
  573. false, /* flag SIF ouput enable */
  574. DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
  575. { /* qam_rf_agc_cfg */
  576. DRX_STANDARD_ITU_B, /* standard */
  577. DRX_AGC_CTRL_AUTO, /* ctrl_mode */
  578. 0, /* output_level */
  579. 0, /* min_output_level */
  580. 0xFFFF, /* max_output_level */
  581. 0x0000, /* speed */
  582. 0x0000, /* top */
  583. 0x0000 /* c.o.c. */
  584. },
  585. { /* qam_if_agc_cfg */
  586. DRX_STANDARD_ITU_B, /* standard */
  587. DRX_AGC_CTRL_AUTO, /* ctrl_mode */
  588. 0, /* output_level */
  589. 0, /* min_output_level */
  590. 0xFFFF, /* max_output_level */
  591. 0x0000, /* speed */
  592. 0x0000, /* top (don't care) */
  593. 0x0000 /* c.o.c. (don't care) */
  594. },
  595. { /* vsb_rf_agc_cfg */
  596. DRX_STANDARD_8VSB, /* standard */
  597. DRX_AGC_CTRL_AUTO, /* ctrl_mode */
  598. 0, /* output_level */
  599. 0, /* min_output_level */
  600. 0xFFFF, /* max_output_level */
  601. 0x0000, /* speed */
  602. 0x0000, /* top (don't care) */
  603. 0x0000 /* c.o.c. (don't care) */
  604. },
  605. { /* vsb_if_agc_cfg */
  606. DRX_STANDARD_8VSB, /* standard */
  607. DRX_AGC_CTRL_AUTO, /* ctrl_mode */
  608. 0, /* output_level */
  609. 0, /* min_output_level */
  610. 0xFFFF, /* max_output_level */
  611. 0x0000, /* speed */
  612. 0x0000, /* top (don't care) */
  613. 0x0000 /* c.o.c. (don't care) */
  614. },
  615. 0, /* qam_pga_cfg */
  616. 0, /* vsb_pga_cfg */
  617. { /* qam_pre_saw_cfg */
  618. DRX_STANDARD_ITU_B, /* standard */
  619. 0, /* reference */
  620. false /* use_pre_saw */
  621. },
  622. { /* vsb_pre_saw_cfg */
  623. DRX_STANDARD_8VSB, /* standard */
  624. 0, /* reference */
  625. false /* use_pre_saw */
  626. },
  627. /* Version information */
  628. #ifndef _CH_
  629. {
  630. "01234567890", /* human readable version microcode */
  631. "01234567890" /* human readable version device specific code */
  632. },
  633. {
  634. { /* struct drx_version for microcode */
  635. DRX_MODULE_UNKNOWN,
  636. (char *)(NULL),
  637. 0,
  638. 0,
  639. 0,
  640. (char *)(NULL)
  641. },
  642. { /* struct drx_version for device specific code */
  643. DRX_MODULE_UNKNOWN,
  644. (char *)(NULL),
  645. 0,
  646. 0,
  647. 0,
  648. (char *)(NULL)
  649. }
  650. },
  651. {
  652. { /* struct drx_version_list for microcode */
  653. (struct drx_version *) (NULL),
  654. (struct drx_version_list *) (NULL)
  655. },
  656. { /* struct drx_version_list for device specific code */
  657. (struct drx_version *) (NULL),
  658. (struct drx_version_list *) (NULL)
  659. }
  660. },
  661. #endif
  662. false, /* smart_ant_inverted */
  663. /* Tracking filter setting for OOB */
  664. {
  665. 12000,
  666. 9300,
  667. 6600,
  668. 5280,
  669. 3700,
  670. 3000,
  671. 2000,
  672. 0},
  673. false, /* oob_power_on */
  674. 0, /* mpeg_ts_static_bitrate */
  675. false, /* disable_te_ihandling */
  676. false, /* bit_reverse_mpeg_outout */
  677. DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpeg_output_clock_rate */
  678. DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpeg_start_width */
  679. /* Pre SAW & Agc configuration for ATV */
  680. {
  681. DRX_STANDARD_NTSC, /* standard */
  682. 7, /* reference */
  683. true /* use_pre_saw */
  684. },
  685. { /* ATV RF-AGC */
  686. DRX_STANDARD_NTSC, /* standard */
  687. DRX_AGC_CTRL_AUTO, /* ctrl_mode */
  688. 0, /* output_level */
  689. 0, /* min_output_level (d.c.) */
  690. 0, /* max_output_level (d.c.) */
  691. 3, /* speed */
  692. 9500, /* top */
  693. 4000 /* cut-off current */
  694. },
  695. { /* ATV IF-AGC */
  696. DRX_STANDARD_NTSC, /* standard */
  697. DRX_AGC_CTRL_AUTO, /* ctrl_mode */
  698. 0, /* output_level */
  699. 0, /* min_output_level (d.c.) */
  700. 0, /* max_output_level (d.c.) */
  701. 3, /* speed */
  702. 2400, /* top */
  703. 0 /* c.o.c. (d.c.) */
  704. },
  705. 140, /* ATV PGA config */
  706. 0, /* curr_symbol_rate */
  707. false, /* pdr_safe_mode */
  708. SIO_PDR_GPIO_CFG__PRE, /* pdr_safe_restore_val_gpio */
  709. SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
  710. SIO_PDR_SMA_RX_CFG__PRE, /* pdr_safe_restore_val_sma_rx */
  711. SIO_PDR_SMA_TX_CFG__PRE, /* pdr_safe_restore_val_sma_tx */
  712. 4, /* oob_pre_saw */
  713. DRXJ_OOB_LO_POW_MINUS10DB, /* oob_lo_pow */
  714. {
  715. false /* aud_data, only first member */
  716. },
  717. };
  718. /**
  719. * \var drxj_default_addr_g
  720. * \brief Default I2C address and device identifier.
  721. */
  722. static struct i2c_device_addr drxj_default_addr_g = {
  723. DRXJ_DEF_I2C_ADDR, /* i2c address */
  724. DRXJ_DEF_DEMOD_DEV_ID /* device id */
  725. };
  726. /**
  727. * \var drxj_default_comm_attr_g
  728. * \brief Default common attributes of a drxj demodulator instance.
  729. */
  730. static struct drx_common_attr drxj_default_comm_attr_g = {
  731. NULL, /* ucode file */
  732. true, /* ucode verify switch */
  733. {0}, /* version record */
  734. 44000, /* IF in kHz in case no tuner instance is used */
  735. (151875 - 0), /* system clock frequency in kHz */
  736. 0, /* oscillator frequency kHz */
  737. 0, /* oscillator deviation in ppm, signed */
  738. false, /* If true mirror frequency spectrum */
  739. {
  740. /* MPEG output configuration */
  741. true, /* If true, enable MPEG ouput */
  742. false, /* If true, insert RS byte */
  743. false, /* If true, parallel out otherwise serial */
  744. false, /* If true, invert DATA signals */
  745. false, /* If true, invert ERR signal */
  746. false, /* If true, invert STR signals */
  747. false, /* If true, invert VAL signals */
  748. false, /* If true, invert CLK signals */
  749. true, /* If true, static MPEG clockrate will
  750. be used, otherwise clockrate will
  751. adapt to the bitrate of the TS */
  752. 19392658UL, /* Maximum bitrate in b/s in case
  753. static clockrate is selected */
  754. DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
  755. },
  756. /* Initilisations below can be omitted, they require no user input and
  757. are initialy 0, NULL or false. The compiler will initialize them to these
  758. values when omitted. */
  759. false, /* is_opened */
  760. /* SCAN */
  761. NULL, /* no scan params yet */
  762. 0, /* current scan index */
  763. 0, /* next scan frequency */
  764. false, /* scan ready flag */
  765. 0, /* max channels to scan */
  766. 0, /* nr of channels scanned */
  767. NULL, /* default scan function */
  768. NULL, /* default context pointer */
  769. 0, /* millisec to wait for demod lock */
  770. DRXJ_DEMOD_LOCK, /* desired lock */
  771. false,
  772. /* Power management */
  773. DRX_POWER_UP,
  774. /* Tuner */
  775. 1, /* nr of I2C port to wich tuner is */
  776. 0L, /* minimum RF input frequency, in kHz */
  777. 0L, /* maximum RF input frequency, in kHz */
  778. false, /* Rf Agc Polarity */
  779. false, /* If Agc Polarity */
  780. false, /* tuner slow mode */
  781. { /* current channel (all 0) */
  782. 0UL /* channel.frequency */
  783. },
  784. DRX_STANDARD_UNKNOWN, /* current standard */
  785. DRX_STANDARD_UNKNOWN, /* previous standard */
  786. DRX_STANDARD_UNKNOWN, /* di_cache_standard */
  787. false, /* use_bootloader */
  788. 0UL, /* capabilities */
  789. 0 /* mfx */
  790. };
  791. /**
  792. * \var drxj_default_demod_g
  793. * \brief Default drxj demodulator instance.
  794. */
  795. static struct drx_demod_instance drxj_default_demod_g = {
  796. &drxj_default_addr_g, /* i2c address & device id */
  797. &drxj_default_comm_attr_g, /* demod common attributes */
  798. &drxj_data_g /* demod device specific attributes */
  799. };
  800. /**
  801. * \brief Default audio data structure for DRK demodulator instance.
  802. *
  803. * This structure is DRXK specific.
  804. *
  805. */
  806. static struct drx_aud_data drxj_default_aud_data_g = {
  807. false, /* audio_is_active */
  808. DRX_AUD_STANDARD_AUTO, /* audio_standard */
  809. /* i2sdata */
  810. {
  811. false, /* output_enable */
  812. 48000, /* frequency */
  813. DRX_I2S_MODE_MASTER, /* mode */
  814. DRX_I2S_WORDLENGTH_32, /* word_length */
  815. DRX_I2S_POLARITY_RIGHT, /* polarity */
  816. DRX_I2S_FORMAT_WS_WITH_DATA /* format */
  817. },
  818. /* volume */
  819. {
  820. true, /* mute; */
  821. 0, /* volume */
  822. DRX_AUD_AVC_OFF, /* avc_mode */
  823. 0, /* avc_ref_level */
  824. DRX_AUD_AVC_MAX_GAIN_12DB, /* avc_max_gain */
  825. DRX_AUD_AVC_MAX_ATTEN_24DB, /* avc_max_atten */
  826. 0, /* strength_left */
  827. 0 /* strength_right */
  828. },
  829. DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
  830. /* ass_thresholds */
  831. {
  832. 440, /* A2 */
  833. 12, /* BTSC */
  834. 700, /* NICAM */
  835. },
  836. /* carrier */
  837. {
  838. /* a */
  839. {
  840. 42, /* thres */
  841. DRX_NO_CARRIER_NOISE, /* opt */
  842. 0, /* shift */
  843. 0 /* dco */
  844. },
  845. /* b */
  846. {
  847. 42, /* thres */
  848. DRX_NO_CARRIER_MUTE, /* opt */
  849. 0, /* shift */
  850. 0 /* dco */
  851. },
  852. },
  853. /* mixer */
  854. {
  855. DRX_AUD_SRC_STEREO_OR_A, /* source_i2s */
  856. DRX_AUD_I2S_MATRIX_STEREO, /* matrix_i2s */
  857. DRX_AUD_FM_MATRIX_SOUND_A /* matrix_fm */
  858. },
  859. DRX_AUD_DEVIATION_NORMAL, /* deviation */
  860. DRX_AUD_AVSYNC_OFF, /* av_sync */
  861. /* prescale */
  862. {
  863. DRX_AUD_MAX_FM_DEVIATION, /* fm_deviation */
  864. DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
  865. },
  866. DRX_AUD_FM_DEEMPH_75US, /* deemph */
  867. DRX_BTSC_STEREO, /* btsc_detect */
  868. 0, /* rds_data_counter */
  869. false /* rds_data_present */
  870. };
  871. /*-----------------------------------------------------------------------------
  872. STRUCTURES
  873. ----------------------------------------------------------------------------*/
  874. struct drxjeq_stat {
  875. u16 eq_mse;
  876. u8 eq_mode;
  877. u8 eq_ctrl;
  878. u8 eq_stat;
  879. };
  880. /* HI command */
  881. struct drxj_hi_cmd {
  882. u16 cmd;
  883. u16 param1;
  884. u16 param2;
  885. u16 param3;
  886. u16 param4;
  887. u16 param5;
  888. u16 param6;
  889. };
  890. /*============================================================================*/
  891. /*=== MICROCODE RELATED STRUCTURES ===========================================*/
  892. /*============================================================================*/
  893. /**
  894. * struct drxu_code_block_hdr - Structure of the microcode block headers
  895. *
  896. * @addr: Destination address of the data in this block
  897. * @size: Size of the block data following this header counted in
  898. * 16 bits words
  899. * @CRC: CRC value of the data block, only valid if CRC flag is
  900. * set.
  901. */
  902. struct drxu_code_block_hdr {
  903. u32 addr;
  904. u16 size;
  905. u16 flags;
  906. u16 CRC;
  907. };
  908. /*-----------------------------------------------------------------------------
  909. FUNCTIONS
  910. ----------------------------------------------------------------------------*/
  911. /* Some prototypes */
  912. static int
  913. hi_command(struct i2c_device_addr *dev_addr,
  914. const struct drxj_hi_cmd *cmd, u16 *result);
  915. static int
  916. ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
  917. static int
  918. ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
  919. static int power_down_aud(struct drx_demod_instance *demod);
  920. static int
  921. ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
  922. static int
  923. ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
  924. /*============================================================================*/
  925. /*============================================================================*/
  926. /*== HELPER FUNCTIONS ==*/
  927. /*============================================================================*/
  928. /*============================================================================*/
  929. /*============================================================================*/
  930. /*
  931. * \fn u32 frac28(u32 N, u32 D)
  932. * \brief Compute: (1<<28)*N/D
  933. * \param N 32 bits
  934. * \param D 32 bits
  935. * \return (1<<28)*N/D
  936. * This function is used to avoid floating-point calculations as they may
  937. * not be present on the target platform.
  938. * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
  939. * fraction used for setting the Frequency Shifter registers.
  940. * N and D can hold numbers up to width: 28-bits.
  941. * The 4 bits integer part and the 28 bits fractional part are calculated.
  942. * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
  943. * N: 0...(1<<28)-1 = 268435454
  944. * D: 0...(1<<28)-1
  945. * Q: 0...(1<<32)-1
  946. */
  947. static u32 frac28(u32 N, u32 D)
  948. {
  949. int i = 0;
  950. u32 Q1 = 0;
  951. u32 R0 = 0;
  952. R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
  953. Q1 = N / D; /* integer part, only the 4 least significant bits
  954. will be visible in the result */
  955. /* division using radix 16, 7 nibbles in the result */
  956. for (i = 0; i < 7; i++) {
  957. Q1 = (Q1 << 4) | R0 / D;
  958. R0 = (R0 % D) << 4;
  959. }
  960. /* rounding */
  961. if ((R0 >> 3) >= D)
  962. Q1++;
  963. return Q1;
  964. }
  965. /**
  966. * \fn u32 log1_times100( u32 x)
  967. * \brief Compute: 100*log10(x)
  968. * \param x 32 bits
  969. * \return 100*log10(x)
  970. *
  971. * 100*log10(x)
  972. * = 100*(log2(x)/log2(10)))
  973. * = (100*(2^15)*log2(x))/((2^15)*log2(10))
  974. * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
  975. * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
  976. * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
  977. *
  978. * where y = 2^k and 1<= (x/y) < 2
  979. */
  980. static u32 log1_times100(u32 x)
  981. {
  982. static const u8 scale = 15;
  983. static const u8 index_width = 5;
  984. /*
  985. log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
  986. 0 <= n < ((1<<INDEXWIDTH)+1)
  987. */
  988. static const u32 log2lut[] = {
  989. 0, /* 0.000000 */
  990. 290941, /* 290941.300628 */
  991. 573196, /* 573196.476418 */
  992. 847269, /* 847269.179851 */
  993. 1113620, /* 1113620.489452 */
  994. 1372674, /* 1372673.576986 */
  995. 1624818, /* 1624817.752104 */
  996. 1870412, /* 1870411.981536 */
  997. 2109788, /* 2109787.962654 */
  998. 2343253, /* 2343252.817465 */
  999. 2571091, /* 2571091.461923 */
  1000. 2793569, /* 2793568.696416 */
  1001. 3010931, /* 3010931.055901 */
  1002. 3223408, /* 3223408.452106 */
  1003. 3431216, /* 3431215.635215 */
  1004. 3634553, /* 3634553.498355 */
  1005. 3833610, /* 3833610.244726 */
  1006. 4028562, /* 4028562.434393 */
  1007. 4219576, /* 4219575.925308 */
  1008. 4406807, /* 4406806.721144 */
  1009. 4590402, /* 4590401.736809 */
  1010. 4770499, /* 4770499.491025 */
  1011. 4947231, /* 4947230.734179 */
  1012. 5120719, /* 5120719.018555 */
  1013. 5291081, /* 5291081.217197 */
  1014. 5458428, /* 5458427.996830 */
  1015. 5622864, /* 5622864.249668 */
  1016. 5784489, /* 5784489.488298 */
  1017. 5943398, /* 5943398.207380 */
  1018. 6099680, /* 6099680.215452 */
  1019. 6253421, /* 6253420.939751 */
  1020. 6404702, /* 6404701.706649 */
  1021. 6553600, /* 6553600.000000 */
  1022. };
  1023. u8 i = 0;
  1024. u32 y = 0;
  1025. u32 d = 0;
  1026. u32 k = 0;
  1027. u32 r = 0;
  1028. if (x == 0)
  1029. return 0;
  1030. /* Scale x (normalize) */
  1031. /* computing y in log(x/y) = log(x) - log(y) */
  1032. if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
  1033. for (k = scale; k > 0; k--) {
  1034. if (x & (((u32) 1) << scale))
  1035. break;
  1036. x <<= 1;
  1037. }
  1038. } else {
  1039. for (k = scale; k < 31; k++) {
  1040. if ((x & (((u32) (-1)) << (scale + 1))) == 0)
  1041. break;
  1042. x >>= 1;
  1043. }
  1044. }
  1045. /*
  1046. Now x has binary point between bit[scale] and bit[scale-1]
  1047. and 1.0 <= x < 2.0 */
  1048. /* correction for division: log(x) = log(x/y)+log(y) */
  1049. y = k * ((((u32) 1) << scale) * 200);
  1050. /* remove integer part */
  1051. x &= ((((u32) 1) << scale) - 1);
  1052. /* get index */
  1053. i = (u8) (x >> (scale - index_width));
  1054. /* compute delta (x-a) */
  1055. d = x & ((((u32) 1) << (scale - index_width)) - 1);
  1056. /* compute log, multiplication ( d* (.. )) must be within range ! */
  1057. y += log2lut[i] +
  1058. ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
  1059. /* Conver to log10() */
  1060. y /= 108853; /* (log2(10) << scale) */
  1061. r = (y >> 1);
  1062. /* rounding */
  1063. if (y & ((u32)1))
  1064. r++;
  1065. return r;
  1066. }
  1067. /**
  1068. * \fn u32 frac_times1e6( u16 N, u32 D)
  1069. * \brief Compute: (N/D) * 1000000.
  1070. * \param N nominator 16-bits.
  1071. * \param D denominator 32-bits.
  1072. * \return u32
  1073. * \retval ((N/D) * 1000000), 32 bits
  1074. *
  1075. * No check on D=0!
  1076. */
  1077. static u32 frac_times1e6(u32 N, u32 D)
  1078. {
  1079. u32 remainder = 0;
  1080. u32 frac = 0;
  1081. /*
  1082. frac = (N * 1000000) / D
  1083. To let it fit in a 32 bits computation:
  1084. frac = (N * (1000000 >> 4)) / (D >> 4)
  1085. This would result in a problem in case D < 16 (div by 0).
  1086. So we do it more elaborate as shown below.
  1087. */
  1088. frac = (((u32) N) * (1000000 >> 4)) / D;
  1089. frac <<= 4;
  1090. remainder = (((u32) N) * (1000000 >> 4)) % D;
  1091. remainder <<= 4;
  1092. frac += remainder / D;
  1093. remainder = remainder % D;
  1094. if ((remainder * 2) > D)
  1095. frac++;
  1096. return frac;
  1097. }
  1098. /*============================================================================*/
  1099. /**
  1100. * \brief Values for NICAM prescaler gain. Computed from dB to integer
  1101. * and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
  1102. *
  1103. */
  1104. static const u16 nicam_presc_table_val[43] = {
  1105. 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
  1106. 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
  1107. 18, 20, 23, 25, 28, 32, 36, 40, 45,
  1108. 51, 57, 64, 71, 80, 90, 101, 113, 127
  1109. };
  1110. /*============================================================================*/
  1111. /*== END HELPER FUNCTIONS ==*/
  1112. /*============================================================================*/
  1113. /*============================================================================*/
  1114. /*============================================================================*/
  1115. /*== DRXJ DAP FUNCTIONS ==*/
  1116. /*============================================================================*/
  1117. /*============================================================================*/
  1118. /*
  1119. This layer takes care of some device specific register access protocols:
  1120. -conversion to short address format
  1121. -access to audio block
  1122. This layer is placed between the drx_dap_fasi and the rest of the drxj
  1123. specific implementation. This layer can use address map knowledge whereas
  1124. dap_fasi may not use memory map knowledge.
  1125. * For audio currently only 16 bits read and write register access is
  1126. supported. More is not needed. RMW and 32 or 8 bit access on audio
  1127. registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
  1128. single/multi master) will be ignored.
  1129. TODO: check ignoring single/multimaster is ok for AUD access ?
  1130. */
  1131. #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
  1132. #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
  1133. /*============================================================================*/
  1134. /**
  1135. * \fn bool is_handled_by_aud_tr_if( u32 addr )
  1136. * \brief Check if this address is handled by the audio token ring interface.
  1137. * \param addr
  1138. * \return bool
  1139. * \retval true Yes, handled by audio token ring interface
  1140. * \retval false No, not handled by audio token ring interface
  1141. *
  1142. */
  1143. static
  1144. bool is_handled_by_aud_tr_if(u32 addr)
  1145. {
  1146. bool retval = false;
  1147. if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
  1148. (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
  1149. (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
  1150. retval = true;
  1151. }
  1152. return retval;
  1153. }
  1154. /*============================================================================*/
  1155. int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
  1156. u16 w_count,
  1157. u8 *wData,
  1158. struct i2c_device_addr *r_dev_addr,
  1159. u16 r_count, u8 *r_data)
  1160. {
  1161. struct drx39xxj_state *state;
  1162. struct i2c_msg msg[2];
  1163. unsigned int num_msgs;
  1164. if (w_dev_addr == NULL) {
  1165. /* Read only */
  1166. state = r_dev_addr->user_data;
  1167. msg[0].addr = r_dev_addr->i2c_addr >> 1;
  1168. msg[0].flags = I2C_M_RD;
  1169. msg[0].buf = r_data;
  1170. msg[0].len = r_count;
  1171. num_msgs = 1;
  1172. } else if (r_dev_addr == NULL) {
  1173. /* Write only */
  1174. state = w_dev_addr->user_data;
  1175. msg[0].addr = w_dev_addr->i2c_addr >> 1;
  1176. msg[0].flags = 0;
  1177. msg[0].buf = wData;
  1178. msg[0].len = w_count;
  1179. num_msgs = 1;
  1180. } else {
  1181. /* Both write and read */
  1182. state = w_dev_addr->user_data;
  1183. msg[0].addr = w_dev_addr->i2c_addr >> 1;
  1184. msg[0].flags = 0;
  1185. msg[0].buf = wData;
  1186. msg[0].len = w_count;
  1187. msg[1].addr = r_dev_addr->i2c_addr >> 1;
  1188. msg[1].flags = I2C_M_RD;
  1189. msg[1].buf = r_data;
  1190. msg[1].len = r_count;
  1191. num_msgs = 2;
  1192. }
  1193. if (state->i2c == NULL) {
  1194. pr_err("i2c was zero, aborting\n");
  1195. return 0;
  1196. }
  1197. if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
  1198. pr_warn("drx3933: I2C write/read failed\n");
  1199. return -EREMOTEIO;
  1200. }
  1201. #ifdef DJH_DEBUG
  1202. if (w_dev_addr == NULL || r_dev_addr == NULL)
  1203. return 0;
  1204. state = w_dev_addr->user_data;
  1205. if (state->i2c == NULL)
  1206. return 0;
  1207. msg[0].addr = w_dev_addr->i2c_addr;
  1208. msg[0].flags = 0;
  1209. msg[0].buf = wData;
  1210. msg[0].len = w_count;
  1211. msg[1].addr = r_dev_addr->i2c_addr;
  1212. msg[1].flags = I2C_M_RD;
  1213. msg[1].buf = r_data;
  1214. msg[1].len = r_count;
  1215. num_msgs = 2;
  1216. pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
  1217. w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
  1218. if (i2c_transfer(state->i2c, msg, 2) != 2) {
  1219. pr_warn("drx3933: I2C write/read failed\n");
  1220. return -EREMOTEIO;
  1221. }
  1222. #endif
  1223. return 0;
  1224. }
  1225. /*============================================================================*/
  1226. /******************************
  1227. *
  1228. * int drxdap_fasi_read_block (
  1229. * struct i2c_device_addr *dev_addr, -- address of I2C device
  1230. * u32 addr, -- address of chip register/memory
  1231. * u16 datasize, -- number of bytes to read
  1232. * u8 *data, -- data to receive
  1233. * u32 flags) -- special device flags
  1234. *
  1235. * Read block data from chip address. Because the chip is word oriented,
  1236. * the number of bytes to read must be even.
  1237. *
  1238. * Make sure that the buffer to receive the data is large enough.
  1239. *
  1240. * Although this function expects an even number of bytes, it is still byte
  1241. * oriented, and the data read back is NOT translated to the endianness of
  1242. * the target platform.
  1243. *
  1244. * Output:
  1245. * - 0 if reading was successful
  1246. * in that case: data read is in *data.
  1247. * - -EIO if anything went wrong
  1248. *
  1249. ******************************/
  1250. static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
  1251. u32 addr,
  1252. u16 datasize,
  1253. u8 *data, u32 flags)
  1254. {
  1255. u8 buf[4];
  1256. u16 bufx;
  1257. int rc;
  1258. u16 overhead_size = 0;
  1259. /* Check parameters ******************************************************* */
  1260. if (dev_addr == NULL)
  1261. return -EINVAL;
  1262. overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
  1263. (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
  1264. if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
  1265. ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
  1266. DRXDAP_FASI_LONG_FORMAT(addr)) ||
  1267. (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
  1268. ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
  1269. return -EINVAL;
  1270. }
  1271. /* ReadModifyWrite & mode flag bits are not allowed */
  1272. flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
  1273. #if DRXDAP_SINGLE_MASTER
  1274. flags |= DRXDAP_FASI_SINGLE_MASTER;
  1275. #endif
  1276. /* Read block from I2C **************************************************** */
  1277. do {
  1278. u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
  1279. datasize : DRXDAP_MAX_RCHUNKSIZE);
  1280. bufx = 0;
  1281. addr &= ~DRXDAP_FASI_FLAGS;
  1282. addr |= flags;
  1283. #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
  1284. /* short format address preferred but long format otherwise */
  1285. if (DRXDAP_FASI_LONG_FORMAT(addr)) {
  1286. #endif
  1287. #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
  1288. buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
  1289. buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
  1290. buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
  1291. buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
  1292. #endif
  1293. #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
  1294. } else {
  1295. #endif
  1296. #if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
  1297. buf[bufx++] = (u8) ((addr << 1) & 0xFF);
  1298. buf[bufx++] =
  1299. (u8) (((addr >> 16) & 0x0F) |
  1300. ((addr >> 18) & 0xF0));
  1301. #endif
  1302. #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
  1303. }
  1304. #endif
  1305. #if DRXDAP_SINGLE_MASTER
  1306. /*
  1307. * In single master mode, split the read and write actions.
  1308. * No special action is needed for write chunks here.
  1309. */
  1310. rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,
  1311. NULL, 0, NULL);
  1312. if (rc == 0)
  1313. rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data);
  1314. #else
  1315. /* In multi master mode, do everything in one RW action */
  1316. rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
  1317. data);
  1318. #endif
  1319. data += todo;
  1320. addr += (todo >> 1);
  1321. datasize -= todo;
  1322. } while (datasize && rc == 0);
  1323. return rc;
  1324. }
  1325. /******************************
  1326. *
  1327. * int drxdap_fasi_read_reg16 (
  1328. * struct i2c_device_addr *dev_addr, -- address of I2C device
  1329. * u32 addr, -- address of chip register/memory
  1330. * u16 *data, -- data to receive
  1331. * u32 flags) -- special device flags
  1332. *
  1333. * Read one 16-bit register or memory location. The data received back is
  1334. * converted back to the target platform's endianness.
  1335. *
  1336. * Output:
  1337. * - 0 if reading was successful
  1338. * in that case: read data is at *data
  1339. * - -EIO if anything went wrong
  1340. *
  1341. ******************************/
  1342. static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
  1343. u32 addr,
  1344. u16 *data, u32 flags)
  1345. {
  1346. u8 buf[sizeof(*data)];
  1347. int rc;
  1348. if (!data)
  1349. return -EINVAL;
  1350. rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
  1351. *data = buf[0] + (((u16) buf[1]) << 8);
  1352. return rc;
  1353. }
  1354. /******************************
  1355. *
  1356. * int drxdap_fasi_read_reg32 (
  1357. * struct i2c_device_addr *dev_addr, -- address of I2C device
  1358. * u32 addr, -- address of chip register/memory
  1359. * u32 *data, -- data to receive
  1360. * u32 flags) -- special device flags
  1361. *
  1362. * Read one 32-bit register or memory location. The data received back is
  1363. * converted back to the target platform's endianness.
  1364. *
  1365. * Output:
  1366. * - 0 if reading was successful
  1367. * in that case: read data is at *data
  1368. * - -EIO if anything went wrong
  1369. *
  1370. ******************************/
  1371. static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
  1372. u32 addr,
  1373. u32 *data, u32 flags)
  1374. {
  1375. u8 buf[sizeof(*data)];
  1376. int rc;
  1377. if (!data)
  1378. return -EINVAL;
  1379. rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
  1380. *data = (((u32) buf[0]) << 0) +
  1381. (((u32) buf[1]) << 8) +
  1382. (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
  1383. return rc;
  1384. }
  1385. /******************************
  1386. *
  1387. * int drxdap_fasi_write_block (
  1388. * struct i2c_device_addr *dev_addr, -- address of I2C device
  1389. * u32 addr, -- address of chip register/memory
  1390. * u16 datasize, -- number of bytes to read
  1391. * u8 *data, -- data to receive
  1392. * u32 flags) -- special device flags
  1393. *
  1394. * Write block data to chip address. Because the chip is word oriented,
  1395. * the number of bytes to write must be even.
  1396. *
  1397. * Although this function expects an even number of bytes, it is still byte
  1398. * oriented, and the data being written is NOT translated from the endianness of
  1399. * the target platform.
  1400. *
  1401. * Output:
  1402. * - 0 if writing was successful
  1403. * - -EIO if anything went wrong
  1404. *
  1405. ******************************/
  1406. static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
  1407. u32 addr,
  1408. u16 datasize,
  1409. u8 *data, u32 flags)
  1410. {
  1411. u8 buf[DRXDAP_MAX_WCHUNKSIZE];
  1412. int st = -EIO;
  1413. int first_err = 0;
  1414. u16 overhead_size = 0;
  1415. u16 block_size = 0;
  1416. /* Check parameters ******************************************************* */
  1417. if (dev_addr == NULL)
  1418. return -EINVAL;
  1419. overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
  1420. (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
  1421. if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
  1422. ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
  1423. DRXDAP_FASI_LONG_FORMAT(addr)) ||
  1424. (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
  1425. ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
  1426. return -EINVAL;
  1427. flags &= DRXDAP_FASI_FLAGS;
  1428. flags &= ~DRXDAP_FASI_MODEFLAGS;
  1429. #if DRXDAP_SINGLE_MASTER
  1430. flags |= DRXDAP_FASI_SINGLE_MASTER;
  1431. #endif
  1432. /* Write block to I2C ***************************************************** */
  1433. block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
  1434. do {
  1435. u16 todo = 0;
  1436. u16 bufx = 0;
  1437. /* Buffer device address */
  1438. addr &= ~DRXDAP_FASI_FLAGS;
  1439. addr |= flags;
  1440. #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
  1441. /* short format address preferred but long format otherwise */
  1442. if (DRXDAP_FASI_LONG_FORMAT(addr)) {
  1443. #endif
  1444. #if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
  1445. buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
  1446. buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
  1447. buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
  1448. buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
  1449. #endif
  1450. #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
  1451. } else {
  1452. #endif
  1453. #if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
  1454. buf[bufx++] = (u8) ((addr << 1) & 0xFF);
  1455. buf[bufx++] =
  1456. (u8) (((addr >> 16) & 0x0F) |
  1457. ((addr >> 18) & 0xF0));
  1458. #endif
  1459. #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
  1460. }
  1461. #endif
  1462. /*
  1463. In single master mode block_size can be 0. In such a case this I2C
  1464. sequense will be visible: (1) write address {i2c addr,
  1465. 4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
  1466. (3) write address (4) write data etc...
  1467. Address must be rewriten because HI is reset after data transport and
  1468. expects an address.
  1469. */
  1470. todo = (block_size < datasize ? block_size : datasize);
  1471. if (todo == 0) {
  1472. u16 overhead_size_i2c_addr = 0;
  1473. u16 data_block_size = 0;
  1474. overhead_size_i2c_addr =
  1475. (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
  1476. data_block_size =
  1477. (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
  1478. /* write device address */
  1479. st = drxbsp_i2c_write_read(dev_addr,
  1480. (u16) (bufx),
  1481. buf,
  1482. (struct i2c_device_addr *)(NULL),
  1483. 0, (u8 *)(NULL));
  1484. if ((st != 0) && (first_err == 0)) {
  1485. /* at the end, return the first error encountered */
  1486. first_err = st;
  1487. }
  1488. bufx = 0;
  1489. todo =
  1490. (data_block_size <
  1491. datasize ? data_block_size : datasize);
  1492. }
  1493. memcpy(&buf[bufx], data, todo);
  1494. /* write (address if can do and) data */
  1495. st = drxbsp_i2c_write_read(dev_addr,
  1496. (u16) (bufx + todo),
  1497. buf,
  1498. (struct i2c_device_addr *)(NULL),
  1499. 0, (u8 *)(NULL));
  1500. if ((st != 0) && (first_err == 0)) {
  1501. /* at the end, return the first error encountered */
  1502. first_err = st;
  1503. }
  1504. datasize -= todo;
  1505. data += todo;
  1506. addr += (todo >> 1);
  1507. } while (datasize);
  1508. return first_err;
  1509. }
  1510. /******************************
  1511. *
  1512. * int drxdap_fasi_write_reg16 (
  1513. * struct i2c_device_addr *dev_addr, -- address of I2C device
  1514. * u32 addr, -- address of chip register/memory
  1515. * u16 data, -- data to send
  1516. * u32 flags) -- special device flags
  1517. *
  1518. * Write one 16-bit register or memory location. The data being written is
  1519. * converted from the target platform's endianness to little endian.
  1520. *
  1521. * Output:
  1522. * - 0 if writing was successful
  1523. * - -EIO if anything went wrong
  1524. *
  1525. ******************************/
  1526. static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
  1527. u32 addr,
  1528. u16 data, u32 flags)
  1529. {
  1530. u8 buf[sizeof(data)];
  1531. buf[0] = (u8) ((data >> 0) & 0xFF);
  1532. buf[1] = (u8) ((data >> 8) & 0xFF);
  1533. return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
  1534. }
  1535. /******************************
  1536. *
  1537. * int drxdap_fasi_read_modify_write_reg16 (
  1538. * struct i2c_device_addr *dev_addr, -- address of I2C device
  1539. * u32 waddr, -- address of chip register/memory
  1540. * u32 raddr, -- chip address to read back from
  1541. * u16 wdata, -- data to send
  1542. * u16 *rdata) -- data to receive back
  1543. *
  1544. * Write 16-bit data, then read back the original contents of that location.
  1545. * Requires long addressing format to be allowed.
  1546. *
  1547. * Before sending data, the data is converted to little endian. The
  1548. * data received back is converted back to the target platform's endianness.
  1549. *
  1550. * WARNING: This function is only guaranteed to work if there is one
  1551. * master on the I2C bus.
  1552. *
  1553. * Output:
  1554. * - 0 if reading was successful
  1555. * in that case: read back data is at *rdata
  1556. * - -EIO if anything went wrong
  1557. *
  1558. ******************************/
  1559. static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
  1560. u32 waddr,
  1561. u32 raddr,
  1562. u16 wdata, u16 *rdata)
  1563. {
  1564. int rc = -EIO;
  1565. #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
  1566. if (rdata == NULL)
  1567. return -EINVAL;
  1568. rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
  1569. if (rc == 0)
  1570. rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
  1571. #endif
  1572. return rc;
  1573. }
  1574. /******************************
  1575. *
  1576. * int drxdap_fasi_write_reg32 (
  1577. * struct i2c_device_addr *dev_addr, -- address of I2C device
  1578. * u32 addr, -- address of chip register/memory
  1579. * u32 data, -- data to send
  1580. * u32 flags) -- special device flags
  1581. *
  1582. * Write one 32-bit register or memory location. The data being written is
  1583. * converted from the target platform's endianness to little endian.
  1584. *
  1585. * Output:
  1586. * - 0 if writing was successful
  1587. * - -EIO if anything went wrong
  1588. *
  1589. ******************************/
  1590. static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
  1591. u32 addr,
  1592. u32 data, u32 flags)
  1593. {
  1594. u8 buf[sizeof(data)];
  1595. buf[0] = (u8) ((data >> 0) & 0xFF);
  1596. buf[1] = (u8) ((data >> 8) & 0xFF);
  1597. buf[2] = (u8) ((data >> 16) & 0xFF);
  1598. buf[3] = (u8) ((data >> 24) & 0xFF);
  1599. return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
  1600. }
  1601. /*============================================================================*/
  1602. /**
  1603. * \fn int drxj_dap_rm_write_reg16short
  1604. * \brief Read modify write 16 bits audio register using short format only.
  1605. * \param dev_addr
  1606. * \param waddr Address to write to
  1607. * \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
  1608. * \param wdata Data to write
  1609. * \param rdata Buffer for data to read
  1610. * \return int
  1611. * \retval 0 Succes
  1612. * \retval -EIO Timeout, I2C error, illegal bank
  1613. *
  1614. * 16 bits register read modify write access using short addressing format only.
  1615. * Requires knowledge of the registermap, thus device dependent.
  1616. * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
  1617. *
  1618. */
  1619. /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
  1620. See comments drxj_dap_read_modify_write_reg16 */
  1621. #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
  1622. static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
  1623. u32 waddr,
  1624. u32 raddr,
  1625. u16 wdata, u16 *rdata)
  1626. {
  1627. int rc;
  1628. if (rdata == NULL)
  1629. return -EINVAL;
  1630. /* Set RMW flag */
  1631. rc = drxdap_fasi_write_reg16(dev_addr,
  1632. SIO_HI_RA_RAM_S0_FLG_ACC__A,
  1633. SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
  1634. 0x0000);
  1635. if (rc == 0) {
  1636. /* Write new data: triggers RMW */
  1637. rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
  1638. 0x0000);
  1639. }
  1640. if (rc == 0) {
  1641. /* Read old data */
  1642. rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
  1643. 0x0000);
  1644. }
  1645. if (rc == 0) {
  1646. /* Reset RMW flag */
  1647. rc = drxdap_fasi_write_reg16(dev_addr,
  1648. SIO_HI_RA_RAM_S0_FLG_ACC__A,
  1649. 0, 0x0000);
  1650. }
  1651. return rc;
  1652. }
  1653. #endif
  1654. /*============================================================================*/
  1655. static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
  1656. u32 waddr,
  1657. u32 raddr,
  1658. u16 wdata, u16 *rdata)
  1659. {
  1660. /* TODO: correct short/long addressing format decision,
  1661. now long format has higher prio then short because short also
  1662. needs virt bnks (not impl yet) for certain audio registers */
  1663. #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
  1664. return drxdap_fasi_read_modify_write_reg16(dev_addr,
  1665. waddr,
  1666. raddr, wdata, rdata);
  1667. #else
  1668. return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
  1669. #endif
  1670. }
  1671. /*============================================================================*/
  1672. /**
  1673. * \fn int drxj_dap_read_aud_reg16
  1674. * \brief Read 16 bits audio register
  1675. * \param dev_addr
  1676. * \param addr
  1677. * \param data
  1678. * \return int
  1679. * \retval 0 Succes
  1680. * \retval -EIO Timeout, I2C error, illegal bank
  1681. *
  1682. * 16 bits register read access via audio token ring interface.
  1683. *
  1684. */
  1685. static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
  1686. u32 addr, u16 *data)
  1687. {
  1688. u32 start_timer = 0;
  1689. u32 current_timer = 0;
  1690. u32 delta_timer = 0;
  1691. u16 tr_status = 0;
  1692. int stat = -EIO;
  1693. /* No read possible for bank 3, return with error */
  1694. if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
  1695. stat = -EINVAL;
  1696. } else {
  1697. const u32 write_bit = ((dr_xaddr_t) 1) << 16;
  1698. /* Force reset write bit */
  1699. addr &= (~write_bit);
  1700. /* Set up read */
  1701. start_timer = jiffies_to_msecs(jiffies);
  1702. do {
  1703. /* RMW to aud TR IF until request is granted or timeout */
  1704. stat = drxj_dap_read_modify_write_reg16(dev_addr,
  1705. addr,
  1706. SIO_HI_RA_RAM_S0_RMWBUF__A,
  1707. 0x0000, &tr_status);
  1708. if (stat != 0)
  1709. break;
  1710. current_timer = jiffies_to_msecs(jiffies);
  1711. delta_timer = current_timer - start_timer;
  1712. if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
  1713. stat = -EIO;
  1714. break;
  1715. }
  1716. } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
  1717. AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
  1718. ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
  1719. AUD_TOP_TR_CTR_FIFO_FULL_FULL));
  1720. } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
  1721. /* Wait for read ready status or timeout */
  1722. if (stat == 0) {
  1723. start_timer = jiffies_to_msecs(jiffies);
  1724. while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
  1725. AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
  1726. stat = drxj_dap_read_reg16(dev_addr,
  1727. AUD_TOP_TR_CTR__A,
  1728. &tr_status, 0x0000);
  1729. if (stat != 0)
  1730. break;
  1731. current_timer = jiffies_to_msecs(jiffies);
  1732. delta_timer = current_timer - start_timer;
  1733. if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
  1734. stat = -EIO;
  1735. break;
  1736. }
  1737. } /* while ( ... ) */
  1738. }
  1739. /* Read value */
  1740. if (stat == 0)
  1741. stat = drxj_dap_read_modify_write_reg16(dev_addr,
  1742. AUD_TOP_TR_RD_REG__A,
  1743. SIO_HI_RA_RAM_S0_RMWBUF__A,
  1744. 0x0000, data);
  1745. return stat;
  1746. }
  1747. /*============================================================================*/
  1748. static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
  1749. u32 addr,
  1750. u16 *data, u32 flags)
  1751. {
  1752. int stat = -EIO;
  1753. /* Check param */
  1754. if ((dev_addr == NULL) || (data == NULL))
  1755. return -EINVAL;
  1756. if (is_handled_by_aud_tr_if(addr))
  1757. stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
  1758. else
  1759. stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
  1760. return stat;
  1761. }
  1762. /*============================================================================*/
  1763. /**
  1764. * \fn int drxj_dap_write_aud_reg16
  1765. * \brief Write 16 bits audio register
  1766. * \param dev_addr
  1767. * \param addr
  1768. * \param data
  1769. * \return int
  1770. * \retval 0 Succes
  1771. * \retval -EIO Timeout, I2C error, illegal bank
  1772. *
  1773. * 16 bits register write access via audio token ring interface.
  1774. *
  1775. */
  1776. static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
  1777. u32 addr, u16 data)
  1778. {
  1779. int stat = -EIO;
  1780. /* No write possible for bank 2, return with error */
  1781. if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
  1782. stat = -EINVAL;
  1783. } else {
  1784. u32 start_timer = 0;
  1785. u32 current_timer = 0;
  1786. u32 delta_timer = 0;
  1787. u16 tr_status = 0;
  1788. const u32 write_bit = ((dr_xaddr_t) 1) << 16;
  1789. /* Force write bit */
  1790. addr |= write_bit;
  1791. start_timer = jiffies_to_msecs(jiffies);
  1792. do {
  1793. /* RMW to aud TR IF until request is granted or timeout */
  1794. stat = drxj_dap_read_modify_write_reg16(dev_addr,
  1795. addr,
  1796. SIO_HI_RA_RAM_S0_RMWBUF__A,
  1797. data, &tr_status);
  1798. if (stat != 0)
  1799. break;
  1800. current_timer = jiffies_to_msecs(jiffies);
  1801. delta_timer = current_timer - start_timer;
  1802. if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
  1803. stat = -EIO;
  1804. break;
  1805. }
  1806. } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
  1807. AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
  1808. ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
  1809. AUD_TOP_TR_CTR_FIFO_FULL_FULL));
  1810. } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
  1811. return stat;
  1812. }
  1813. /*============================================================================*/
  1814. static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
  1815. u32 addr,
  1816. u16 data, u32 flags)
  1817. {
  1818. int stat = -EIO;
  1819. /* Check param */
  1820. if (dev_addr == NULL)
  1821. return -EINVAL;
  1822. if (is_handled_by_aud_tr_if(addr))
  1823. stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
  1824. else
  1825. stat = drxdap_fasi_write_reg16(dev_addr,
  1826. addr, data, flags);
  1827. return stat;
  1828. }
  1829. /*============================================================================*/
  1830. /* Free data ram in SIO HI */
  1831. #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
  1832. #define SIO_HI_RA_RAM_USR_END__A 0x420060
  1833. #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
  1834. #define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
  1835. #define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
  1836. #define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
  1837. /**
  1838. * \fn int drxj_dap_atomic_read_write_block()
  1839. * \brief Basic access routine for atomic read or write access
  1840. * \param dev_addr pointer to i2c dev address
  1841. * \param addr destination/source address
  1842. * \param datasize size of data buffer in bytes
  1843. * \param data pointer to data buffer
  1844. * \return int
  1845. * \retval 0 Succes
  1846. * \retval -EIO Timeout, I2C error, illegal bank
  1847. *
  1848. */
  1849. static
  1850. int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
  1851. u32 addr,
  1852. u16 datasize,
  1853. u8 *data, bool read_flag)
  1854. {
  1855. struct drxj_hi_cmd hi_cmd;
  1856. int rc;
  1857. u16 word;
  1858. u16 dummy = 0;
  1859. u16 i = 0;
  1860. /* Parameter check */
  1861. if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
  1862. return -EINVAL;
  1863. /* Set up HI parameters to read or write n bytes */
  1864. hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
  1865. hi_cmd.param1 =
  1866. (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
  1867. DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
  1868. hi_cmd.param2 =
  1869. (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
  1870. hi_cmd.param3 = (u16) ((datasize / 2) - 1);
  1871. if (!read_flag)
  1872. hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
  1873. else
  1874. hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
  1875. hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
  1876. DRXDAP_FASI_ADDR2BANK(addr));
  1877. hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
  1878. if (!read_flag) {
  1879. /* write data to buffer */
  1880. for (i = 0; i < (datasize / 2); i++) {
  1881. word = ((u16) data[2 * i]);
  1882. word += (((u16) data[(2 * i) + 1]) << 8);
  1883. drxj_dap_write_reg16(dev_addr,
  1884. (DRXJ_HI_ATOMIC_BUF_START + i),
  1885. word, 0);
  1886. }
  1887. }
  1888. rc = hi_command(dev_addr, &hi_cmd, &dummy);
  1889. if (rc != 0) {
  1890. pr_err("error %d\n", rc);
  1891. goto rw_error;
  1892. }
  1893. if (read_flag) {
  1894. /* read data from buffer */
  1895. for (i = 0; i < (datasize / 2); i++) {
  1896. drxj_dap_read_reg16(dev_addr,
  1897. (DRXJ_HI_ATOMIC_BUF_START + i),
  1898. &word, 0);
  1899. data[2 * i] = (u8) (word & 0xFF);
  1900. data[(2 * i) + 1] = (u8) (word >> 8);
  1901. }
  1902. }
  1903. return 0;
  1904. rw_error:
  1905. return rc;
  1906. }
  1907. /*============================================================================*/
  1908. /**
  1909. * \fn int drxj_dap_atomic_read_reg32()
  1910. * \brief Atomic read of 32 bits words
  1911. */
  1912. static
  1913. int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
  1914. u32 addr,
  1915. u32 *data, u32 flags)
  1916. {
  1917. u8 buf[sizeof(*data)] = { 0 };
  1918. int rc = -EIO;
  1919. u32 word = 0;
  1920. if (!data)
  1921. return -EINVAL;
  1922. rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
  1923. sizeof(*data), buf, true);
  1924. if (rc < 0)
  1925. return 0;
  1926. word = (u32) buf[3];
  1927. word <<= 8;
  1928. word |= (u32) buf[2];
  1929. word <<= 8;
  1930. word |= (u32) buf[1];
  1931. word <<= 8;
  1932. word |= (u32) buf[0];
  1933. *data = word;
  1934. return rc;
  1935. }
  1936. /*============================================================================*/
  1937. /*============================================================================*/
  1938. /*== END DRXJ DAP FUNCTIONS ==*/
  1939. /*============================================================================*/
  1940. /*============================================================================*/
  1941. /*============================================================================*/
  1942. /*== HOST INTERFACE FUNCTIONS ==*/
  1943. /*============================================================================*/
  1944. /*============================================================================*/
  1945. /**
  1946. * \fn int hi_cfg_command()
  1947. * \brief Configure HI with settings stored in the demod structure.
  1948. * \param demod Demodulator.
  1949. * \return int.
  1950. *
  1951. * This routine was created because to much orthogonal settings have
  1952. * been put into one HI API function (configure). Especially the I2C bridge
  1953. * enable/disable should not need re-configuration of the HI.
  1954. *
  1955. */
  1956. static int hi_cfg_command(const struct drx_demod_instance *demod)
  1957. {
  1958. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  1959. struct drxj_hi_cmd hi_cmd;
  1960. u16 result = 0;
  1961. int rc;
  1962. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  1963. hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
  1964. hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
  1965. hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
  1966. hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
  1967. hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
  1968. hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
  1969. hi_cmd.param6 = ext_attr->hi_cfg_transmit;
  1970. rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
  1971. if (rc != 0) {
  1972. pr_err("error %d\n", rc);
  1973. goto rw_error;
  1974. }
  1975. /* Reset power down flag (set one call only) */
  1976. ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
  1977. return 0;
  1978. rw_error:
  1979. return rc;
  1980. }
  1981. /**
  1982. * \fn int hi_command()
  1983. * \brief Configure HI with settings stored in the demod structure.
  1984. * \param dev_addr I2C address.
  1985. * \param cmd HI command.
  1986. * \param result HI command result.
  1987. * \return int.
  1988. *
  1989. * Sends command to HI
  1990. *
  1991. */
  1992. static int
  1993. hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
  1994. {
  1995. u16 wait_cmd = 0;
  1996. u16 nr_retries = 0;
  1997. bool powerdown_cmd = false;
  1998. int rc;
  1999. /* Write parameters */
  2000. switch (cmd->cmd) {
  2001. case SIO_HI_RA_RAM_CMD_CONFIG:
  2002. case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
  2003. rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
  2004. if (rc != 0) {
  2005. pr_err("error %d\n", rc);
  2006. goto rw_error;
  2007. }
  2008. rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
  2009. if (rc != 0) {
  2010. pr_err("error %d\n", rc);
  2011. goto rw_error;
  2012. }
  2013. rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
  2014. if (rc != 0) {
  2015. pr_err("error %d\n", rc);
  2016. goto rw_error;
  2017. }
  2018. rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
  2019. if (rc != 0) {
  2020. pr_err("error %d\n", rc);
  2021. goto rw_error;
  2022. }
  2023. /* fallthrough */
  2024. case SIO_HI_RA_RAM_CMD_BRDCTRL:
  2025. rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
  2026. if (rc != 0) {
  2027. pr_err("error %d\n", rc);
  2028. goto rw_error;
  2029. }
  2030. rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
  2031. if (rc != 0) {
  2032. pr_err("error %d\n", rc);
  2033. goto rw_error;
  2034. }
  2035. /* fallthrough */
  2036. case SIO_HI_RA_RAM_CMD_NULL:
  2037. /* No parameters */
  2038. break;
  2039. default:
  2040. return -EINVAL;
  2041. break;
  2042. }
  2043. /* Write command */
  2044. rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
  2045. if (rc != 0) {
  2046. pr_err("error %d\n", rc);
  2047. goto rw_error;
  2048. }
  2049. if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
  2050. msleep(1);
  2051. /* Detect power down to ommit reading result */
  2052. powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
  2053. (((cmd->
  2054. param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
  2055. == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
  2056. if (!powerdown_cmd) {
  2057. /* Wait until command rdy */
  2058. do {
  2059. nr_retries++;
  2060. if (nr_retries > DRXJ_MAX_RETRIES) {
  2061. pr_err("timeout\n");
  2062. goto rw_error;
  2063. }
  2064. rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
  2065. if (rc != 0) {
  2066. pr_err("error %d\n", rc);
  2067. goto rw_error;
  2068. }
  2069. } while (wait_cmd != 0);
  2070. /* Read result */
  2071. rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
  2072. if (rc != 0) {
  2073. pr_err("error %d\n", rc);
  2074. goto rw_error;
  2075. }
  2076. }
  2077. /* if ( powerdown_cmd == true ) */
  2078. return 0;
  2079. rw_error:
  2080. return rc;
  2081. }
  2082. /**
  2083. * \fn int init_hi( const struct drx_demod_instance *demod )
  2084. * \brief Initialise and configurate HI.
  2085. * \param demod pointer to demod data.
  2086. * \return int Return status.
  2087. * \retval 0 Success.
  2088. * \retval -EIO Failure.
  2089. *
  2090. * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
  2091. * Need to store configuration in driver because of the way I2C
  2092. * bridging is controlled.
  2093. *
  2094. */
  2095. static int init_hi(const struct drx_demod_instance *demod)
  2096. {
  2097. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  2098. struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
  2099. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
  2100. int rc;
  2101. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  2102. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  2103. dev_addr = demod->my_i2c_dev_addr;
  2104. /* PATCH for bug 5003, HI ucode v3.1.0 */
  2105. rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);
  2106. if (rc != 0) {
  2107. pr_err("error %d\n", rc);
  2108. goto rw_error;
  2109. }
  2110. /* Timing div, 250ns/Psys */
  2111. /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
  2112. ext_attr->hi_cfg_timing_div =
  2113. (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
  2114. /* Clipping */
  2115. if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
  2116. ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
  2117. /* Bridge delay, uses oscilator clock */
  2118. /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
  2119. /* SDA brdige delay */
  2120. ext_attr->hi_cfg_bridge_delay =
  2121. (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
  2122. 1000;
  2123. /* Clipping */
  2124. if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
  2125. ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
  2126. /* SCL bridge delay, same as SDA for now */
  2127. ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
  2128. SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
  2129. /* Wakeup key, setting the read flag (as suggest in the documentation) does
  2130. not always result into a working solution (barebones worked VI2C failed).
  2131. Not setting the bit works in all cases . */
  2132. ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
  2133. /* port/bridge/power down ctrl */
  2134. ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
  2135. /* transit mode time out delay and watch dog divider */
  2136. ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
  2137. rc = hi_cfg_command(demod);
  2138. if (rc != 0) {
  2139. pr_err("error %d\n", rc);
  2140. goto rw_error;
  2141. }
  2142. return 0;
  2143. rw_error:
  2144. return rc;
  2145. }
  2146. /*============================================================================*/
  2147. /*== END HOST INTERFACE FUNCTIONS ==*/
  2148. /*============================================================================*/
  2149. /*============================================================================*/
  2150. /*============================================================================*/
  2151. /*== AUXILIARY FUNCTIONS ==*/
  2152. /*============================================================================*/
  2153. /*============================================================================*/
  2154. /**
  2155. * \fn int get_device_capabilities()
  2156. * \brief Get and store device capabilities.
  2157. * \param demod Pointer to demodulator instance.
  2158. * \return int.
  2159. * \return 0 Success
  2160. * \retval -EIO Failure
  2161. *
  2162. * Depending on pulldowns on MDx pins the following internals are set:
  2163. * * common_attr->osc_clock_freq
  2164. * * ext_attr->has_lna
  2165. * * ext_attr->has_ntsc
  2166. * * ext_attr->has_btsc
  2167. * * ext_attr->has_oob
  2168. *
  2169. */
  2170. static int get_device_capabilities(struct drx_demod_instance *demod)
  2171. {
  2172. struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
  2173. struct drxj_data *ext_attr = (struct drxj_data *) NULL;
  2174. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
  2175. u16 sio_pdr_ohw_cfg = 0;
  2176. u32 sio_top_jtagid_lo = 0;
  2177. u16 bid = 0;
  2178. int rc;
  2179. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  2180. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  2181. dev_addr = demod->my_i2c_dev_addr;
  2182. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
  2183. if (rc != 0) {
  2184. pr_err("error %d\n", rc);
  2185. goto rw_error;
  2186. }
  2187. rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
  2188. if (rc != 0) {
  2189. pr_err("error %d\n", rc);
  2190. goto rw_error;
  2191. }
  2192. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
  2193. if (rc != 0) {
  2194. pr_err("error %d\n", rc);
  2195. goto rw_error;
  2196. }
  2197. switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
  2198. case 0:
  2199. /* ignore (bypass ?) */
  2200. break;
  2201. case 1:
  2202. /* 27 MHz */
  2203. common_attr->osc_clock_freq = 27000;
  2204. break;
  2205. case 2:
  2206. /* 20.25 MHz */
  2207. common_attr->osc_clock_freq = 20250;
  2208. break;
  2209. case 3:
  2210. /* 4 MHz */
  2211. common_attr->osc_clock_freq = 4000;
  2212. break;
  2213. default:
  2214. return -EIO;
  2215. }
  2216. /*
  2217. Determine device capabilities
  2218. Based on pinning v47
  2219. */
  2220. rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
  2221. if (rc != 0) {
  2222. pr_err("error %d\n", rc);
  2223. goto rw_error;
  2224. }
  2225. ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
  2226. switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
  2227. case 0x31:
  2228. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
  2229. if (rc != 0) {
  2230. pr_err("error %d\n", rc);
  2231. goto rw_error;
  2232. }
  2233. rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
  2234. if (rc != 0) {
  2235. pr_err("error %d\n", rc);
  2236. goto rw_error;
  2237. }
  2238. bid = (bid >> 10) & 0xf;
  2239. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
  2240. if (rc != 0) {
  2241. pr_err("error %d\n", rc);
  2242. goto rw_error;
  2243. }
  2244. ext_attr->has_lna = true;
  2245. ext_attr->has_ntsc = false;
  2246. ext_attr->has_btsc = false;
  2247. ext_attr->has_oob = false;
  2248. ext_attr->has_smatx = true;
  2249. ext_attr->has_smarx = false;
  2250. ext_attr->has_gpio = false;
  2251. ext_attr->has_irqn = false;
  2252. break;
  2253. case 0x33:
  2254. ext_attr->has_lna = false;
  2255. ext_attr->has_ntsc = false;
  2256. ext_attr->has_btsc = false;
  2257. ext_attr->has_oob = false;
  2258. ext_attr->has_smatx = true;
  2259. ext_attr->has_smarx = false;
  2260. ext_attr->has_gpio = false;
  2261. ext_attr->has_irqn = false;
  2262. break;
  2263. case 0x45:
  2264. ext_attr->has_lna = true;
  2265. ext_attr->has_ntsc = true;
  2266. ext_attr->has_btsc = false;
  2267. ext_attr->has_oob = false;
  2268. ext_attr->has_smatx = true;
  2269. ext_attr->has_smarx = true;
  2270. ext_attr->has_gpio = true;
  2271. ext_attr->has_irqn = false;
  2272. break;
  2273. case 0x46:
  2274. ext_attr->has_lna = false;
  2275. ext_attr->has_ntsc = true;
  2276. ext_attr->has_btsc = false;
  2277. ext_attr->has_oob = false;
  2278. ext_attr->has_smatx = true;
  2279. ext_attr->has_smarx = true;
  2280. ext_attr->has_gpio = true;
  2281. ext_attr->has_irqn = false;
  2282. break;
  2283. case 0x41:
  2284. ext_attr->has_lna = true;
  2285. ext_attr->has_ntsc = true;
  2286. ext_attr->has_btsc = true;
  2287. ext_attr->has_oob = false;
  2288. ext_attr->has_smatx = true;
  2289. ext_attr->has_smarx = true;
  2290. ext_attr->has_gpio = true;
  2291. ext_attr->has_irqn = false;
  2292. break;
  2293. case 0x43:
  2294. ext_attr->has_lna = false;
  2295. ext_attr->has_ntsc = true;
  2296. ext_attr->has_btsc = true;
  2297. ext_attr->has_oob = false;
  2298. ext_attr->has_smatx = true;
  2299. ext_attr->has_smarx = true;
  2300. ext_attr->has_gpio = true;
  2301. ext_attr->has_irqn = false;
  2302. break;
  2303. case 0x32:
  2304. ext_attr->has_lna = true;
  2305. ext_attr->has_ntsc = false;
  2306. ext_attr->has_btsc = false;
  2307. ext_attr->has_oob = true;
  2308. ext_attr->has_smatx = true;
  2309. ext_attr->has_smarx = true;
  2310. ext_attr->has_gpio = true;
  2311. ext_attr->has_irqn = true;
  2312. break;
  2313. case 0x34:
  2314. ext_attr->has_lna = false;
  2315. ext_attr->has_ntsc = true;
  2316. ext_attr->has_btsc = true;
  2317. ext_attr->has_oob = true;
  2318. ext_attr->has_smatx = true;
  2319. ext_attr->has_smarx = true;
  2320. ext_attr->has_gpio = true;
  2321. ext_attr->has_irqn = true;
  2322. break;
  2323. case 0x42:
  2324. ext_attr->has_lna = true;
  2325. ext_attr->has_ntsc = true;
  2326. ext_attr->has_btsc = true;
  2327. ext_attr->has_oob = true;
  2328. ext_attr->has_smatx = true;
  2329. ext_attr->has_smarx = true;
  2330. ext_attr->has_gpio = true;
  2331. ext_attr->has_irqn = true;
  2332. break;
  2333. case 0x44:
  2334. ext_attr->has_lna = false;
  2335. ext_attr->has_ntsc = true;
  2336. ext_attr->has_btsc = true;
  2337. ext_attr->has_oob = true;
  2338. ext_attr->has_smatx = true;
  2339. ext_attr->has_smarx = true;
  2340. ext_attr->has_gpio = true;
  2341. ext_attr->has_irqn = true;
  2342. break;
  2343. default:
  2344. /* Unknown device variant */
  2345. return -EIO;
  2346. break;
  2347. }
  2348. return 0;
  2349. rw_error:
  2350. return rc;
  2351. }
  2352. /**
  2353. * \fn int power_up_device()
  2354. * \brief Power up device.
  2355. * \param demod Pointer to demodulator instance.
  2356. * \return int.
  2357. * \return 0 Success
  2358. * \retval -EIO Failure, I2C or max retries reached
  2359. *
  2360. */
  2361. #ifndef DRXJ_MAX_RETRIES_POWERUP
  2362. #define DRXJ_MAX_RETRIES_POWERUP 10
  2363. #endif
  2364. static int power_up_device(struct drx_demod_instance *demod)
  2365. {
  2366. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
  2367. u8 data = 0;
  2368. u16 retry_count = 0;
  2369. struct i2c_device_addr wake_up_addr;
  2370. dev_addr = demod->my_i2c_dev_addr;
  2371. wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
  2372. wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
  2373. wake_up_addr.user_data = dev_addr->user_data;
  2374. /*
  2375. * I2C access may fail in this case: no ack
  2376. * dummy write must be used to wake uop device, dummy read must be used to
  2377. * reset HI state machine (avoiding actual writes)
  2378. */
  2379. do {
  2380. data = 0;
  2381. drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
  2382. (struct i2c_device_addr *)(NULL), 0,
  2383. (u8 *)(NULL));
  2384. msleep(10);
  2385. retry_count++;
  2386. } while ((drxbsp_i2c_write_read
  2387. ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
  2388. &data)
  2389. != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
  2390. /* Need some recovery time .... */
  2391. msleep(10);
  2392. if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
  2393. return -EIO;
  2394. return 0;
  2395. }
  2396. /*----------------------------------------------------------------------------*/
  2397. /* MPEG Output Configuration Functions - begin */
  2398. /*----------------------------------------------------------------------------*/
  2399. /**
  2400. * \fn int ctrl_set_cfg_mpeg_output()
  2401. * \brief Set MPEG output configuration of the device.
  2402. * \param devmod Pointer to demodulator instance.
  2403. * \param cfg_data Pointer to mpeg output configuaration.
  2404. * \return int.
  2405. *
  2406. * Configure MPEG output parameters.
  2407. *
  2408. */
  2409. static int
  2410. ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
  2411. {
  2412. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
  2413. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  2414. struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
  2415. int rc;
  2416. u16 fec_oc_reg_mode = 0;
  2417. u16 fec_oc_reg_ipr_mode = 0;
  2418. u16 fec_oc_reg_ipr_invert = 0;
  2419. u32 max_bit_rate = 0;
  2420. u32 rcn_rate = 0;
  2421. u32 nr_bits = 0;
  2422. u16 sio_pdr_md_cfg = 0;
  2423. /* data mask for the output data byte */
  2424. u16 invert_data_mask =
  2425. FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
  2426. FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
  2427. FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
  2428. FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
  2429. /* check arguments */
  2430. if ((demod == NULL) || (cfg_data == NULL))
  2431. return -EINVAL;
  2432. dev_addr = demod->my_i2c_dev_addr;
  2433. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  2434. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  2435. if (cfg_data->enable_mpeg_output == true) {
  2436. /* quick and dirty patch to set MPEG incase current std is not
  2437. producing MPEG */
  2438. switch (ext_attr->standard) {
  2439. case DRX_STANDARD_8VSB:
  2440. case DRX_STANDARD_ITU_A:
  2441. case DRX_STANDARD_ITU_B:
  2442. case DRX_STANDARD_ITU_C:
  2443. break;
  2444. default:
  2445. return 0;
  2446. }
  2447. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
  2448. if (rc != 0) {
  2449. pr_err("error %d\n", rc);
  2450. goto rw_error;
  2451. }
  2452. switch (ext_attr->standard) {
  2453. case DRX_STANDARD_8VSB:
  2454. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
  2455. if (rc != 0) {
  2456. pr_err("error %d\n", rc);
  2457. goto rw_error;
  2458. } /* 2048 bytes fifo ram */
  2459. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
  2460. if (rc != 0) {
  2461. pr_err("error %d\n", rc);
  2462. goto rw_error;
  2463. }
  2464. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
  2465. if (rc != 0) {
  2466. pr_err("error %d\n", rc);
  2467. goto rw_error;
  2468. }
  2469. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
  2470. if (rc != 0) {
  2471. pr_err("error %d\n", rc);
  2472. goto rw_error;
  2473. }
  2474. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
  2475. if (rc != 0) {
  2476. pr_err("error %d\n", rc);
  2477. goto rw_error;
  2478. }
  2479. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
  2480. if (rc != 0) {
  2481. pr_err("error %d\n", rc);
  2482. goto rw_error;
  2483. }
  2484. /* Low Water Mark for synchronization */
  2485. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
  2486. if (rc != 0) {
  2487. pr_err("error %d\n", rc);
  2488. goto rw_error;
  2489. }
  2490. /* High Water Mark for synchronization */
  2491. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
  2492. if (rc != 0) {
  2493. pr_err("error %d\n", rc);
  2494. goto rw_error;
  2495. }
  2496. break;
  2497. case DRX_STANDARD_ITU_A:
  2498. case DRX_STANDARD_ITU_C:
  2499. switch (ext_attr->constellation) {
  2500. case DRX_CONSTELLATION_QAM256:
  2501. nr_bits = 8;
  2502. break;
  2503. case DRX_CONSTELLATION_QAM128:
  2504. nr_bits = 7;
  2505. break;
  2506. case DRX_CONSTELLATION_QAM64:
  2507. nr_bits = 6;
  2508. break;
  2509. case DRX_CONSTELLATION_QAM32:
  2510. nr_bits = 5;
  2511. break;
  2512. case DRX_CONSTELLATION_QAM16:
  2513. nr_bits = 4;
  2514. break;
  2515. default:
  2516. return -EIO;
  2517. } /* ext_attr->constellation */
  2518. /* max_bit_rate = symbol_rate * nr_bits * coef */
  2519. /* coef = 188/204 */
  2520. max_bit_rate =
  2521. (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
  2522. /* pass through b/c Annex A/c need following settings */
  2523. case DRX_STANDARD_ITU_B:
  2524. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
  2525. if (rc != 0) {
  2526. pr_err("error %d\n", rc);
  2527. goto rw_error;
  2528. }
  2529. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
  2530. if (rc != 0) {
  2531. pr_err("error %d\n", rc);
  2532. goto rw_error;
  2533. }
  2534. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
  2535. if (rc != 0) {
  2536. pr_err("error %d\n", rc);
  2537. goto rw_error;
  2538. }
  2539. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
  2540. if (rc != 0) {
  2541. pr_err("error %d\n", rc);
  2542. goto rw_error;
  2543. }
  2544. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
  2545. if (rc != 0) {
  2546. pr_err("error %d\n", rc);
  2547. goto rw_error;
  2548. }
  2549. if (cfg_data->static_clk == true) {
  2550. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
  2551. if (rc != 0) {
  2552. pr_err("error %d\n", rc);
  2553. goto rw_error;
  2554. }
  2555. } else {
  2556. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
  2557. if (rc != 0) {
  2558. pr_err("error %d\n", rc);
  2559. goto rw_error;
  2560. }
  2561. }
  2562. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
  2563. if (rc != 0) {
  2564. pr_err("error %d\n", rc);
  2565. goto rw_error;
  2566. }
  2567. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
  2568. if (rc != 0) {
  2569. pr_err("error %d\n", rc);
  2570. goto rw_error;
  2571. }
  2572. break;
  2573. default:
  2574. break;
  2575. } /* swtich (standard) */
  2576. /* Check insertion of the Reed-Solomon parity bytes */
  2577. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
  2578. if (rc != 0) {
  2579. pr_err("error %d\n", rc);
  2580. goto rw_error;
  2581. }
  2582. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
  2583. if (rc != 0) {
  2584. pr_err("error %d\n", rc);
  2585. goto rw_error;
  2586. }
  2587. if (cfg_data->insert_rs_byte == true) {
  2588. /* enable parity symbol forward */
  2589. fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
  2590. /* MVAL disable during parity bytes */
  2591. fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
  2592. switch (ext_attr->standard) {
  2593. case DRX_STANDARD_8VSB:
  2594. rcn_rate = 0x004854D3;
  2595. break;
  2596. case DRX_STANDARD_ITU_B:
  2597. fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
  2598. switch (ext_attr->constellation) {
  2599. case DRX_CONSTELLATION_QAM256:
  2600. rcn_rate = 0x008945E7;
  2601. break;
  2602. case DRX_CONSTELLATION_QAM64:
  2603. rcn_rate = 0x005F64D4;
  2604. break;
  2605. default:
  2606. return -EIO;
  2607. }
  2608. break;
  2609. case DRX_STANDARD_ITU_A:
  2610. case DRX_STANDARD_ITU_C:
  2611. /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
  2612. rcn_rate =
  2613. (frac28
  2614. (max_bit_rate,
  2615. (u32) (common_attr->sys_clock_freq / 8))) /
  2616. 188;
  2617. break;
  2618. default:
  2619. return -EIO;
  2620. } /* ext_attr->standard */
  2621. } else { /* insert_rs_byte == false */
  2622. /* disable parity symbol forward */
  2623. fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
  2624. /* MVAL enable during parity bytes */
  2625. fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
  2626. switch (ext_attr->standard) {
  2627. case DRX_STANDARD_8VSB:
  2628. rcn_rate = 0x0041605C;
  2629. break;
  2630. case DRX_STANDARD_ITU_B:
  2631. fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
  2632. switch (ext_attr->constellation) {
  2633. case DRX_CONSTELLATION_QAM256:
  2634. rcn_rate = 0x0082D6A0;
  2635. break;
  2636. case DRX_CONSTELLATION_QAM64:
  2637. rcn_rate = 0x005AEC1A;
  2638. break;
  2639. default:
  2640. return -EIO;
  2641. }
  2642. break;
  2643. case DRX_STANDARD_ITU_A:
  2644. case DRX_STANDARD_ITU_C:
  2645. /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
  2646. rcn_rate =
  2647. (frac28
  2648. (max_bit_rate,
  2649. (u32) (common_attr->sys_clock_freq / 8))) /
  2650. 204;
  2651. break;
  2652. default:
  2653. return -EIO;
  2654. } /* ext_attr->standard */
  2655. }
  2656. if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> clear ipr_mode[0] */
  2657. fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
  2658. } else { /* MPEG data output is serial -> set ipr_mode[0] */
  2659. fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
  2660. }
  2661. /* Control slective inversion of output bits */
  2662. if (cfg_data->invert_data == true)
  2663. fec_oc_reg_ipr_invert |= invert_data_mask;
  2664. else
  2665. fec_oc_reg_ipr_invert &= (~(invert_data_mask));
  2666. if (cfg_data->invert_err == true)
  2667. fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
  2668. else
  2669. fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
  2670. if (cfg_data->invert_str == true)
  2671. fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
  2672. else
  2673. fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
  2674. if (cfg_data->invert_val == true)
  2675. fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
  2676. else
  2677. fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
  2678. if (cfg_data->invert_clk == true)
  2679. fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
  2680. else
  2681. fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
  2682. if (cfg_data->static_clk == true) { /* Static mode */
  2683. u32 dto_rate = 0;
  2684. u32 bit_rate = 0;
  2685. u16 fec_oc_dto_burst_len = 0;
  2686. u16 fec_oc_dto_period = 0;
  2687. fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
  2688. switch (ext_attr->standard) {
  2689. case DRX_STANDARD_8VSB:
  2690. fec_oc_dto_period = 4;
  2691. if (cfg_data->insert_rs_byte == true)
  2692. fec_oc_dto_burst_len = 208;
  2693. break;
  2694. case DRX_STANDARD_ITU_A:
  2695. {
  2696. u32 symbol_rate_th = 6400000;
  2697. if (cfg_data->insert_rs_byte == true) {
  2698. fec_oc_dto_burst_len = 204;
  2699. symbol_rate_th = 5900000;
  2700. }
  2701. if (ext_attr->curr_symbol_rate >=
  2702. symbol_rate_th) {
  2703. fec_oc_dto_period = 0;
  2704. } else {
  2705. fec_oc_dto_period = 1;
  2706. }
  2707. }
  2708. break;
  2709. case DRX_STANDARD_ITU_B:
  2710. fec_oc_dto_period = 1;
  2711. if (cfg_data->insert_rs_byte == true)
  2712. fec_oc_dto_burst_len = 128;
  2713. break;
  2714. case DRX_STANDARD_ITU_C:
  2715. fec_oc_dto_period = 1;
  2716. if (cfg_data->insert_rs_byte == true)
  2717. fec_oc_dto_burst_len = 204;
  2718. break;
  2719. default:
  2720. return -EIO;
  2721. }
  2722. bit_rate =
  2723. common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
  2724. 2);
  2725. dto_rate =
  2726. frac28(bit_rate, common_attr->sys_clock_freq * 1000);
  2727. dto_rate >>= 3;
  2728. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
  2729. if (rc != 0) {
  2730. pr_err("error %d\n", rc);
  2731. goto rw_error;
  2732. }
  2733. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
  2734. if (rc != 0) {
  2735. pr_err("error %d\n", rc);
  2736. goto rw_error;
  2737. }
  2738. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
  2739. if (rc != 0) {
  2740. pr_err("error %d\n", rc);
  2741. goto rw_error;
  2742. }
  2743. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
  2744. if (rc != 0) {
  2745. pr_err("error %d\n", rc);
  2746. goto rw_error;
  2747. }
  2748. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
  2749. if (rc != 0) {
  2750. pr_err("error %d\n", rc);
  2751. goto rw_error;
  2752. }
  2753. if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
  2754. fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
  2755. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
  2756. if (rc != 0) {
  2757. pr_err("error %d\n", rc);
  2758. goto rw_error;
  2759. }
  2760. } else { /* Dynamic mode */
  2761. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
  2762. if (rc != 0) {
  2763. pr_err("error %d\n", rc);
  2764. goto rw_error;
  2765. }
  2766. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
  2767. if (rc != 0) {
  2768. pr_err("error %d\n", rc);
  2769. goto rw_error;
  2770. }
  2771. }
  2772. rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
  2773. if (rc != 0) {
  2774. pr_err("error %d\n", rc);
  2775. goto rw_error;
  2776. }
  2777. /* Write appropriate registers with requested configuration */
  2778. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
  2779. if (rc != 0) {
  2780. pr_err("error %d\n", rc);
  2781. goto rw_error;
  2782. }
  2783. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
  2784. if (rc != 0) {
  2785. pr_err("error %d\n", rc);
  2786. goto rw_error;
  2787. }
  2788. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
  2789. if (rc != 0) {
  2790. pr_err("error %d\n", rc);
  2791. goto rw_error;
  2792. }
  2793. /* enabling for both parallel and serial now */
  2794. /* Write magic word to enable pdr reg write */
  2795. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
  2796. if (rc != 0) {
  2797. pr_err("error %d\n", rc);
  2798. goto rw_error;
  2799. }
  2800. /* Set MPEG TS pads to outputmode */
  2801. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
  2802. if (rc != 0) {
  2803. pr_err("error %d\n", rc);
  2804. goto rw_error;
  2805. }
  2806. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
  2807. if (rc != 0) {
  2808. pr_err("error %d\n", rc);
  2809. goto rw_error;
  2810. }
  2811. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B | 0x03 << SIO_PDR_MCLK_CFG_MODE__B, 0);
  2812. if (rc != 0) {
  2813. pr_err("error %d\n", rc);
  2814. goto rw_error;
  2815. }
  2816. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
  2817. if (rc != 0) {
  2818. pr_err("error %d\n", rc);
  2819. goto rw_error;
  2820. }
  2821. sio_pdr_md_cfg =
  2822. MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
  2823. SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
  2824. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
  2825. if (rc != 0) {
  2826. pr_err("error %d\n", rc);
  2827. goto rw_error;
  2828. }
  2829. if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> set MD1 to MD7 to output mode */
  2830. sio_pdr_md_cfg =
  2831. MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
  2832. SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
  2833. SIO_PDR_MD0_CFG_MODE__B;
  2834. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
  2835. if (rc != 0) {
  2836. pr_err("error %d\n", rc);
  2837. goto rw_error;
  2838. }
  2839. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
  2840. if (rc != 0) {
  2841. pr_err("error %d\n", rc);
  2842. goto rw_error;
  2843. }
  2844. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
  2845. if (rc != 0) {
  2846. pr_err("error %d\n", rc);
  2847. goto rw_error;
  2848. }
  2849. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
  2850. if (rc != 0) {
  2851. pr_err("error %d\n", rc);
  2852. goto rw_error;
  2853. }
  2854. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
  2855. if (rc != 0) {
  2856. pr_err("error %d\n", rc);
  2857. goto rw_error;
  2858. }
  2859. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
  2860. if (rc != 0) {
  2861. pr_err("error %d\n", rc);
  2862. goto rw_error;
  2863. }
  2864. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
  2865. if (rc != 0) {
  2866. pr_err("error %d\n", rc);
  2867. goto rw_error;
  2868. }
  2869. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
  2870. if (rc != 0) {
  2871. pr_err("error %d\n", rc);
  2872. goto rw_error;
  2873. }
  2874. } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
  2875. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
  2876. if (rc != 0) {
  2877. pr_err("error %d\n", rc);
  2878. goto rw_error;
  2879. }
  2880. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
  2881. if (rc != 0) {
  2882. pr_err("error %d\n", rc);
  2883. goto rw_error;
  2884. }
  2885. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
  2886. if (rc != 0) {
  2887. pr_err("error %d\n", rc);
  2888. goto rw_error;
  2889. }
  2890. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
  2891. if (rc != 0) {
  2892. pr_err("error %d\n", rc);
  2893. goto rw_error;
  2894. }
  2895. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
  2896. if (rc != 0) {
  2897. pr_err("error %d\n", rc);
  2898. goto rw_error;
  2899. }
  2900. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
  2901. if (rc != 0) {
  2902. pr_err("error %d\n", rc);
  2903. goto rw_error;
  2904. }
  2905. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
  2906. if (rc != 0) {
  2907. pr_err("error %d\n", rc);
  2908. goto rw_error;
  2909. }
  2910. }
  2911. /* Enable Monitor Bus output over MPEG pads and ctl input */
  2912. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
  2913. if (rc != 0) {
  2914. pr_err("error %d\n", rc);
  2915. goto rw_error;
  2916. }
  2917. /* Write nomagic word to enable pdr reg write */
  2918. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
  2919. if (rc != 0) {
  2920. pr_err("error %d\n", rc);
  2921. goto rw_error;
  2922. }
  2923. } else {
  2924. /* Write magic word to enable pdr reg write */
  2925. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
  2926. if (rc != 0) {
  2927. pr_err("error %d\n", rc);
  2928. goto rw_error;
  2929. }
  2930. /* Set MPEG TS pads to inputmode */
  2931. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
  2932. if (rc != 0) {
  2933. pr_err("error %d\n", rc);
  2934. goto rw_error;
  2935. }
  2936. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
  2937. if (rc != 0) {
  2938. pr_err("error %d\n", rc);
  2939. goto rw_error;
  2940. }
  2941. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
  2942. if (rc != 0) {
  2943. pr_err("error %d\n", rc);
  2944. goto rw_error;
  2945. }
  2946. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
  2947. if (rc != 0) {
  2948. pr_err("error %d\n", rc);
  2949. goto rw_error;
  2950. }
  2951. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
  2952. if (rc != 0) {
  2953. pr_err("error %d\n", rc);
  2954. goto rw_error;
  2955. }
  2956. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
  2957. if (rc != 0) {
  2958. pr_err("error %d\n", rc);
  2959. goto rw_error;
  2960. }
  2961. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
  2962. if (rc != 0) {
  2963. pr_err("error %d\n", rc);
  2964. goto rw_error;
  2965. }
  2966. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
  2967. if (rc != 0) {
  2968. pr_err("error %d\n", rc);
  2969. goto rw_error;
  2970. }
  2971. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
  2972. if (rc != 0) {
  2973. pr_err("error %d\n", rc);
  2974. goto rw_error;
  2975. }
  2976. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
  2977. if (rc != 0) {
  2978. pr_err("error %d\n", rc);
  2979. goto rw_error;
  2980. }
  2981. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
  2982. if (rc != 0) {
  2983. pr_err("error %d\n", rc);
  2984. goto rw_error;
  2985. }
  2986. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
  2987. if (rc != 0) {
  2988. pr_err("error %d\n", rc);
  2989. goto rw_error;
  2990. }
  2991. /* Enable Monitor Bus output over MPEG pads and ctl input */
  2992. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
  2993. if (rc != 0) {
  2994. pr_err("error %d\n", rc);
  2995. goto rw_error;
  2996. }
  2997. /* Write nomagic word to enable pdr reg write */
  2998. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
  2999. if (rc != 0) {
  3000. pr_err("error %d\n", rc);
  3001. goto rw_error;
  3002. }
  3003. }
  3004. /* save values for restore after re-acquire */
  3005. common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
  3006. return 0;
  3007. rw_error:
  3008. return rc;
  3009. }
  3010. /*----------------------------------------------------------------------------*/
  3011. /*----------------------------------------------------------------------------*/
  3012. /* MPEG Output Configuration Functions - end */
  3013. /*----------------------------------------------------------------------------*/
  3014. /*----------------------------------------------------------------------------*/
  3015. /* miscellaneous configuartions - begin */
  3016. /*----------------------------------------------------------------------------*/
  3017. /**
  3018. * \fn int set_mpegtei_handling()
  3019. * \brief Activate MPEG TEI handling settings.
  3020. * \param devmod Pointer to demodulator instance.
  3021. * \return int.
  3022. *
  3023. * This routine should be called during a set channel of QAM/VSB
  3024. *
  3025. */
  3026. static int set_mpegtei_handling(struct drx_demod_instance *demod)
  3027. {
  3028. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  3029. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
  3030. int rc;
  3031. u16 fec_oc_dpr_mode = 0;
  3032. u16 fec_oc_snc_mode = 0;
  3033. u16 fec_oc_ems_mode = 0;
  3034. dev_addr = demod->my_i2c_dev_addr;
  3035. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  3036. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
  3037. if (rc != 0) {
  3038. pr_err("error %d\n", rc);
  3039. goto rw_error;
  3040. }
  3041. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
  3042. if (rc != 0) {
  3043. pr_err("error %d\n", rc);
  3044. goto rw_error;
  3045. }
  3046. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
  3047. if (rc != 0) {
  3048. pr_err("error %d\n", rc);
  3049. goto rw_error;
  3050. }
  3051. /* reset to default, allow TEI bit to be changed */
  3052. fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
  3053. fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
  3054. FEC_OC_SNC_MODE_CORR_DISABLE__M));
  3055. fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
  3056. if (ext_attr->disable_te_ihandling) {
  3057. /* do not change TEI bit */
  3058. fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
  3059. fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
  3060. ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
  3061. fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
  3062. }
  3063. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
  3064. if (rc != 0) {
  3065. pr_err("error %d\n", rc);
  3066. goto rw_error;
  3067. }
  3068. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
  3069. if (rc != 0) {
  3070. pr_err("error %d\n", rc);
  3071. goto rw_error;
  3072. }
  3073. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
  3074. if (rc != 0) {
  3075. pr_err("error %d\n", rc);
  3076. goto rw_error;
  3077. }
  3078. return 0;
  3079. rw_error:
  3080. return rc;
  3081. }
  3082. /*----------------------------------------------------------------------------*/
  3083. /**
  3084. * \fn int bit_reverse_mpeg_output()
  3085. * \brief Set MPEG output bit-endian settings.
  3086. * \param devmod Pointer to demodulator instance.
  3087. * \return int.
  3088. *
  3089. * This routine should be called during a set channel of QAM/VSB
  3090. *
  3091. */
  3092. static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
  3093. {
  3094. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  3095. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
  3096. int rc;
  3097. u16 fec_oc_ipr_mode = 0;
  3098. dev_addr = demod->my_i2c_dev_addr;
  3099. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  3100. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
  3101. if (rc != 0) {
  3102. pr_err("error %d\n", rc);
  3103. goto rw_error;
  3104. }
  3105. /* reset to default (normal bit order) */
  3106. fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
  3107. if (ext_attr->bit_reverse_mpeg_outout)
  3108. fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
  3109. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
  3110. if (rc != 0) {
  3111. pr_err("error %d\n", rc);
  3112. goto rw_error;
  3113. }
  3114. return 0;
  3115. rw_error:
  3116. return rc;
  3117. }
  3118. /*----------------------------------------------------------------------------*/
  3119. /**
  3120. * \fn int set_mpeg_start_width()
  3121. * \brief Set MPEG start width.
  3122. * \param devmod Pointer to demodulator instance.
  3123. * \return int.
  3124. *
  3125. * This routine should be called during a set channel of QAM/VSB
  3126. *
  3127. */
  3128. static int set_mpeg_start_width(struct drx_demod_instance *demod)
  3129. {
  3130. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  3131. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
  3132. struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
  3133. int rc;
  3134. u16 fec_oc_comm_mb = 0;
  3135. dev_addr = demod->my_i2c_dev_addr;
  3136. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  3137. common_attr = demod->my_common_attr;
  3138. if ((common_attr->mpeg_cfg.static_clk == true)
  3139. && (common_attr->mpeg_cfg.enable_parallel == false)) {
  3140. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
  3141. if (rc != 0) {
  3142. pr_err("error %d\n", rc);
  3143. goto rw_error;
  3144. }
  3145. fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
  3146. if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
  3147. fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
  3148. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
  3149. if (rc != 0) {
  3150. pr_err("error %d\n", rc);
  3151. goto rw_error;
  3152. }
  3153. }
  3154. return 0;
  3155. rw_error:
  3156. return rc;
  3157. }
  3158. /*----------------------------------------------------------------------------*/
  3159. /* miscellaneous configuartions - end */
  3160. /*----------------------------------------------------------------------------*/
  3161. /*----------------------------------------------------------------------------*/
  3162. /* UIO Configuration Functions - begin */
  3163. /*----------------------------------------------------------------------------*/
  3164. /**
  3165. * \fn int ctrl_set_uio_cfg()
  3166. * \brief Configure modus oprandi UIO.
  3167. * \param demod Pointer to demodulator instance.
  3168. * \param uio_cfg Pointer to a configuration setting for a certain UIO.
  3169. * \return int.
  3170. */
  3171. static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
  3172. {
  3173. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  3174. int rc;
  3175. if ((uio_cfg == NULL) || (demod == NULL))
  3176. return -EINVAL;
  3177. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  3178. /* Write magic word to enable pdr reg write */
  3179. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
  3180. if (rc != 0) {
  3181. pr_err("error %d\n", rc);
  3182. goto rw_error;
  3183. }
  3184. switch (uio_cfg->uio) {
  3185. /*====================================================================*/
  3186. case DRX_UIO1:
  3187. /* DRX_UIO1: SMA_TX UIO-1 */
  3188. if (!ext_attr->has_smatx)
  3189. return -EIO;
  3190. switch (uio_cfg->mode) {
  3191. case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
  3192. case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
  3193. case DRX_UIO_MODE_READWRITE:
  3194. ext_attr->uio_sma_tx_mode = uio_cfg->mode;
  3195. break;
  3196. case DRX_UIO_MODE_DISABLE:
  3197. ext_attr->uio_sma_tx_mode = uio_cfg->mode;
  3198. /* pad configuration register is set 0 - input mode */
  3199. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
  3200. if (rc != 0) {
  3201. pr_err("error %d\n", rc);
  3202. goto rw_error;
  3203. }
  3204. break;
  3205. default:
  3206. return -EINVAL;
  3207. } /* switch ( uio_cfg->mode ) */
  3208. break;
  3209. /*====================================================================*/
  3210. case DRX_UIO2:
  3211. /* DRX_UIO2: SMA_RX UIO-2 */
  3212. if (!ext_attr->has_smarx)
  3213. return -EIO;
  3214. switch (uio_cfg->mode) {
  3215. case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
  3216. case DRX_UIO_MODE_READWRITE:
  3217. ext_attr->uio_sma_rx_mode = uio_cfg->mode;
  3218. break;
  3219. case DRX_UIO_MODE_DISABLE:
  3220. ext_attr->uio_sma_rx_mode = uio_cfg->mode;
  3221. /* pad configuration register is set 0 - input mode */
  3222. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
  3223. if (rc != 0) {
  3224. pr_err("error %d\n", rc);
  3225. goto rw_error;
  3226. }
  3227. break;
  3228. default:
  3229. return -EINVAL;
  3230. break;
  3231. } /* switch ( uio_cfg->mode ) */
  3232. break;
  3233. /*====================================================================*/
  3234. case DRX_UIO3:
  3235. /* DRX_UIO3: GPIO UIO-3 */
  3236. if (!ext_attr->has_gpio)
  3237. return -EIO;
  3238. switch (uio_cfg->mode) {
  3239. case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
  3240. case DRX_UIO_MODE_READWRITE:
  3241. ext_attr->uio_gpio_mode = uio_cfg->mode;
  3242. break;
  3243. case DRX_UIO_MODE_DISABLE:
  3244. ext_attr->uio_gpio_mode = uio_cfg->mode;
  3245. /* pad configuration register is set 0 - input mode */
  3246. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
  3247. if (rc != 0) {
  3248. pr_err("error %d\n", rc);
  3249. goto rw_error;
  3250. }
  3251. break;
  3252. default:
  3253. return -EINVAL;
  3254. break;
  3255. } /* switch ( uio_cfg->mode ) */
  3256. break;
  3257. /*====================================================================*/
  3258. case DRX_UIO4:
  3259. /* DRX_UIO4: IRQN UIO-4 */
  3260. if (!ext_attr->has_irqn)
  3261. return -EIO;
  3262. switch (uio_cfg->mode) {
  3263. case DRX_UIO_MODE_READWRITE:
  3264. ext_attr->uio_irqn_mode = uio_cfg->mode;
  3265. break;
  3266. case DRX_UIO_MODE_DISABLE:
  3267. /* pad configuration register is set 0 - input mode */
  3268. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
  3269. if (rc != 0) {
  3270. pr_err("error %d\n", rc);
  3271. goto rw_error;
  3272. }
  3273. ext_attr->uio_irqn_mode = uio_cfg->mode;
  3274. break;
  3275. case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
  3276. default:
  3277. return -EINVAL;
  3278. break;
  3279. } /* switch ( uio_cfg->mode ) */
  3280. break;
  3281. /*====================================================================*/
  3282. default:
  3283. return -EINVAL;
  3284. } /* switch ( uio_cfg->uio ) */
  3285. /* Write magic word to disable pdr reg write */
  3286. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
  3287. if (rc != 0) {
  3288. pr_err("error %d\n", rc);
  3289. goto rw_error;
  3290. }
  3291. return 0;
  3292. rw_error:
  3293. return rc;
  3294. }
  3295. /**
  3296. * \fn int ctrl_uio_write()
  3297. * \brief Write to a UIO.
  3298. * \param demod Pointer to demodulator instance.
  3299. * \param uio_data Pointer to data container for a certain UIO.
  3300. * \return int.
  3301. */
  3302. static int
  3303. ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
  3304. {
  3305. struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
  3306. int rc;
  3307. u16 pin_cfg_value = 0;
  3308. u16 value = 0;
  3309. if ((uio_data == NULL) || (demod == NULL))
  3310. return -EINVAL;
  3311. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  3312. /* Write magic word to enable pdr reg write */
  3313. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
  3314. if (rc != 0) {
  3315. pr_err("error %d\n", rc);
  3316. goto rw_error;
  3317. }
  3318. switch (uio_data->uio) {
  3319. /*====================================================================*/
  3320. case DRX_UIO1:
  3321. /* DRX_UIO1: SMA_TX UIO-1 */
  3322. if (!ext_attr->has_smatx)
  3323. return -EIO;
  3324. if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
  3325. && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
  3326. return -EIO;
  3327. }
  3328. pin_cfg_value = 0;
  3329. /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
  3330. pin_cfg_value |= 0x0113;
  3331. /* io_pad_cfg_mode output mode is drive always */
  3332. /* io_pad_cfg_drive is set to power 2 (23 mA) */
  3333. /* write to io pad configuration register - output mode */
  3334. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
  3335. if (rc != 0) {
  3336. pr_err("error %d\n", rc);
  3337. goto rw_error;
  3338. }
  3339. /* use corresponding bit in io data output registar */
  3340. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
  3341. if (rc != 0) {
  3342. pr_err("error %d\n", rc);
  3343. goto rw_error;
  3344. }
  3345. if (!uio_data->value)
  3346. value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
  3347. else
  3348. value |= 0x8000; /* write one to 15th bit - 1st UIO */
  3349. /* write back to io data output register */
  3350. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
  3351. if (rc != 0) {
  3352. pr_err("error %d\n", rc);
  3353. goto rw_error;
  3354. }
  3355. break;
  3356. /*======================================================================*/
  3357. case DRX_UIO2:
  3358. /* DRX_UIO2: SMA_RX UIO-2 */
  3359. if (!ext_attr->has_smarx)
  3360. return -EIO;
  3361. if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
  3362. return -EIO;
  3363. pin_cfg_value = 0;
  3364. /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
  3365. pin_cfg_value |= 0x0113;
  3366. /* io_pad_cfg_mode output mode is drive always */
  3367. /* io_pad_cfg_drive is set to power 2 (23 mA) */
  3368. /* write to io pad configuration register - output mode */
  3369. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
  3370. if (rc != 0) {
  3371. pr_err("error %d\n", rc);
  3372. goto rw_error;
  3373. }
  3374. /* use corresponding bit in io data output registar */
  3375. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
  3376. if (rc != 0) {
  3377. pr_err("error %d\n", rc);
  3378. goto rw_error;
  3379. }
  3380. if (!uio_data->value)
  3381. value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
  3382. else
  3383. value |= 0x4000; /* write one to 14th bit - 2nd UIO */
  3384. /* write back to io data output register */
  3385. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
  3386. if (rc != 0) {
  3387. pr_err("error %d\n", rc);
  3388. goto rw_error;
  3389. }
  3390. break;
  3391. /*====================================================================*/
  3392. case DRX_UIO3:
  3393. /* DRX_UIO3: ASEL UIO-3 */
  3394. if (!ext_attr->has_gpio)
  3395. return -EIO;
  3396. if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
  3397. return -EIO;
  3398. pin_cfg_value = 0;
  3399. /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
  3400. pin_cfg_value |= 0x0113;
  3401. /* io_pad_cfg_mode output mode is drive always */
  3402. /* io_pad_cfg_drive is set to power 2 (23 mA) */
  3403. /* write to io pad configuration register - output mode */
  3404. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
  3405. if (rc != 0) {
  3406. pr_err("error %d\n", rc);
  3407. goto rw_error;
  3408. }
  3409. /* use corresponding bit in io data output registar */
  3410. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
  3411. if (rc != 0) {
  3412. pr_err("error %d\n", rc);
  3413. goto rw_error;
  3414. }
  3415. if (!uio_data->value)
  3416. value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
  3417. else
  3418. value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
  3419. /* write back to io data output register */
  3420. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
  3421. if (rc != 0) {
  3422. pr_err("error %d\n", rc);
  3423. goto rw_error;
  3424. }
  3425. break;
  3426. /*=====================================================================*/
  3427. case DRX_UIO4:
  3428. /* DRX_UIO4: IRQN UIO-4 */
  3429. if (!ext_attr->has_irqn)
  3430. return -EIO;
  3431. if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
  3432. return -EIO;
  3433. pin_cfg_value = 0;
  3434. /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
  3435. pin_cfg_value |= 0x0113;
  3436. /* io_pad_cfg_mode output mode is drive always */
  3437. /* io_pad_cfg_drive is set to power 2 (23 mA) */
  3438. /* write to io pad configuration register - output mode */
  3439. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
  3440. if (rc != 0) {
  3441. pr_err("error %d\n", rc);
  3442. goto rw_error;
  3443. }
  3444. /* use corresponding bit in io data output registar */
  3445. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
  3446. if (rc != 0) {
  3447. pr_err("error %d\n", rc);
  3448. goto rw_error;
  3449. }
  3450. if (uio_data->value == false)
  3451. value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
  3452. else
  3453. value |= 0x1000; /* write one to 12th bit - 4th UIO */
  3454. /* write back to io data output register */
  3455. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
  3456. if (rc != 0) {
  3457. pr_err("error %d\n", rc);
  3458. goto rw_error;
  3459. }
  3460. break;
  3461. /*=====================================================================*/
  3462. default:
  3463. return -EINVAL;
  3464. } /* switch ( uio_data->uio ) */
  3465. /* Write magic word to disable pdr reg write */
  3466. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
  3467. if (rc != 0) {
  3468. pr_err("error %d\n", rc);
  3469. goto rw_error;
  3470. }
  3471. return 0;
  3472. rw_error:
  3473. return rc;
  3474. }
  3475. /*---------------------------------------------------------------------------*/
  3476. /* UIO Configuration Functions - end */
  3477. /*---------------------------------------------------------------------------*/
  3478. /*----------------------------------------------------------------------------*/
  3479. /* I2C Bridge Functions - begin */
  3480. /*----------------------------------------------------------------------------*/
  3481. /**
  3482. * \fn int ctrl_i2c_bridge()
  3483. * \brief Open or close the I2C switch to tuner.
  3484. * \param demod Pointer to demodulator instance.
  3485. * \param bridge_closed Pointer to bool indication if bridge is closed not.
  3486. * \return int.
  3487. */
  3488. static int
  3489. ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
  3490. {
  3491. struct drxj_hi_cmd hi_cmd;
  3492. u16 result = 0;
  3493. /* check arguments */
  3494. if (bridge_closed == NULL)
  3495. return -EINVAL;
  3496. hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
  3497. hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
  3498. if (*bridge_closed)
  3499. hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
  3500. else
  3501. hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
  3502. return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
  3503. }
  3504. /*----------------------------------------------------------------------------*/
  3505. /* I2C Bridge Functions - end */
  3506. /*----------------------------------------------------------------------------*/
  3507. /*----------------------------------------------------------------------------*/
  3508. /* Smart antenna Functions - begin */
  3509. /*----------------------------------------------------------------------------*/
  3510. /**
  3511. * \fn int smart_ant_init()
  3512. * \brief Initialize Smart Antenna.
  3513. * \param pointer to struct drx_demod_instance.
  3514. * \return int.
  3515. *
  3516. */
  3517. static int smart_ant_init(struct drx_demod_instance *demod)
  3518. {
  3519. struct drxj_data *ext_attr = NULL;
  3520. struct i2c_device_addr *dev_addr = NULL;
  3521. struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
  3522. int rc;
  3523. u16 data = 0;
  3524. dev_addr = demod->my_i2c_dev_addr;
  3525. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  3526. /* Write magic word to enable pdr reg write */
  3527. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
  3528. if (rc != 0) {
  3529. pr_err("error %d\n", rc);
  3530. goto rw_error;
  3531. }
  3532. /* init smart antenna */
  3533. rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
  3534. if (rc != 0) {
  3535. pr_err("error %d\n", rc);
  3536. goto rw_error;
  3537. }
  3538. if (ext_attr->smart_ant_inverted) {
  3539. rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
  3540. if (rc != 0) {
  3541. pr_err("error %d\n", rc);
  3542. goto rw_error;
  3543. }
  3544. } else {
  3545. rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
  3546. if (rc != 0) {
  3547. pr_err("error %d\n", rc);
  3548. goto rw_error;
  3549. }
  3550. }
  3551. /* config SMA_TX pin to smart antenna mode */
  3552. rc = ctrl_set_uio_cfg(demod, &uio_cfg);
  3553. if (rc != 0) {
  3554. pr_err("error %d\n", rc);
  3555. goto rw_error;
  3556. }
  3557. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
  3558. if (rc != 0) {
  3559. pr_err("error %d\n", rc);
  3560. goto rw_error;
  3561. }
  3562. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
  3563. if (rc != 0) {
  3564. pr_err("error %d\n", rc);
  3565. goto rw_error;
  3566. }
  3567. /* Write magic word to disable pdr reg write */
  3568. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
  3569. if (rc != 0) {
  3570. pr_err("error %d\n", rc);
  3571. goto rw_error;
  3572. }
  3573. return 0;
  3574. rw_error:
  3575. return rc;
  3576. }
  3577. static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
  3578. {
  3579. int rc;
  3580. u16 cur_cmd = 0;
  3581. unsigned long timeout;
  3582. /* Check param */
  3583. if (cmd == NULL)
  3584. return -EINVAL;
  3585. /* Wait until SCU command interface is ready to receive command */
  3586. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
  3587. if (rc != 0) {
  3588. pr_err("error %d\n", rc);
  3589. goto rw_error;
  3590. }
  3591. if (cur_cmd != DRX_SCU_READY)
  3592. return -EIO;
  3593. switch (cmd->parameter_len) {
  3594. case 5:
  3595. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
  3596. if (rc != 0) {
  3597. pr_err("error %d\n", rc);
  3598. goto rw_error;
  3599. } /* fallthrough */
  3600. case 4:
  3601. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
  3602. if (rc != 0) {
  3603. pr_err("error %d\n", rc);
  3604. goto rw_error;
  3605. } /* fallthrough */
  3606. case 3:
  3607. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
  3608. if (rc != 0) {
  3609. pr_err("error %d\n", rc);
  3610. goto rw_error;
  3611. } /* fallthrough */
  3612. case 2:
  3613. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
  3614. if (rc != 0) {
  3615. pr_err("error %d\n", rc);
  3616. goto rw_error;
  3617. } /* fallthrough */
  3618. case 1:
  3619. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
  3620. if (rc != 0) {
  3621. pr_err("error %d\n", rc);
  3622. goto rw_error;
  3623. } /* fallthrough */
  3624. case 0:
  3625. /* do nothing */
  3626. break;
  3627. default:
  3628. /* this number of parameters is not supported */
  3629. return -EIO;
  3630. }
  3631. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
  3632. if (rc != 0) {
  3633. pr_err("error %d\n", rc);
  3634. goto rw_error;
  3635. }
  3636. /* Wait until SCU has processed command */
  3637. timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
  3638. while (time_is_after_jiffies(timeout)) {
  3639. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
  3640. if (rc != 0) {
  3641. pr_err("error %d\n", rc);
  3642. goto rw_error;
  3643. }
  3644. if (cur_cmd == DRX_SCU_READY)
  3645. break;
  3646. usleep_range(1000, 2000);
  3647. }
  3648. if (cur_cmd != DRX_SCU_READY)
  3649. return -EIO;
  3650. /* read results */
  3651. if ((cmd->result_len > 0) && (cmd->result != NULL)) {
  3652. s16 err;
  3653. switch (cmd->result_len) {
  3654. case 4:
  3655. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
  3656. if (rc != 0) {
  3657. pr_err("error %d\n", rc);
  3658. goto rw_error;
  3659. } /* fallthrough */
  3660. case 3:
  3661. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
  3662. if (rc != 0) {
  3663. pr_err("error %d\n", rc);
  3664. goto rw_error;
  3665. } /* fallthrough */
  3666. case 2:
  3667. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
  3668. if (rc != 0) {
  3669. pr_err("error %d\n", rc);
  3670. goto rw_error;
  3671. } /* fallthrough */
  3672. case 1:
  3673. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
  3674. if (rc != 0) {
  3675. pr_err("error %d\n", rc);
  3676. goto rw_error;
  3677. } /* fallthrough */
  3678. case 0:
  3679. /* do nothing */
  3680. break;
  3681. default:
  3682. /* this number of parameters is not supported */
  3683. return -EIO;
  3684. }
  3685. /* Check if an error was reported by SCU */
  3686. err = cmd->result[0];
  3687. /* check a few fixed error codes */
  3688. if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
  3689. || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
  3690. || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
  3691. || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
  3692. ) {
  3693. return -EINVAL;
  3694. }
  3695. /* here it is assumed that negative means error, and positive no error */
  3696. else if (err < 0)
  3697. return -EIO;
  3698. else
  3699. return 0;
  3700. }
  3701. return 0;
  3702. rw_error:
  3703. return rc;
  3704. }
  3705. /**
  3706. * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
  3707. * \brief Basic access routine for SCU atomic read or write access
  3708. * \param dev_addr pointer to i2c dev address
  3709. * \param addr destination/source address
  3710. * \param datasize size of data buffer in bytes
  3711. * \param data pointer to data buffer
  3712. * \return int
  3713. * \retval 0 Succes
  3714. * \retval -EIO Timeout, I2C error, illegal bank
  3715. *
  3716. */
  3717. #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
  3718. static
  3719. int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 addr, u16 datasize, /* max 30 bytes because the limit of SCU parameter */
  3720. u8 *data, bool read_flag)
  3721. {
  3722. struct drxjscu_cmd scu_cmd;
  3723. int rc;
  3724. u16 set_param_parameters[15];
  3725. u16 cmd_result[15];
  3726. /* Parameter check */
  3727. if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
  3728. return -EINVAL;
  3729. set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
  3730. if (read_flag) { /* read */
  3731. set_param_parameters[0] = ((~(0x0080)) & datasize);
  3732. scu_cmd.parameter_len = 2;
  3733. scu_cmd.result_len = datasize / 2 + 2;
  3734. } else {
  3735. int i = 0;
  3736. set_param_parameters[0] = 0x0080 | datasize;
  3737. for (i = 0; i < (datasize / 2); i++) {
  3738. set_param_parameters[i + 2] =
  3739. (data[2 * i] | (data[(2 * i) + 1] << 8));
  3740. }
  3741. scu_cmd.parameter_len = datasize / 2 + 2;
  3742. scu_cmd.result_len = 1;
  3743. }
  3744. scu_cmd.command =
  3745. SCU_RAM_COMMAND_STANDARD_TOP |
  3746. SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
  3747. scu_cmd.result = cmd_result;
  3748. scu_cmd.parameter = set_param_parameters;
  3749. rc = scu_command(dev_addr, &scu_cmd);
  3750. if (rc != 0) {
  3751. pr_err("error %d\n", rc);
  3752. goto rw_error;
  3753. }
  3754. if (read_flag) {
  3755. int i = 0;
  3756. /* read data from buffer */
  3757. for (i = 0; i < (datasize / 2); i++) {
  3758. data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
  3759. data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
  3760. }
  3761. }
  3762. return 0;
  3763. rw_error:
  3764. return rc;
  3765. }
  3766. /*============================================================================*/
  3767. /**
  3768. * \fn int DRXJ_DAP_AtomicReadReg16()
  3769. * \brief Atomic read of 16 bits words
  3770. */
  3771. static
  3772. int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
  3773. u32 addr,
  3774. u16 *data, u32 flags)
  3775. {
  3776. u8 buf[2] = { 0 };
  3777. int rc = -EIO;
  3778. u16 word = 0;
  3779. if (!data)
  3780. return -EINVAL;
  3781. rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
  3782. if (rc < 0)
  3783. return rc;
  3784. word = (u16) (buf[0] + (buf[1] << 8));
  3785. *data = word;
  3786. return rc;
  3787. }
  3788. /*============================================================================*/
  3789. /**
  3790. * \fn int drxj_dap_scu_atomic_write_reg16()
  3791. * \brief Atomic read of 16 bits words
  3792. */
  3793. static
  3794. int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
  3795. u32 addr,
  3796. u16 data, u32 flags)
  3797. {
  3798. u8 buf[2];
  3799. int rc = -EIO;
  3800. buf[0] = (u8) (data & 0xff);
  3801. buf[1] = (u8) ((data >> 8) & 0xff);
  3802. rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
  3803. return rc;
  3804. }
  3805. /* -------------------------------------------------------------------------- */
  3806. /**
  3807. * \brief Measure result of ADC synchronisation
  3808. * \param demod demod instance
  3809. * \param count (returned) count
  3810. * \return int.
  3811. * \retval 0 Success
  3812. * \retval -EIO Failure: I2C error
  3813. *
  3814. */
  3815. static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
  3816. {
  3817. struct i2c_device_addr *dev_addr = NULL;
  3818. int rc;
  3819. u16 data = 0;
  3820. dev_addr = demod->my_i2c_dev_addr;
  3821. /* Start measurement */
  3822. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
  3823. if (rc != 0) {
  3824. pr_err("error %d\n", rc);
  3825. goto rw_error;
  3826. }
  3827. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
  3828. if (rc != 0) {
  3829. pr_err("error %d\n", rc);
  3830. goto rw_error;
  3831. }
  3832. /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
  3833. msleep(1);
  3834. *count = 0;
  3835. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);
  3836. if (rc != 0) {
  3837. pr_err("error %d\n", rc);
  3838. goto rw_error;
  3839. }
  3840. if (data == 127)
  3841. *count = *count + 1;
  3842. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);
  3843. if (rc != 0) {
  3844. pr_err("error %d\n", rc);
  3845. goto rw_error;
  3846. }
  3847. if (data == 127)
  3848. *count = *count + 1;
  3849. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);
  3850. if (rc != 0) {
  3851. pr_err("error %d\n", rc);
  3852. goto rw_error;
  3853. }
  3854. if (data == 127)
  3855. *count = *count + 1;
  3856. return 0;
  3857. rw_error:
  3858. return rc;
  3859. }
  3860. /**
  3861. * \brief Synchronize analog and digital clock domains
  3862. * \param demod demod instance
  3863. * \return int.
  3864. * \retval 0 Success
  3865. * \retval -EIO Failure: I2C error or failure to synchronize
  3866. *
  3867. * An IQM reset will also reset the results of this synchronization.
  3868. * After an IQM reset this routine needs to be called again.
  3869. *
  3870. */
  3871. static int adc_synchronization(struct drx_demod_instance *demod)
  3872. {
  3873. struct i2c_device_addr *dev_addr = NULL;
  3874. int rc;
  3875. u16 count = 0;
  3876. dev_addr = demod->my_i2c_dev_addr;
  3877. rc = adc_sync_measurement(demod, &count);
  3878. if (rc != 0) {
  3879. pr_err("error %d\n", rc);
  3880. goto rw_error;
  3881. }
  3882. if (count == 1) {
  3883. /* Try sampling on a different edge */
  3884. u16 clk_neg = 0;
  3885. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
  3886. if (rc != 0) {
  3887. pr_err("error %d\n", rc);
  3888. goto rw_error;
  3889. }
  3890. clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
  3891. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
  3892. if (rc != 0) {
  3893. pr_err("error %d\n", rc);
  3894. goto rw_error;
  3895. }
  3896. rc = adc_sync_measurement(demod, &count);
  3897. if (rc != 0) {
  3898. pr_err("error %d\n", rc);
  3899. goto rw_error;
  3900. }
  3901. }
  3902. /* TODO: implement fallback scenarios */
  3903. if (count < 2)
  3904. return -EIO;
  3905. return 0;
  3906. rw_error:
  3907. return rc;
  3908. }
  3909. /*============================================================================*/
  3910. /*== END AUXILIARY FUNCTIONS ==*/
  3911. /*============================================================================*/
  3912. /*============================================================================*/
  3913. /*============================================================================*/
  3914. /*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
  3915. /*============================================================================*/
  3916. /*============================================================================*/
  3917. /**
  3918. * \fn int init_agc ()
  3919. * \brief Initialize AGC for all standards.
  3920. * \param demod instance of demodulator.
  3921. * \param channel pointer to channel data.
  3922. * \return int.
  3923. */
  3924. static int init_agc(struct drx_demod_instance *demod)
  3925. {
  3926. struct i2c_device_addr *dev_addr = NULL;
  3927. struct drx_common_attr *common_attr = NULL;
  3928. struct drxj_data *ext_attr = NULL;
  3929. struct drxj_cfg_agc *p_agc_rf_settings = NULL;
  3930. struct drxj_cfg_agc *p_agc_if_settings = NULL;
  3931. int rc;
  3932. u16 ingain_tgt_max = 0;
  3933. u16 clp_dir_to = 0;
  3934. u16 sns_sum_max = 0;
  3935. u16 clp_sum_max = 0;
  3936. u16 sns_dir_to = 0;
  3937. u16 ki_innergain_min = 0;
  3938. u16 agc_ki = 0;
  3939. u16 ki_max = 0;
  3940. u16 if_iaccu_hi_tgt_min = 0;
  3941. u16 data = 0;
  3942. u16 agc_ki_dgain = 0;
  3943. u16 ki_min = 0;
  3944. u16 clp_ctrl_mode = 0;
  3945. u16 agc_rf = 0;
  3946. u16 agc_if = 0;
  3947. dev_addr = demod->my_i2c_dev_addr;
  3948. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  3949. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  3950. switch (ext_attr->standard) {
  3951. case DRX_STANDARD_8VSB:
  3952. clp_sum_max = 1023;
  3953. clp_dir_to = (u16) (-9);
  3954. sns_sum_max = 1023;
  3955. sns_dir_to = (u16) (-9);
  3956. ki_innergain_min = (u16) (-32768);
  3957. ki_max = 0x032C;
  3958. agc_ki_dgain = 0xC;
  3959. if_iaccu_hi_tgt_min = 2047;
  3960. ki_min = 0x0117;
  3961. ingain_tgt_max = 16383;
  3962. clp_ctrl_mode = 0;
  3963. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
  3964. if (rc != 0) {
  3965. pr_err("error %d\n", rc);
  3966. goto rw_error;
  3967. }
  3968. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
  3969. if (rc != 0) {
  3970. pr_err("error %d\n", rc);
  3971. goto rw_error;
  3972. }
  3973. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
  3974. if (rc != 0) {
  3975. pr_err("error %d\n", rc);
  3976. goto rw_error;
  3977. }
  3978. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
  3979. if (rc != 0) {
  3980. pr_err("error %d\n", rc);
  3981. goto rw_error;
  3982. }
  3983. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
  3984. if (rc != 0) {
  3985. pr_err("error %d\n", rc);
  3986. goto rw_error;
  3987. }
  3988. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
  3989. if (rc != 0) {
  3990. pr_err("error %d\n", rc);
  3991. goto rw_error;
  3992. }
  3993. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
  3994. if (rc != 0) {
  3995. pr_err("error %d\n", rc);
  3996. goto rw_error;
  3997. }
  3998. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
  3999. if (rc != 0) {
  4000. pr_err("error %d\n", rc);
  4001. goto rw_error;
  4002. }
  4003. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
  4004. if (rc != 0) {
  4005. pr_err("error %d\n", rc);
  4006. goto rw_error;
  4007. }
  4008. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
  4009. if (rc != 0) {
  4010. pr_err("error %d\n", rc);
  4011. goto rw_error;
  4012. }
  4013. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
  4014. if (rc != 0) {
  4015. pr_err("error %d\n", rc);
  4016. goto rw_error;
  4017. }
  4018. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
  4019. if (rc != 0) {
  4020. pr_err("error %d\n", rc);
  4021. goto rw_error;
  4022. }
  4023. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
  4024. if (rc != 0) {
  4025. pr_err("error %d\n", rc);
  4026. goto rw_error;
  4027. }
  4028. p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
  4029. p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
  4030. break;
  4031. #ifndef DRXJ_VSB_ONLY
  4032. case DRX_STANDARD_ITU_A:
  4033. case DRX_STANDARD_ITU_C:
  4034. case DRX_STANDARD_ITU_B:
  4035. ingain_tgt_max = 5119;
  4036. clp_sum_max = 1023;
  4037. clp_dir_to = (u16) (-5);
  4038. sns_sum_max = 127;
  4039. sns_dir_to = (u16) (-3);
  4040. ki_innergain_min = 0;
  4041. ki_max = 0x0657;
  4042. if_iaccu_hi_tgt_min = 2047;
  4043. agc_ki_dgain = 0x7;
  4044. ki_min = 0x0117;
  4045. clp_ctrl_mode = 0;
  4046. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
  4047. if (rc != 0) {
  4048. pr_err("error %d\n", rc);
  4049. goto rw_error;
  4050. }
  4051. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
  4052. if (rc != 0) {
  4053. pr_err("error %d\n", rc);
  4054. goto rw_error;
  4055. }
  4056. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
  4057. if (rc != 0) {
  4058. pr_err("error %d\n", rc);
  4059. goto rw_error;
  4060. }
  4061. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
  4062. if (rc != 0) {
  4063. pr_err("error %d\n", rc);
  4064. goto rw_error;
  4065. }
  4066. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
  4067. if (rc != 0) {
  4068. pr_err("error %d\n", rc);
  4069. goto rw_error;
  4070. }
  4071. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
  4072. if (rc != 0) {
  4073. pr_err("error %d\n", rc);
  4074. goto rw_error;
  4075. }
  4076. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
  4077. if (rc != 0) {
  4078. pr_err("error %d\n", rc);
  4079. goto rw_error;
  4080. }
  4081. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
  4082. if (rc != 0) {
  4083. pr_err("error %d\n", rc);
  4084. goto rw_error;
  4085. }
  4086. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
  4087. if (rc != 0) {
  4088. pr_err("error %d\n", rc);
  4089. goto rw_error;
  4090. }
  4091. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
  4092. if (rc != 0) {
  4093. pr_err("error %d\n", rc);
  4094. goto rw_error;
  4095. }
  4096. p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
  4097. p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
  4098. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
  4099. if (rc != 0) {
  4100. pr_err("error %d\n", rc);
  4101. goto rw_error;
  4102. }
  4103. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
  4104. if (rc != 0) {
  4105. pr_err("error %d\n", rc);
  4106. goto rw_error;
  4107. }
  4108. agc_ki &= 0xf000;
  4109. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
  4110. if (rc != 0) {
  4111. pr_err("error %d\n", rc);
  4112. goto rw_error;
  4113. }
  4114. break;
  4115. #endif
  4116. default:
  4117. return -EINVAL;
  4118. }
  4119. /* for new AGC interface */
  4120. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
  4121. if (rc != 0) {
  4122. pr_err("error %d\n", rc);
  4123. goto rw_error;
  4124. }
  4125. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
  4126. if (rc != 0) {
  4127. pr_err("error %d\n", rc);
  4128. goto rw_error;
  4129. } /* Gain fed from inner to outer AGC */
  4130. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
  4131. if (rc != 0) {
  4132. pr_err("error %d\n", rc);
  4133. goto rw_error;
  4134. }
  4135. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
  4136. if (rc != 0) {
  4137. pr_err("error %d\n", rc);
  4138. goto rw_error;
  4139. }
  4140. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
  4141. if (rc != 0) {
  4142. pr_err("error %d\n", rc);
  4143. goto rw_error;
  4144. } /* set to p_agc_settings->top before */
  4145. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
  4146. if (rc != 0) {
  4147. pr_err("error %d\n", rc);
  4148. goto rw_error;
  4149. }
  4150. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
  4151. if (rc != 0) {
  4152. pr_err("error %d\n", rc);
  4153. goto rw_error;
  4154. }
  4155. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
  4156. if (rc != 0) {
  4157. pr_err("error %d\n", rc);
  4158. goto rw_error;
  4159. }
  4160. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
  4161. if (rc != 0) {
  4162. pr_err("error %d\n", rc);
  4163. goto rw_error;
  4164. }
  4165. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
  4166. if (rc != 0) {
  4167. pr_err("error %d\n", rc);
  4168. goto rw_error;
  4169. }
  4170. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
  4171. if (rc != 0) {
  4172. pr_err("error %d\n", rc);
  4173. goto rw_error;
  4174. }
  4175. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
  4176. if (rc != 0) {
  4177. pr_err("error %d\n", rc);
  4178. goto rw_error;
  4179. }
  4180. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
  4181. if (rc != 0) {
  4182. pr_err("error %d\n", rc);
  4183. goto rw_error;
  4184. }
  4185. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
  4186. if (rc != 0) {
  4187. pr_err("error %d\n", rc);
  4188. goto rw_error;
  4189. }
  4190. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
  4191. if (rc != 0) {
  4192. pr_err("error %d\n", rc);
  4193. goto rw_error;
  4194. }
  4195. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
  4196. if (rc != 0) {
  4197. pr_err("error %d\n", rc);
  4198. goto rw_error;
  4199. }
  4200. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
  4201. if (rc != 0) {
  4202. pr_err("error %d\n", rc);
  4203. goto rw_error;
  4204. }
  4205. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
  4206. if (rc != 0) {
  4207. pr_err("error %d\n", rc);
  4208. goto rw_error;
  4209. }
  4210. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
  4211. if (rc != 0) {
  4212. pr_err("error %d\n", rc);
  4213. goto rw_error;
  4214. }
  4215. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
  4216. if (rc != 0) {
  4217. pr_err("error %d\n", rc);
  4218. goto rw_error;
  4219. }
  4220. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
  4221. if (rc != 0) {
  4222. pr_err("error %d\n", rc);
  4223. goto rw_error;
  4224. }
  4225. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
  4226. if (rc != 0) {
  4227. pr_err("error %d\n", rc);
  4228. goto rw_error;
  4229. }
  4230. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
  4231. if (rc != 0) {
  4232. pr_err("error %d\n", rc);
  4233. goto rw_error;
  4234. }
  4235. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
  4236. if (rc != 0) {
  4237. pr_err("error %d\n", rc);
  4238. goto rw_error;
  4239. }
  4240. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
  4241. if (rc != 0) {
  4242. pr_err("error %d\n", rc);
  4243. goto rw_error;
  4244. }
  4245. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
  4246. if (rc != 0) {
  4247. pr_err("error %d\n", rc);
  4248. goto rw_error;
  4249. }
  4250. agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
  4251. if (common_attr->tuner_rf_agc_pol == true)
  4252. agc_rf = 0x87ff - agc_rf;
  4253. agc_if = 0x800;
  4254. if (common_attr->tuner_if_agc_pol == true)
  4255. agc_rf = 0x87ff - agc_rf;
  4256. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
  4257. if (rc != 0) {
  4258. pr_err("error %d\n", rc);
  4259. goto rw_error;
  4260. }
  4261. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
  4262. if (rc != 0) {
  4263. pr_err("error %d\n", rc);
  4264. goto rw_error;
  4265. }
  4266. /* Set/restore Ki DGAIN factor */
  4267. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
  4268. if (rc != 0) {
  4269. pr_err("error %d\n", rc);
  4270. goto rw_error;
  4271. }
  4272. data &= ~SCU_RAM_AGC_KI_DGAIN__M;
  4273. data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
  4274. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
  4275. if (rc != 0) {
  4276. pr_err("error %d\n", rc);
  4277. goto rw_error;
  4278. }
  4279. return 0;
  4280. rw_error:
  4281. return rc;
  4282. }
  4283. /**
  4284. * \fn int set_frequency ()
  4285. * \brief Set frequency shift.
  4286. * \param demod instance of demodulator.
  4287. * \param channel pointer to channel data.
  4288. * \param tuner_freq_offset residual frequency from tuner.
  4289. * \return int.
  4290. */
  4291. static int
  4292. set_frequency(struct drx_demod_instance *demod,
  4293. struct drx_channel *channel, s32 tuner_freq_offset)
  4294. {
  4295. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  4296. struct drxj_data *ext_attr = demod->my_ext_attr;
  4297. int rc;
  4298. s32 sampling_frequency = 0;
  4299. s32 frequency_shift = 0;
  4300. s32 if_freq_actual = 0;
  4301. s32 rf_freq_residual = -1 * tuner_freq_offset;
  4302. s32 adc_freq = 0;
  4303. s32 intermediate_freq = 0;
  4304. u32 iqm_fs_rate_ofs = 0;
  4305. bool adc_flip = true;
  4306. bool select_pos_image = false;
  4307. bool rf_mirror;
  4308. bool tuner_mirror;
  4309. bool image_to_select = true;
  4310. s32 fm_frequency_shift = 0;
  4311. rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
  4312. tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
  4313. /*
  4314. Program frequency shifter
  4315. No need to account for mirroring on RF
  4316. */
  4317. switch (ext_attr->standard) {
  4318. case DRX_STANDARD_ITU_A: /* fallthrough */
  4319. case DRX_STANDARD_ITU_C: /* fallthrough */
  4320. case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
  4321. case DRX_STANDARD_8VSB:
  4322. select_pos_image = true;
  4323. break;
  4324. case DRX_STANDARD_FM:
  4325. /* After IQM FS sound carrier must appear at 4 Mhz in spect.
  4326. Sound carrier is already 3Mhz above centre frequency due
  4327. to tuner setting so now add an extra shift of 1MHz... */
  4328. fm_frequency_shift = 1000;
  4329. case DRX_STANDARD_ITU_B: /* fallthrough */
  4330. case DRX_STANDARD_NTSC: /* fallthrough */
  4331. case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
  4332. case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
  4333. case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
  4334. case DRX_STANDARD_PAL_SECAM_L:
  4335. select_pos_image = false;
  4336. break;
  4337. default:
  4338. return -EINVAL;
  4339. }
  4340. intermediate_freq = demod->my_common_attr->intermediate_freq;
  4341. sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
  4342. if (tuner_mirror)
  4343. if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
  4344. else
  4345. if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
  4346. if (if_freq_actual > sampling_frequency / 2) {
  4347. /* adc mirrors */
  4348. adc_freq = sampling_frequency - if_freq_actual;
  4349. adc_flip = true;
  4350. } else {
  4351. /* adc doesn't mirror */
  4352. adc_freq = if_freq_actual;
  4353. adc_flip = false;
  4354. }
  4355. frequency_shift = adc_freq;
  4356. image_to_select =
  4357. (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
  4358. iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
  4359. if (image_to_select)
  4360. iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
  4361. /* Program frequency shifter with tuner offset compensation */
  4362. /* frequency_shift += tuner_freq_offset; TODO */
  4363. rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
  4364. if (rc != 0) {
  4365. pr_err("error %d\n", rc);
  4366. goto rw_error;
  4367. }
  4368. ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
  4369. ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
  4370. return 0;
  4371. rw_error:
  4372. return rc;
  4373. }
  4374. /**
  4375. * \fn int get_acc_pkt_err()
  4376. * \brief Retrieve signal strength for VSB and QAM.
  4377. * \param demod Pointer to demod instance
  4378. * \param packet_err Pointer to packet error
  4379. * \return int.
  4380. * \retval 0 sig_strength contains valid data.
  4381. * \retval -EINVAL sig_strength is NULL.
  4382. * \retval -EIO Erroneous data, sig_strength contains invalid data.
  4383. */
  4384. #ifdef DRXJ_SIGNAL_ACCUM_ERR
  4385. static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
  4386. {
  4387. int rc;
  4388. static u16 pkt_err;
  4389. static u16 last_pkt_err;
  4390. u16 data = 0;
  4391. struct drxj_data *ext_attr = NULL;
  4392. struct i2c_device_addr *dev_addr = NULL;
  4393. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  4394. dev_addr = demod->my_i2c_dev_addr;
  4395. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
  4396. if (rc != 0) {
  4397. pr_err("error %d\n", rc);
  4398. goto rw_error;
  4399. }
  4400. if (ext_attr->reset_pkt_err_acc) {
  4401. last_pkt_err = data;
  4402. pkt_err = 0;
  4403. ext_attr->reset_pkt_err_acc = false;
  4404. }
  4405. if (data < last_pkt_err) {
  4406. pkt_err += 0xffff - last_pkt_err;
  4407. pkt_err += data;
  4408. } else {
  4409. pkt_err += (data - last_pkt_err);
  4410. }
  4411. *packet_err = pkt_err;
  4412. last_pkt_err = data;
  4413. return 0;
  4414. rw_error:
  4415. return rc;
  4416. }
  4417. #endif
  4418. /*============================================================================*/
  4419. /**
  4420. * \fn int set_agc_rf ()
  4421. * \brief Configure RF AGC
  4422. * \param demod instance of demodulator.
  4423. * \param agc_settings AGC configuration structure
  4424. * \return int.
  4425. */
  4426. static int
  4427. set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
  4428. {
  4429. struct i2c_device_addr *dev_addr = NULL;
  4430. struct drxj_data *ext_attr = NULL;
  4431. struct drxj_cfg_agc *p_agc_settings = NULL;
  4432. struct drx_common_attr *common_attr = NULL;
  4433. int rc;
  4434. drx_write_reg16func_t scu_wr16 = NULL;
  4435. drx_read_reg16func_t scu_rr16 = NULL;
  4436. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  4437. dev_addr = demod->my_i2c_dev_addr;
  4438. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  4439. if (atomic) {
  4440. scu_rr16 = drxj_dap_scu_atomic_read_reg16;
  4441. scu_wr16 = drxj_dap_scu_atomic_write_reg16;
  4442. } else {
  4443. scu_rr16 = drxj_dap_read_reg16;
  4444. scu_wr16 = drxj_dap_write_reg16;
  4445. }
  4446. /* Configure AGC only if standard is currently active */
  4447. if ((ext_attr->standard == agc_settings->standard) ||
  4448. (DRXJ_ISQAMSTD(ext_attr->standard) &&
  4449. DRXJ_ISQAMSTD(agc_settings->standard)) ||
  4450. (DRXJ_ISATVSTD(ext_attr->standard) &&
  4451. DRXJ_ISATVSTD(agc_settings->standard))) {
  4452. u16 data = 0;
  4453. switch (agc_settings->ctrl_mode) {
  4454. case DRX_AGC_CTRL_AUTO:
  4455. /* Enable RF AGC DAC */
  4456. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
  4457. if (rc != 0) {
  4458. pr_err("error %d\n", rc);
  4459. goto rw_error;
  4460. }
  4461. data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
  4462. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
  4463. if (rc != 0) {
  4464. pr_err("error %d\n", rc);
  4465. goto rw_error;
  4466. }
  4467. /* Enable SCU RF AGC loop */
  4468. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
  4469. if (rc != 0) {
  4470. pr_err("error %d\n", rc);
  4471. goto rw_error;
  4472. }
  4473. data &= ~SCU_RAM_AGC_KI_RF__M;
  4474. if (ext_attr->standard == DRX_STANDARD_8VSB)
  4475. data |= (2 << SCU_RAM_AGC_KI_RF__B);
  4476. else if (DRXJ_ISQAMSTD(ext_attr->standard))
  4477. data |= (5 << SCU_RAM_AGC_KI_RF__B);
  4478. else
  4479. data |= (4 << SCU_RAM_AGC_KI_RF__B);
  4480. if (common_attr->tuner_rf_agc_pol)
  4481. data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
  4482. else
  4483. data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
  4484. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
  4485. if (rc != 0) {
  4486. pr_err("error %d\n", rc);
  4487. goto rw_error;
  4488. }
  4489. /* Set speed ( using complementary reduction value ) */
  4490. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
  4491. if (rc != 0) {
  4492. pr_err("error %d\n", rc);
  4493. goto rw_error;
  4494. }
  4495. data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
  4496. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_RAGC_RED__B) & SCU_RAM_AGC_KI_RED_RAGC_RED__M) | data, 0);
  4497. if (rc != 0) {
  4498. pr_err("error %d\n", rc);
  4499. goto rw_error;
  4500. }
  4501. if (agc_settings->standard == DRX_STANDARD_8VSB)
  4502. p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
  4503. else if (DRXJ_ISQAMSTD(agc_settings->standard))
  4504. p_agc_settings = &(ext_attr->qam_if_agc_cfg);
  4505. else if (DRXJ_ISATVSTD(agc_settings->standard))
  4506. p_agc_settings = &(ext_attr->atv_if_agc_cfg);
  4507. else
  4508. return -EINVAL;
  4509. /* Set TOP, only if IF-AGC is in AUTO mode */
  4510. if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
  4511. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
  4512. if (rc != 0) {
  4513. pr_err("error %d\n", rc);
  4514. goto rw_error;
  4515. }
  4516. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
  4517. if (rc != 0) {
  4518. pr_err("error %d\n", rc);
  4519. goto rw_error;
  4520. }
  4521. }
  4522. /* Cut-Off current */
  4523. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
  4524. if (rc != 0) {
  4525. pr_err("error %d\n", rc);
  4526. goto rw_error;
  4527. }
  4528. break;
  4529. case DRX_AGC_CTRL_USER:
  4530. /* Enable RF AGC DAC */
  4531. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
  4532. if (rc != 0) {
  4533. pr_err("error %d\n", rc);
  4534. goto rw_error;
  4535. }
  4536. data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
  4537. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
  4538. if (rc != 0) {
  4539. pr_err("error %d\n", rc);
  4540. goto rw_error;
  4541. }
  4542. /* Disable SCU RF AGC loop */
  4543. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
  4544. if (rc != 0) {
  4545. pr_err("error %d\n", rc);
  4546. goto rw_error;
  4547. }
  4548. data &= ~SCU_RAM_AGC_KI_RF__M;
  4549. if (common_attr->tuner_rf_agc_pol)
  4550. data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
  4551. else
  4552. data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
  4553. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
  4554. if (rc != 0) {
  4555. pr_err("error %d\n", rc);
  4556. goto rw_error;
  4557. }
  4558. /* Write value to output pin */
  4559. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
  4560. if (rc != 0) {
  4561. pr_err("error %d\n", rc);
  4562. goto rw_error;
  4563. }
  4564. break;
  4565. case DRX_AGC_CTRL_OFF:
  4566. /* Disable RF AGC DAC */
  4567. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
  4568. if (rc != 0) {
  4569. pr_err("error %d\n", rc);
  4570. goto rw_error;
  4571. }
  4572. data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
  4573. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
  4574. if (rc != 0) {
  4575. pr_err("error %d\n", rc);
  4576. goto rw_error;
  4577. }
  4578. /* Disable SCU RF AGC loop */
  4579. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
  4580. if (rc != 0) {
  4581. pr_err("error %d\n", rc);
  4582. goto rw_error;
  4583. }
  4584. data &= ~SCU_RAM_AGC_KI_RF__M;
  4585. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
  4586. if (rc != 0) {
  4587. pr_err("error %d\n", rc);
  4588. goto rw_error;
  4589. }
  4590. break;
  4591. default:
  4592. return -EINVAL;
  4593. } /* switch ( agcsettings->ctrl_mode ) */
  4594. }
  4595. /* Store rf agc settings */
  4596. switch (agc_settings->standard) {
  4597. case DRX_STANDARD_8VSB:
  4598. ext_attr->vsb_rf_agc_cfg = *agc_settings;
  4599. break;
  4600. #ifndef DRXJ_VSB_ONLY
  4601. case DRX_STANDARD_ITU_A:
  4602. case DRX_STANDARD_ITU_B:
  4603. case DRX_STANDARD_ITU_C:
  4604. ext_attr->qam_rf_agc_cfg = *agc_settings;
  4605. break;
  4606. #endif
  4607. default:
  4608. return -EIO;
  4609. }
  4610. return 0;
  4611. rw_error:
  4612. return rc;
  4613. }
  4614. /**
  4615. * \fn int set_agc_if ()
  4616. * \brief Configure If AGC
  4617. * \param demod instance of demodulator.
  4618. * \param agc_settings AGC configuration structure
  4619. * \return int.
  4620. */
  4621. static int
  4622. set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
  4623. {
  4624. struct i2c_device_addr *dev_addr = NULL;
  4625. struct drxj_data *ext_attr = NULL;
  4626. struct drxj_cfg_agc *p_agc_settings = NULL;
  4627. struct drx_common_attr *common_attr = NULL;
  4628. drx_write_reg16func_t scu_wr16 = NULL;
  4629. drx_read_reg16func_t scu_rr16 = NULL;
  4630. int rc;
  4631. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  4632. dev_addr = demod->my_i2c_dev_addr;
  4633. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  4634. if (atomic) {
  4635. scu_rr16 = drxj_dap_scu_atomic_read_reg16;
  4636. scu_wr16 = drxj_dap_scu_atomic_write_reg16;
  4637. } else {
  4638. scu_rr16 = drxj_dap_read_reg16;
  4639. scu_wr16 = drxj_dap_write_reg16;
  4640. }
  4641. /* Configure AGC only if standard is currently active */
  4642. if ((ext_attr->standard == agc_settings->standard) ||
  4643. (DRXJ_ISQAMSTD(ext_attr->standard) &&
  4644. DRXJ_ISQAMSTD(agc_settings->standard)) ||
  4645. (DRXJ_ISATVSTD(ext_attr->standard) &&
  4646. DRXJ_ISATVSTD(agc_settings->standard))) {
  4647. u16 data = 0;
  4648. switch (agc_settings->ctrl_mode) {
  4649. case DRX_AGC_CTRL_AUTO:
  4650. /* Enable IF AGC DAC */
  4651. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
  4652. if (rc != 0) {
  4653. pr_err("error %d\n", rc);
  4654. goto rw_error;
  4655. }
  4656. data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
  4657. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
  4658. if (rc != 0) {
  4659. pr_err("error %d\n", rc);
  4660. goto rw_error;
  4661. }
  4662. /* Enable SCU IF AGC loop */
  4663. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
  4664. if (rc != 0) {
  4665. pr_err("error %d\n", rc);
  4666. goto rw_error;
  4667. }
  4668. data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
  4669. data &= ~SCU_RAM_AGC_KI_IF__M;
  4670. if (ext_attr->standard == DRX_STANDARD_8VSB)
  4671. data |= (3 << SCU_RAM_AGC_KI_IF__B);
  4672. else if (DRXJ_ISQAMSTD(ext_attr->standard))
  4673. data |= (6 << SCU_RAM_AGC_KI_IF__B);
  4674. else
  4675. data |= (5 << SCU_RAM_AGC_KI_IF__B);
  4676. if (common_attr->tuner_if_agc_pol)
  4677. data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
  4678. else
  4679. data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
  4680. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
  4681. if (rc != 0) {
  4682. pr_err("error %d\n", rc);
  4683. goto rw_error;
  4684. }
  4685. /* Set speed (using complementary reduction value) */
  4686. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
  4687. if (rc != 0) {
  4688. pr_err("error %d\n", rc);
  4689. goto rw_error;
  4690. }
  4691. data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
  4692. rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_IAGC_RED__B) & SCU_RAM_AGC_KI_RED_IAGC_RED__M) | data, 0);
  4693. if (rc != 0) {
  4694. pr_err("error %d\n", rc);
  4695. goto rw_error;
  4696. }
  4697. if (agc_settings->standard == DRX_STANDARD_8VSB)
  4698. p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
  4699. else if (DRXJ_ISQAMSTD(agc_settings->standard))
  4700. p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
  4701. else if (DRXJ_ISATVSTD(agc_settings->standard))
  4702. p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
  4703. else
  4704. return -EINVAL;
  4705. /* Restore TOP */
  4706. if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
  4707. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
  4708. if (rc != 0) {
  4709. pr_err("error %d\n", rc);
  4710. goto rw_error;
  4711. }
  4712. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
  4713. if (rc != 0) {
  4714. pr_err("error %d\n", rc);
  4715. goto rw_error;
  4716. }
  4717. } else {
  4718. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
  4719. if (rc != 0) {
  4720. pr_err("error %d\n", rc);
  4721. goto rw_error;
  4722. }
  4723. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
  4724. if (rc != 0) {
  4725. pr_err("error %d\n", rc);
  4726. goto rw_error;
  4727. }
  4728. }
  4729. break;
  4730. case DRX_AGC_CTRL_USER:
  4731. /* Enable IF AGC DAC */
  4732. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
  4733. if (rc != 0) {
  4734. pr_err("error %d\n", rc);
  4735. goto rw_error;
  4736. }
  4737. data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
  4738. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
  4739. if (rc != 0) {
  4740. pr_err("error %d\n", rc);
  4741. goto rw_error;
  4742. }
  4743. /* Disable SCU IF AGC loop */
  4744. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
  4745. if (rc != 0) {
  4746. pr_err("error %d\n", rc);
  4747. goto rw_error;
  4748. }
  4749. data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
  4750. data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
  4751. if (common_attr->tuner_if_agc_pol)
  4752. data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
  4753. else
  4754. data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
  4755. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
  4756. if (rc != 0) {
  4757. pr_err("error %d\n", rc);
  4758. goto rw_error;
  4759. }
  4760. /* Write value to output pin */
  4761. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
  4762. if (rc != 0) {
  4763. pr_err("error %d\n", rc);
  4764. goto rw_error;
  4765. }
  4766. break;
  4767. case DRX_AGC_CTRL_OFF:
  4768. /* Disable If AGC DAC */
  4769. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
  4770. if (rc != 0) {
  4771. pr_err("error %d\n", rc);
  4772. goto rw_error;
  4773. }
  4774. data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
  4775. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
  4776. if (rc != 0) {
  4777. pr_err("error %d\n", rc);
  4778. goto rw_error;
  4779. }
  4780. /* Disable SCU IF AGC loop */
  4781. rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
  4782. if (rc != 0) {
  4783. pr_err("error %d\n", rc);
  4784. goto rw_error;
  4785. }
  4786. data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
  4787. data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
  4788. rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
  4789. if (rc != 0) {
  4790. pr_err("error %d\n", rc);
  4791. goto rw_error;
  4792. }
  4793. break;
  4794. default:
  4795. return -EINVAL;
  4796. } /* switch ( agcsettings->ctrl_mode ) */
  4797. /* always set the top to support configurations without if-loop */
  4798. rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
  4799. if (rc != 0) {
  4800. pr_err("error %d\n", rc);
  4801. goto rw_error;
  4802. }
  4803. }
  4804. /* Store if agc settings */
  4805. switch (agc_settings->standard) {
  4806. case DRX_STANDARD_8VSB:
  4807. ext_attr->vsb_if_agc_cfg = *agc_settings;
  4808. break;
  4809. #ifndef DRXJ_VSB_ONLY
  4810. case DRX_STANDARD_ITU_A:
  4811. case DRX_STANDARD_ITU_B:
  4812. case DRX_STANDARD_ITU_C:
  4813. ext_attr->qam_if_agc_cfg = *agc_settings;
  4814. break;
  4815. #endif
  4816. default:
  4817. return -EIO;
  4818. }
  4819. return 0;
  4820. rw_error:
  4821. return rc;
  4822. }
  4823. /**
  4824. * \fn int set_iqm_af ()
  4825. * \brief Configure IQM AF registers
  4826. * \param demod instance of demodulator.
  4827. * \param active
  4828. * \return int.
  4829. */
  4830. static int set_iqm_af(struct drx_demod_instance *demod, bool active)
  4831. {
  4832. u16 data = 0;
  4833. struct i2c_device_addr *dev_addr = NULL;
  4834. int rc;
  4835. dev_addr = demod->my_i2c_dev_addr;
  4836. /* Configure IQM */
  4837. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
  4838. if (rc != 0) {
  4839. pr_err("error %d\n", rc);
  4840. goto rw_error;
  4841. }
  4842. if (!active)
  4843. data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE));
  4844. else
  4845. data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
  4846. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
  4847. if (rc != 0) {
  4848. pr_err("error %d\n", rc);
  4849. goto rw_error;
  4850. }
  4851. return 0;
  4852. rw_error:
  4853. return rc;
  4854. }
  4855. /*============================================================================*/
  4856. /*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
  4857. /*============================================================================*/
  4858. /*============================================================================*/
  4859. /*============================================================================*/
  4860. /*== 8VSB DATAPATH FUNCTIONS ==*/
  4861. /*============================================================================*/
  4862. /*============================================================================*/
  4863. /**
  4864. * \fn int power_down_vsb ()
  4865. * \brief Powr down QAM related blocks.
  4866. * \param demod instance of demodulator.
  4867. * \param channel pointer to channel data.
  4868. * \return int.
  4869. */
  4870. static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
  4871. {
  4872. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  4873. struct drxjscu_cmd cmd_scu = { /* command */ 0,
  4874. /* parameter_len */ 0,
  4875. /* result_len */ 0,
  4876. /* *parameter */ NULL,
  4877. /* *result */ NULL
  4878. };
  4879. struct drx_cfg_mpeg_output cfg_mpeg_output;
  4880. int rc;
  4881. u16 cmd_result = 0;
  4882. /*
  4883. STOP demodulator
  4884. reset of FEC and VSB HW
  4885. */
  4886. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
  4887. SCU_RAM_COMMAND_CMD_DEMOD_STOP;
  4888. cmd_scu.parameter_len = 0;
  4889. cmd_scu.result_len = 1;
  4890. cmd_scu.parameter = NULL;
  4891. cmd_scu.result = &cmd_result;
  4892. rc = scu_command(dev_addr, &cmd_scu);
  4893. if (rc != 0) {
  4894. pr_err("error %d\n", rc);
  4895. goto rw_error;
  4896. }
  4897. /* stop all comm_exec */
  4898. rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
  4899. if (rc != 0) {
  4900. pr_err("error %d\n", rc);
  4901. goto rw_error;
  4902. }
  4903. rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
  4904. if (rc != 0) {
  4905. pr_err("error %d\n", rc);
  4906. goto rw_error;
  4907. }
  4908. if (primary) {
  4909. rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
  4910. if (rc != 0) {
  4911. pr_err("error %d\n", rc);
  4912. goto rw_error;
  4913. }
  4914. rc = set_iqm_af(demod, false);
  4915. if (rc != 0) {
  4916. pr_err("error %d\n", rc);
  4917. goto rw_error;
  4918. }
  4919. } else {
  4920. rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
  4921. if (rc != 0) {
  4922. pr_err("error %d\n", rc);
  4923. goto rw_error;
  4924. }
  4925. rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
  4926. if (rc != 0) {
  4927. pr_err("error %d\n", rc);
  4928. goto rw_error;
  4929. }
  4930. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
  4931. if (rc != 0) {
  4932. pr_err("error %d\n", rc);
  4933. goto rw_error;
  4934. }
  4935. rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
  4936. if (rc != 0) {
  4937. pr_err("error %d\n", rc);
  4938. goto rw_error;
  4939. }
  4940. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
  4941. if (rc != 0) {
  4942. pr_err("error %d\n", rc);
  4943. goto rw_error;
  4944. }
  4945. }
  4946. cfg_mpeg_output.enable_mpeg_output = false;
  4947. rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
  4948. if (rc != 0) {
  4949. pr_err("error %d\n", rc);
  4950. goto rw_error;
  4951. }
  4952. return 0;
  4953. rw_error:
  4954. return rc;
  4955. }
  4956. /**
  4957. * \fn int set_vsb_leak_n_gain ()
  4958. * \brief Set ATSC demod.
  4959. * \param demod instance of demodulator.
  4960. * \return int.
  4961. */
  4962. static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
  4963. {
  4964. struct i2c_device_addr *dev_addr = NULL;
  4965. int rc;
  4966. const u8 vsb_ffe_leak_gain_ram0[] = {
  4967. DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
  4968. DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
  4969. DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
  4970. DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
  4971. DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
  4972. DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
  4973. DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
  4974. DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
  4975. DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
  4976. DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
  4977. DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
  4978. DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
  4979. DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
  4980. DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
  4981. DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
  4982. DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
  4983. DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
  4984. DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
  4985. DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
  4986. DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
  4987. DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
  4988. DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
  4989. DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
  4990. DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
  4991. DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
  4992. DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
  4993. DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
  4994. DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
  4995. DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
  4996. DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
  4997. DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
  4998. DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
  4999. DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
  5000. DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
  5001. DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
  5002. DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
  5003. DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
  5004. DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
  5005. DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
  5006. DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
  5007. DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
  5008. DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
  5009. DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
  5010. DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
  5011. DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
  5012. DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
  5013. DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
  5014. DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
  5015. DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
  5016. DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
  5017. DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
  5018. DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
  5019. DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
  5020. DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
  5021. DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
  5022. DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
  5023. DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
  5024. DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
  5025. DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
  5026. DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
  5027. DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
  5028. DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
  5029. DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
  5030. DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
  5031. DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
  5032. DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
  5033. DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
  5034. DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
  5035. DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
  5036. DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
  5037. DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
  5038. DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
  5039. DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
  5040. DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
  5041. DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
  5042. DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
  5043. DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
  5044. DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
  5045. DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
  5046. DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
  5047. DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
  5048. DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
  5049. DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
  5050. DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
  5051. DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
  5052. DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
  5053. DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
  5054. DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
  5055. DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
  5056. DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
  5057. DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
  5058. DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
  5059. DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
  5060. DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
  5061. DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
  5062. DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
  5063. DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
  5064. DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
  5065. DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
  5066. DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
  5067. DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
  5068. DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
  5069. DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
  5070. DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
  5071. DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
  5072. DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
  5073. DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
  5074. DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
  5075. DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
  5076. DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
  5077. DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
  5078. DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
  5079. DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
  5080. DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
  5081. DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
  5082. DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
  5083. DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
  5084. DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
  5085. DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
  5086. DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
  5087. DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
  5088. DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
  5089. DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
  5090. DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
  5091. DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
  5092. DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
  5093. DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
  5094. DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
  5095. };
  5096. const u8 vsb_ffe_leak_gain_ram1[] = {
  5097. DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
  5098. DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
  5099. DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
  5100. DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
  5101. DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
  5102. DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
  5103. DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
  5104. DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
  5105. DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
  5106. DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
  5107. DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
  5108. DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
  5109. DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
  5110. DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
  5111. DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
  5112. DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
  5113. DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
  5114. DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
  5115. DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
  5116. DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
  5117. DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
  5118. DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
  5119. DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
  5120. DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
  5121. DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
  5122. DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
  5123. DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
  5124. DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
  5125. DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
  5126. DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
  5127. DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
  5128. DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
  5129. DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
  5130. DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
  5131. DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
  5132. DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
  5133. DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
  5134. DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
  5135. DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
  5136. DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
  5137. DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
  5138. DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
  5139. DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
  5140. DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
  5141. DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
  5142. DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
  5143. DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
  5144. DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
  5145. DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
  5146. DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
  5147. DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
  5148. DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
  5149. DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
  5150. DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
  5151. };
  5152. dev_addr = demod->my_i2c_dev_addr;
  5153. rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
  5154. if (rc != 0) {
  5155. pr_err("error %d\n", rc);
  5156. goto rw_error;
  5157. }
  5158. rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
  5159. if (rc != 0) {
  5160. pr_err("error %d\n", rc);
  5161. goto rw_error;
  5162. }
  5163. return 0;
  5164. rw_error:
  5165. return rc;
  5166. }
  5167. /**
  5168. * \fn int set_vsb()
  5169. * \brief Set 8VSB demod.
  5170. * \param demod instance of demodulator.
  5171. * \return int.
  5172. *
  5173. */
  5174. static int set_vsb(struct drx_demod_instance *demod)
  5175. {
  5176. struct i2c_device_addr *dev_addr = NULL;
  5177. int rc;
  5178. struct drx_common_attr *common_attr = NULL;
  5179. struct drxjscu_cmd cmd_scu;
  5180. struct drxj_data *ext_attr = NULL;
  5181. u16 cmd_result = 0;
  5182. u16 cmd_param = 0;
  5183. const u8 vsb_taps_re[] = {
  5184. DRXJ_16TO8(-2), /* re0 */
  5185. DRXJ_16TO8(4), /* re1 */
  5186. DRXJ_16TO8(1), /* re2 */
  5187. DRXJ_16TO8(-4), /* re3 */
  5188. DRXJ_16TO8(1), /* re4 */
  5189. DRXJ_16TO8(4), /* re5 */
  5190. DRXJ_16TO8(-3), /* re6 */
  5191. DRXJ_16TO8(-3), /* re7 */
  5192. DRXJ_16TO8(6), /* re8 */
  5193. DRXJ_16TO8(1), /* re9 */
  5194. DRXJ_16TO8(-9), /* re10 */
  5195. DRXJ_16TO8(3), /* re11 */
  5196. DRXJ_16TO8(12), /* re12 */
  5197. DRXJ_16TO8(-9), /* re13 */
  5198. DRXJ_16TO8(-15), /* re14 */
  5199. DRXJ_16TO8(17), /* re15 */
  5200. DRXJ_16TO8(19), /* re16 */
  5201. DRXJ_16TO8(-29), /* re17 */
  5202. DRXJ_16TO8(-22), /* re18 */
  5203. DRXJ_16TO8(45), /* re19 */
  5204. DRXJ_16TO8(25), /* re20 */
  5205. DRXJ_16TO8(-70), /* re21 */
  5206. DRXJ_16TO8(-28), /* re22 */
  5207. DRXJ_16TO8(111), /* re23 */
  5208. DRXJ_16TO8(30), /* re24 */
  5209. DRXJ_16TO8(-201), /* re25 */
  5210. DRXJ_16TO8(-31), /* re26 */
  5211. DRXJ_16TO8(629) /* re27 */
  5212. };
  5213. dev_addr = demod->my_i2c_dev_addr;
  5214. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  5215. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  5216. /* stop all comm_exec */
  5217. rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
  5218. if (rc != 0) {
  5219. pr_err("error %d\n", rc);
  5220. goto rw_error;
  5221. }
  5222. rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
  5223. if (rc != 0) {
  5224. pr_err("error %d\n", rc);
  5225. goto rw_error;
  5226. }
  5227. rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
  5228. if (rc != 0) {
  5229. pr_err("error %d\n", rc);
  5230. goto rw_error;
  5231. }
  5232. rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
  5233. if (rc != 0) {
  5234. pr_err("error %d\n", rc);
  5235. goto rw_error;
  5236. }
  5237. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
  5238. if (rc != 0) {
  5239. pr_err("error %d\n", rc);
  5240. goto rw_error;
  5241. }
  5242. rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
  5243. if (rc != 0) {
  5244. pr_err("error %d\n", rc);
  5245. goto rw_error;
  5246. }
  5247. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
  5248. if (rc != 0) {
  5249. pr_err("error %d\n", rc);
  5250. goto rw_error;
  5251. }
  5252. /* reset demodulator */
  5253. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
  5254. | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
  5255. cmd_scu.parameter_len = 0;
  5256. cmd_scu.result_len = 1;
  5257. cmd_scu.parameter = NULL;
  5258. cmd_scu.result = &cmd_result;
  5259. rc = scu_command(dev_addr, &cmd_scu);
  5260. if (rc != 0) {
  5261. pr_err("error %d\n", rc);
  5262. goto rw_error;
  5263. }
  5264. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
  5265. if (rc != 0) {
  5266. pr_err("error %d\n", rc);
  5267. goto rw_error;
  5268. }
  5269. rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
  5270. if (rc != 0) {
  5271. pr_err("error %d\n", rc);
  5272. goto rw_error;
  5273. }
  5274. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
  5275. if (rc != 0) {
  5276. pr_err("error %d\n", rc);
  5277. goto rw_error;
  5278. }
  5279. ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
  5280. rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
  5281. if (rc != 0) {
  5282. pr_err("error %d\n", rc);
  5283. goto rw_error;
  5284. }
  5285. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
  5286. if (rc != 0) {
  5287. pr_err("error %d\n", rc);
  5288. goto rw_error;
  5289. }
  5290. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
  5291. if (rc != 0) {
  5292. pr_err("error %d\n", rc);
  5293. goto rw_error;
  5294. }
  5295. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
  5296. if (rc != 0) {
  5297. pr_err("error %d\n", rc);
  5298. goto rw_error;
  5299. }
  5300. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);
  5301. if (rc != 0) {
  5302. pr_err("error %d\n", rc);
  5303. goto rw_error;
  5304. }
  5305. rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
  5306. if (rc != 0) {
  5307. pr_err("error %d\n", rc);
  5308. goto rw_error;
  5309. }
  5310. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
  5311. if (rc != 0) {
  5312. pr_err("error %d\n", rc);
  5313. goto rw_error;
  5314. }
  5315. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
  5316. if (rc != 0) {
  5317. pr_err("error %d\n", rc);
  5318. goto rw_error;
  5319. }
  5320. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
  5321. if (rc != 0) {
  5322. pr_err("error %d\n", rc);
  5323. goto rw_error;
  5324. }
  5325. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);
  5326. if (rc != 0) {
  5327. pr_err("error %d\n", rc);
  5328. goto rw_error;
  5329. }
  5330. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
  5331. if (rc != 0) {
  5332. pr_err("error %d\n", rc);
  5333. goto rw_error;
  5334. }
  5335. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
  5336. if (rc != 0) {
  5337. pr_err("error %d\n", rc);
  5338. goto rw_error;
  5339. }
  5340. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
  5341. if (rc != 0) {
  5342. pr_err("error %d\n", rc);
  5343. goto rw_error;
  5344. }
  5345. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
  5346. if (rc != 0) {
  5347. pr_err("error %d\n", rc);
  5348. goto rw_error;
  5349. }
  5350. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
  5351. if (rc != 0) {
  5352. pr_err("error %d\n", rc);
  5353. goto rw_error;
  5354. } /* set higher threshold */
  5355. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
  5356. if (rc != 0) {
  5357. pr_err("error %d\n", rc);
  5358. goto rw_error;
  5359. } /* burst detection on */
  5360. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
  5361. if (rc != 0) {
  5362. pr_err("error %d\n", rc);
  5363. goto rw_error;
  5364. } /* drop thresholds by 1 dB */
  5365. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
  5366. if (rc != 0) {
  5367. pr_err("error %d\n", rc);
  5368. goto rw_error;
  5369. } /* drop thresholds by 2 dB */
  5370. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
  5371. if (rc != 0) {
  5372. pr_err("error %d\n", rc);
  5373. goto rw_error;
  5374. } /* cma on */
  5375. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
  5376. if (rc != 0) {
  5377. pr_err("error %d\n", rc);
  5378. goto rw_error;
  5379. } /* GPIO */
  5380. /* Initialize the FEC Subsystem */
  5381. rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
  5382. if (rc != 0) {
  5383. pr_err("error %d\n", rc);
  5384. goto rw_error;
  5385. }
  5386. {
  5387. u16 fec_oc_snc_mode = 0;
  5388. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
  5389. if (rc != 0) {
  5390. pr_err("error %d\n", rc);
  5391. goto rw_error;
  5392. }
  5393. /* output data even when not locked */
  5394. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
  5395. if (rc != 0) {
  5396. pr_err("error %d\n", rc);
  5397. goto rw_error;
  5398. }
  5399. }
  5400. /* set clip */
  5401. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
  5402. if (rc != 0) {
  5403. pr_err("error %d\n", rc);
  5404. goto rw_error;
  5405. }
  5406. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
  5407. if (rc != 0) {
  5408. pr_err("error %d\n", rc);
  5409. goto rw_error;
  5410. }
  5411. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
  5412. if (rc != 0) {
  5413. pr_err("error %d\n", rc);
  5414. goto rw_error;
  5415. }
  5416. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
  5417. if (rc != 0) {
  5418. pr_err("error %d\n", rc);
  5419. goto rw_error;
  5420. }
  5421. /* no transparent, no A&C framing; parity is set in mpegoutput */
  5422. {
  5423. u16 fec_oc_reg_mode = 0;
  5424. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
  5425. if (rc != 0) {
  5426. pr_err("error %d\n", rc);
  5427. goto rw_error;
  5428. }
  5429. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), 0);
  5430. if (rc != 0) {
  5431. pr_err("error %d\n", rc);
  5432. goto rw_error;
  5433. }
  5434. }
  5435. rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
  5436. if (rc != 0) {
  5437. pr_err("error %d\n", rc);
  5438. goto rw_error;
  5439. } /* timeout counter for restarting */
  5440. rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
  5441. if (rc != 0) {
  5442. pr_err("error %d\n", rc);
  5443. goto rw_error;
  5444. }
  5445. rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);
  5446. if (rc != 0) {
  5447. pr_err("error %d\n", rc);
  5448. goto rw_error;
  5449. } /* bypass disabled */
  5450. /* initialize RS packet error measurement parameters */
  5451. rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
  5452. if (rc != 0) {
  5453. pr_err("error %d\n", rc);
  5454. goto rw_error;
  5455. }
  5456. rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
  5457. if (rc != 0) {
  5458. pr_err("error %d\n", rc);
  5459. goto rw_error;
  5460. }
  5461. /* init measurement period of MER/SER */
  5462. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
  5463. if (rc != 0) {
  5464. pr_err("error %d\n", rc);
  5465. goto rw_error;
  5466. }
  5467. rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
  5468. if (rc != 0) {
  5469. pr_err("error %d\n", rc);
  5470. goto rw_error;
  5471. }
  5472. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
  5473. if (rc != 0) {
  5474. pr_err("error %d\n", rc);
  5475. goto rw_error;
  5476. }
  5477. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
  5478. if (rc != 0) {
  5479. pr_err("error %d\n", rc);
  5480. goto rw_error;
  5481. }
  5482. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
  5483. if (rc != 0) {
  5484. pr_err("error %d\n", rc);
  5485. goto rw_error;
  5486. }
  5487. /* B-Input to ADC, PGA+filter in standby */
  5488. if (!ext_attr->has_lna) {
  5489. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
  5490. if (rc != 0) {
  5491. pr_err("error %d\n", rc);
  5492. goto rw_error;
  5493. }
  5494. }
  5495. /* turn on IQMAF. It has to be in front of setAgc**() */
  5496. rc = set_iqm_af(demod, true);
  5497. if (rc != 0) {
  5498. pr_err("error %d\n", rc);
  5499. goto rw_error;
  5500. }
  5501. rc = adc_synchronization(demod);
  5502. if (rc != 0) {
  5503. pr_err("error %d\n", rc);
  5504. goto rw_error;
  5505. }
  5506. rc = init_agc(demod);
  5507. if (rc != 0) {
  5508. pr_err("error %d\n", rc);
  5509. goto rw_error;
  5510. }
  5511. rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
  5512. if (rc != 0) {
  5513. pr_err("error %d\n", rc);
  5514. goto rw_error;
  5515. }
  5516. rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
  5517. if (rc != 0) {
  5518. pr_err("error %d\n", rc);
  5519. goto rw_error;
  5520. }
  5521. {
  5522. /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
  5523. of only the gain */
  5524. struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
  5525. vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
  5526. rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
  5527. if (rc != 0) {
  5528. pr_err("error %d\n", rc);
  5529. goto rw_error;
  5530. }
  5531. }
  5532. rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
  5533. if (rc != 0) {
  5534. pr_err("error %d\n", rc);
  5535. goto rw_error;
  5536. }
  5537. /* Mpeg output has to be in front of FEC active */
  5538. rc = set_mpegtei_handling(demod);
  5539. if (rc != 0) {
  5540. pr_err("error %d\n", rc);
  5541. goto rw_error;
  5542. }
  5543. rc = bit_reverse_mpeg_output(demod);
  5544. if (rc != 0) {
  5545. pr_err("error %d\n", rc);
  5546. goto rw_error;
  5547. }
  5548. rc = set_mpeg_start_width(demod);
  5549. if (rc != 0) {
  5550. pr_err("error %d\n", rc);
  5551. goto rw_error;
  5552. }
  5553. {
  5554. /* TODO: move to set_standard after hardware reset value problem is solved */
  5555. /* Configure initial MPEG output */
  5556. struct drx_cfg_mpeg_output cfg_mpeg_output;
  5557. memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
  5558. cfg_mpeg_output.enable_mpeg_output = true;
  5559. rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
  5560. if (rc != 0) {
  5561. pr_err("error %d\n", rc);
  5562. goto rw_error;
  5563. }
  5564. }
  5565. /* TBD: what parameters should be set */
  5566. cmd_param = 0x00; /* Default mode AGC on, etc */
  5567. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
  5568. | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
  5569. cmd_scu.parameter_len = 1;
  5570. cmd_scu.result_len = 1;
  5571. cmd_scu.parameter = &cmd_param;
  5572. cmd_scu.result = &cmd_result;
  5573. rc = scu_command(dev_addr, &cmd_scu);
  5574. if (rc != 0) {
  5575. pr_err("error %d\n", rc);
  5576. goto rw_error;
  5577. }
  5578. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
  5579. if (rc != 0) {
  5580. pr_err("error %d\n", rc);
  5581. goto rw_error;
  5582. }
  5583. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
  5584. if (rc != 0) {
  5585. pr_err("error %d\n", rc);
  5586. goto rw_error;
  5587. }
  5588. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
  5589. if (rc != 0) {
  5590. pr_err("error %d\n", rc);
  5591. goto rw_error;
  5592. }
  5593. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
  5594. if (rc != 0) {
  5595. pr_err("error %d\n", rc);
  5596. goto rw_error;
  5597. }
  5598. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
  5599. if (rc != 0) {
  5600. pr_err("error %d\n", rc);
  5601. goto rw_error;
  5602. }
  5603. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
  5604. if (rc != 0) {
  5605. pr_err("error %d\n", rc);
  5606. goto rw_error;
  5607. }
  5608. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
  5609. if (rc != 0) {
  5610. pr_err("error %d\n", rc);
  5611. goto rw_error;
  5612. }
  5613. rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
  5614. if (rc != 0) {
  5615. pr_err("error %d\n", rc);
  5616. goto rw_error;
  5617. }
  5618. /* start demodulator */
  5619. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
  5620. | SCU_RAM_COMMAND_CMD_DEMOD_START;
  5621. cmd_scu.parameter_len = 0;
  5622. cmd_scu.result_len = 1;
  5623. cmd_scu.parameter = NULL;
  5624. cmd_scu.result = &cmd_result;
  5625. rc = scu_command(dev_addr, &cmd_scu);
  5626. if (rc != 0) {
  5627. pr_err("error %d\n", rc);
  5628. goto rw_error;
  5629. }
  5630. rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
  5631. if (rc != 0) {
  5632. pr_err("error %d\n", rc);
  5633. goto rw_error;
  5634. }
  5635. rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
  5636. if (rc != 0) {
  5637. pr_err("error %d\n", rc);
  5638. goto rw_error;
  5639. }
  5640. rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
  5641. if (rc != 0) {
  5642. pr_err("error %d\n", rc);
  5643. goto rw_error;
  5644. }
  5645. return 0;
  5646. rw_error:
  5647. return rc;
  5648. }
  5649. /**
  5650. * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
  5651. * \brief Get the values of packet error in 8VSB mode
  5652. * \return Error code
  5653. */
  5654. static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
  5655. u32 *pck_errs, u32 *pck_count)
  5656. {
  5657. int rc;
  5658. u16 data = 0;
  5659. u16 period = 0;
  5660. u16 prescale = 0;
  5661. u16 packet_errors_mant = 0;
  5662. u16 packet_errors_exp = 0;
  5663. rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
  5664. if (rc != 0) {
  5665. pr_err("error %d\n", rc);
  5666. goto rw_error;
  5667. }
  5668. packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
  5669. packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
  5670. >> FEC_RS_NR_FAILURES_EXP__B;
  5671. period = FEC_RS_MEASUREMENT_PERIOD;
  5672. prescale = FEC_RS_MEASUREMENT_PRESCALE;
  5673. /* packet error rate = (error packet number) per second */
  5674. /* 77.3 us is time for per packet */
  5675. if (period * prescale == 0) {
  5676. pr_err("error: period and/or prescale is zero!\n");
  5677. return -EIO;
  5678. }
  5679. *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
  5680. *pck_count = period * prescale * 77;
  5681. return 0;
  5682. rw_error:
  5683. return rc;
  5684. }
  5685. /**
  5686. * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
  5687. * \brief Get the values of ber in VSB mode
  5688. * \return Error code
  5689. */
  5690. static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
  5691. u32 *ber, u32 *cnt)
  5692. {
  5693. int rc;
  5694. u16 data = 0;
  5695. u16 period = 0;
  5696. u16 prescale = 0;
  5697. u16 bit_errors_mant = 0;
  5698. u16 bit_errors_exp = 0;
  5699. rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
  5700. if (rc != 0) {
  5701. pr_err("error %d\n", rc);
  5702. goto rw_error;
  5703. }
  5704. period = FEC_RS_MEASUREMENT_PERIOD;
  5705. prescale = FEC_RS_MEASUREMENT_PRESCALE;
  5706. bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
  5707. bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
  5708. >> FEC_RS_NR_BIT_ERRORS_EXP__B;
  5709. *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
  5710. if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
  5711. *ber = (*cnt) * 26570;
  5712. else {
  5713. if (period * prescale == 0) {
  5714. pr_err("error: period and/or prescale is zero!\n");
  5715. return -EIO;
  5716. }
  5717. *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
  5718. (bit_errors_exp - 3) : bit_errors_exp);
  5719. }
  5720. return 0;
  5721. rw_error:
  5722. return rc;
  5723. }
  5724. /**
  5725. * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
  5726. * \brief Get the values of ber in VSB mode
  5727. * \return Error code
  5728. */
  5729. static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
  5730. u32 *ber, u32 *cnt)
  5731. {
  5732. u16 data = 0;
  5733. int rc;
  5734. rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
  5735. if (rc != 0) {
  5736. pr_err("error %d\n", rc);
  5737. return -EIO;
  5738. }
  5739. *ber = data;
  5740. *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
  5741. return 0;
  5742. }
  5743. /**
  5744. * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
  5745. * \brief Get the values of MER
  5746. * \return Error code
  5747. */
  5748. static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
  5749. {
  5750. int rc;
  5751. u16 data_hi = 0;
  5752. rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
  5753. if (rc != 0) {
  5754. pr_err("error %d\n", rc);
  5755. goto rw_error;
  5756. }
  5757. *mer =
  5758. (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
  5759. return 0;
  5760. rw_error:
  5761. return rc;
  5762. }
  5763. /*============================================================================*/
  5764. /*== END 8VSB DATAPATH FUNCTIONS ==*/
  5765. /*============================================================================*/
  5766. /*============================================================================*/
  5767. /*============================================================================*/
  5768. /*== QAM DATAPATH FUNCTIONS ==*/
  5769. /*============================================================================*/
  5770. /*============================================================================*/
  5771. /**
  5772. * \fn int power_down_qam ()
  5773. * \brief Powr down QAM related blocks.
  5774. * \param demod instance of demodulator.
  5775. * \param channel pointer to channel data.
  5776. * \return int.
  5777. */
  5778. static int power_down_qam(struct drx_demod_instance *demod, bool primary)
  5779. {
  5780. struct drxjscu_cmd cmd_scu = { /* command */ 0,
  5781. /* parameter_len */ 0,
  5782. /* result_len */ 0,
  5783. /* *parameter */ NULL,
  5784. /* *result */ NULL
  5785. };
  5786. int rc;
  5787. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  5788. struct drx_cfg_mpeg_output cfg_mpeg_output;
  5789. struct drx_common_attr *common_attr = demod->my_common_attr;
  5790. u16 cmd_result = 0;
  5791. /*
  5792. STOP demodulator
  5793. resets IQM, QAM and FEC HW blocks
  5794. */
  5795. /* stop all comm_exec */
  5796. rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
  5797. if (rc != 0) {
  5798. pr_err("error %d\n", rc);
  5799. goto rw_error;
  5800. }
  5801. rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
  5802. if (rc != 0) {
  5803. pr_err("error %d\n", rc);
  5804. goto rw_error;
  5805. }
  5806. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
  5807. SCU_RAM_COMMAND_CMD_DEMOD_STOP;
  5808. cmd_scu.parameter_len = 0;
  5809. cmd_scu.result_len = 1;
  5810. cmd_scu.parameter = NULL;
  5811. cmd_scu.result = &cmd_result;
  5812. rc = scu_command(dev_addr, &cmd_scu);
  5813. if (rc != 0) {
  5814. pr_err("error %d\n", rc);
  5815. goto rw_error;
  5816. }
  5817. if (primary) {
  5818. rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
  5819. if (rc != 0) {
  5820. pr_err("error %d\n", rc);
  5821. goto rw_error;
  5822. }
  5823. rc = set_iqm_af(demod, false);
  5824. if (rc != 0) {
  5825. pr_err("error %d\n", rc);
  5826. goto rw_error;
  5827. }
  5828. } else {
  5829. rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
  5830. if (rc != 0) {
  5831. pr_err("error %d\n", rc);
  5832. goto rw_error;
  5833. }
  5834. rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
  5835. if (rc != 0) {
  5836. pr_err("error %d\n", rc);
  5837. goto rw_error;
  5838. }
  5839. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
  5840. if (rc != 0) {
  5841. pr_err("error %d\n", rc);
  5842. goto rw_error;
  5843. }
  5844. rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
  5845. if (rc != 0) {
  5846. pr_err("error %d\n", rc);
  5847. goto rw_error;
  5848. }
  5849. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
  5850. if (rc != 0) {
  5851. pr_err("error %d\n", rc);
  5852. goto rw_error;
  5853. }
  5854. }
  5855. memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
  5856. cfg_mpeg_output.enable_mpeg_output = false;
  5857. rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
  5858. if (rc != 0) {
  5859. pr_err("error %d\n", rc);
  5860. goto rw_error;
  5861. }
  5862. return 0;
  5863. rw_error:
  5864. return rc;
  5865. }
  5866. /*============================================================================*/
  5867. /**
  5868. * \fn int set_qam_measurement ()
  5869. * \brief Setup of the QAM Measuremnt intervals for signal quality
  5870. * \param demod instance of demod.
  5871. * \param constellation current constellation.
  5872. * \return int.
  5873. *
  5874. * NOTE:
  5875. * Take into account that for certain settings the errorcounters can overflow.
  5876. * The implementation does not check this.
  5877. *
  5878. * TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
  5879. * constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
  5880. * field ?
  5881. *
  5882. */
  5883. #ifndef DRXJ_VSB_ONLY
  5884. static int
  5885. set_qam_measurement(struct drx_demod_instance *demod,
  5886. enum drx_modulation constellation, u32 symbol_rate)
  5887. {
  5888. struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
  5889. struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specific data */
  5890. int rc;
  5891. u32 fec_bits_desired = 0; /* BER accounting period */
  5892. u16 fec_rs_plen = 0; /* defines RS BER measurement period */
  5893. u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
  5894. u32 fec_rs_period = 0; /* Value for corresponding I2C register */
  5895. u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
  5896. u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
  5897. u32 qam_vd_period = 0; /* Value for corresponding I2C register */
  5898. u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
  5899. u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
  5900. u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
  5901. dev_addr = demod->my_i2c_dev_addr;
  5902. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  5903. fec_bits_desired = ext_attr->fec_bits_desired;
  5904. fec_rs_prescale = ext_attr->fec_rs_prescale;
  5905. switch (constellation) {
  5906. case DRX_CONSTELLATION_QAM16:
  5907. fec_bits_desired = 4 * symbol_rate;
  5908. break;
  5909. case DRX_CONSTELLATION_QAM32:
  5910. fec_bits_desired = 5 * symbol_rate;
  5911. break;
  5912. case DRX_CONSTELLATION_QAM64:
  5913. fec_bits_desired = 6 * symbol_rate;
  5914. break;
  5915. case DRX_CONSTELLATION_QAM128:
  5916. fec_bits_desired = 7 * symbol_rate;
  5917. break;
  5918. case DRX_CONSTELLATION_QAM256:
  5919. fec_bits_desired = 8 * symbol_rate;
  5920. break;
  5921. default:
  5922. return -EINVAL;
  5923. }
  5924. /* Parameters for Reed-Solomon Decoder */
  5925. /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
  5926. /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
  5927. /* result is within 32 bit arithmetic -> */
  5928. /* no need for mult or frac functions */
  5929. /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
  5930. switch (ext_attr->standard) {
  5931. case DRX_STANDARD_ITU_A:
  5932. case DRX_STANDARD_ITU_C:
  5933. fec_rs_plen = 204 * 8;
  5934. break;
  5935. case DRX_STANDARD_ITU_B:
  5936. fec_rs_plen = 128 * 7;
  5937. break;
  5938. default:
  5939. return -EINVAL;
  5940. }
  5941. ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
  5942. fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
  5943. if (fec_rs_bit_cnt == 0) {
  5944. pr_err("error: fec_rs_bit_cnt is zero!\n");
  5945. return -EIO;
  5946. }
  5947. fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
  5948. if (ext_attr->standard != DRX_STANDARD_ITU_B)
  5949. fec_oc_snc_fail_period = fec_rs_period;
  5950. /* limit to max 16 bit value (I2C register width) if needed */
  5951. if (fec_rs_period > 0xFFFF)
  5952. fec_rs_period = 0xFFFF;
  5953. /* write corresponding registers */
  5954. switch (ext_attr->standard) {
  5955. case DRX_STANDARD_ITU_A:
  5956. case DRX_STANDARD_ITU_C:
  5957. break;
  5958. case DRX_STANDARD_ITU_B:
  5959. switch (constellation) {
  5960. case DRX_CONSTELLATION_QAM64:
  5961. fec_rs_period = 31581;
  5962. fec_oc_snc_fail_period = 17932;
  5963. break;
  5964. case DRX_CONSTELLATION_QAM256:
  5965. fec_rs_period = 45446;
  5966. fec_oc_snc_fail_period = 25805;
  5967. break;
  5968. default:
  5969. return -EINVAL;
  5970. }
  5971. break;
  5972. default:
  5973. return -EINVAL;
  5974. }
  5975. rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
  5976. if (rc != 0) {
  5977. pr_err("error %d\n", rc);
  5978. goto rw_error;
  5979. }
  5980. rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
  5981. if (rc != 0) {
  5982. pr_err("error %d\n", rc);
  5983. goto rw_error;
  5984. }
  5985. rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
  5986. if (rc != 0) {
  5987. pr_err("error %d\n", rc);
  5988. goto rw_error;
  5989. }
  5990. ext_attr->fec_rs_period = (u16) fec_rs_period;
  5991. ext_attr->fec_rs_prescale = fec_rs_prescale;
  5992. rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
  5993. if (rc != 0) {
  5994. pr_err("error %d\n", rc);
  5995. goto rw_error;
  5996. }
  5997. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
  5998. if (rc != 0) {
  5999. pr_err("error %d\n", rc);
  6000. goto rw_error;
  6001. }
  6002. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
  6003. if (rc != 0) {
  6004. pr_err("error %d\n", rc);
  6005. goto rw_error;
  6006. }
  6007. if (ext_attr->standard == DRX_STANDARD_ITU_B) {
  6008. /* Parameters for Viterbi Decoder */
  6009. /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
  6010. /* (qamvd_prescale*plen*(qam_constellation+1))) */
  6011. /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
  6012. /* result is within 32 bit arithmetic -> */
  6013. /* no need for mult or frac functions */
  6014. /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
  6015. fec_vd_plen = ext_attr->fec_vd_plen;
  6016. qam_vd_prescale = ext_attr->qam_vd_prescale;
  6017. qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
  6018. switch (constellation) {
  6019. case DRX_CONSTELLATION_QAM64:
  6020. /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
  6021. qam_vd_period =
  6022. qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
  6023. * (QAM_TOP_CONSTELLATION_QAM64 + 1);
  6024. break;
  6025. case DRX_CONSTELLATION_QAM256:
  6026. /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
  6027. qam_vd_period =
  6028. qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
  6029. * (QAM_TOP_CONSTELLATION_QAM256 + 1);
  6030. break;
  6031. default:
  6032. return -EINVAL;
  6033. }
  6034. if (qam_vd_period == 0) {
  6035. pr_err("error: qam_vd_period is zero!\n");
  6036. return -EIO;
  6037. }
  6038. qam_vd_period = fec_bits_desired / qam_vd_period;
  6039. /* limit to max 16 bit value (I2C register width) if needed */
  6040. if (qam_vd_period > 0xFFFF)
  6041. qam_vd_period = 0xFFFF;
  6042. /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
  6043. qam_vd_bit_cnt *= qam_vd_period;
  6044. rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
  6045. if (rc != 0) {
  6046. pr_err("error %d\n", rc);
  6047. goto rw_error;
  6048. }
  6049. rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
  6050. if (rc != 0) {
  6051. pr_err("error %d\n", rc);
  6052. goto rw_error;
  6053. }
  6054. ext_attr->qam_vd_period = (u16) qam_vd_period;
  6055. ext_attr->qam_vd_prescale = qam_vd_prescale;
  6056. }
  6057. return 0;
  6058. rw_error:
  6059. return rc;
  6060. }
  6061. /*============================================================================*/
  6062. /**
  6063. * \fn int set_qam16 ()
  6064. * \brief QAM16 specific setup
  6065. * \param demod instance of demod.
  6066. * \return int.
  6067. */
  6068. static int set_qam16(struct drx_demod_instance *demod)
  6069. {
  6070. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  6071. int rc;
  6072. const u8 qam_dq_qual_fun[] = {
  6073. DRXJ_16TO8(2), /* fun0 */
  6074. DRXJ_16TO8(2), /* fun1 */
  6075. DRXJ_16TO8(2), /* fun2 */
  6076. DRXJ_16TO8(2), /* fun3 */
  6077. DRXJ_16TO8(3), /* fun4 */
  6078. DRXJ_16TO8(3), /* fun5 */
  6079. };
  6080. const u8 qam_eq_cma_rad[] = {
  6081. DRXJ_16TO8(13517), /* RAD0 */
  6082. DRXJ_16TO8(13517), /* RAD1 */
  6083. DRXJ_16TO8(13517), /* RAD2 */
  6084. DRXJ_16TO8(13517), /* RAD3 */
  6085. DRXJ_16TO8(13517), /* RAD4 */
  6086. DRXJ_16TO8(13517), /* RAD5 */
  6087. };
  6088. rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
  6089. if (rc != 0) {
  6090. pr_err("error %d\n", rc);
  6091. goto rw_error;
  6092. }
  6093. rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
  6094. if (rc != 0) {
  6095. pr_err("error %d\n", rc);
  6096. goto rw_error;
  6097. }
  6098. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
  6099. if (rc != 0) {
  6100. pr_err("error %d\n", rc);
  6101. goto rw_error;
  6102. }
  6103. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
  6104. if (rc != 0) {
  6105. pr_err("error %d\n", rc);
  6106. goto rw_error;
  6107. }
  6108. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
  6109. if (rc != 0) {
  6110. pr_err("error %d\n", rc);
  6111. goto rw_error;
  6112. }
  6113. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
  6114. if (rc != 0) {
  6115. pr_err("error %d\n", rc);
  6116. goto rw_error;
  6117. }
  6118. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
  6119. if (rc != 0) {
  6120. pr_err("error %d\n", rc);
  6121. goto rw_error;
  6122. }
  6123. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
  6124. if (rc != 0) {
  6125. pr_err("error %d\n", rc);
  6126. goto rw_error;
  6127. }
  6128. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
  6129. if (rc != 0) {
  6130. pr_err("error %d\n", rc);
  6131. goto rw_error;
  6132. }
  6133. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
  6134. if (rc != 0) {
  6135. pr_err("error %d\n", rc);
  6136. goto rw_error;
  6137. }
  6138. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
  6139. if (rc != 0) {
  6140. pr_err("error %d\n", rc);
  6141. goto rw_error;
  6142. }
  6143. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
  6144. if (rc != 0) {
  6145. pr_err("error %d\n", rc);
  6146. goto rw_error;
  6147. }
  6148. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
  6149. if (rc != 0) {
  6150. pr_err("error %d\n", rc);
  6151. goto rw_error;
  6152. }
  6153. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
  6154. if (rc != 0) {
  6155. pr_err("error %d\n", rc);
  6156. goto rw_error;
  6157. }
  6158. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
  6159. if (rc != 0) {
  6160. pr_err("error %d\n", rc);
  6161. goto rw_error;
  6162. }
  6163. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
  6164. if (rc != 0) {
  6165. pr_err("error %d\n", rc);
  6166. goto rw_error;
  6167. }
  6168. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
  6169. if (rc != 0) {
  6170. pr_err("error %d\n", rc);
  6171. goto rw_error;
  6172. }
  6173. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
  6174. if (rc != 0) {
  6175. pr_err("error %d\n", rc);
  6176. goto rw_error;
  6177. }
  6178. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
  6179. if (rc != 0) {
  6180. pr_err("error %d\n", rc);
  6181. goto rw_error;
  6182. }
  6183. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
  6184. if (rc != 0) {
  6185. pr_err("error %d\n", rc);
  6186. goto rw_error;
  6187. }
  6188. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
  6189. if (rc != 0) {
  6190. pr_err("error %d\n", rc);
  6191. goto rw_error;
  6192. }
  6193. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
  6194. if (rc != 0) {
  6195. pr_err("error %d\n", rc);
  6196. goto rw_error;
  6197. }
  6198. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
  6199. if (rc != 0) {
  6200. pr_err("error %d\n", rc);
  6201. goto rw_error;
  6202. }
  6203. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
  6204. if (rc != 0) {
  6205. pr_err("error %d\n", rc);
  6206. goto rw_error;
  6207. }
  6208. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
  6209. if (rc != 0) {
  6210. pr_err("error %d\n", rc);
  6211. goto rw_error;
  6212. }
  6213. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
  6214. if (rc != 0) {
  6215. pr_err("error %d\n", rc);
  6216. goto rw_error;
  6217. }
  6218. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
  6219. if (rc != 0) {
  6220. pr_err("error %d\n", rc);
  6221. goto rw_error;
  6222. }
  6223. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
  6224. if (rc != 0) {
  6225. pr_err("error %d\n", rc);
  6226. goto rw_error;
  6227. }
  6228. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
  6229. if (rc != 0) {
  6230. pr_err("error %d\n", rc);
  6231. goto rw_error;
  6232. }
  6233. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
  6234. if (rc != 0) {
  6235. pr_err("error %d\n", rc);
  6236. goto rw_error;
  6237. }
  6238. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
  6239. if (rc != 0) {
  6240. pr_err("error %d\n", rc);
  6241. goto rw_error;
  6242. }
  6243. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
  6244. if (rc != 0) {
  6245. pr_err("error %d\n", rc);
  6246. goto rw_error;
  6247. }
  6248. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
  6249. if (rc != 0) {
  6250. pr_err("error %d\n", rc);
  6251. goto rw_error;
  6252. }
  6253. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
  6254. if (rc != 0) {
  6255. pr_err("error %d\n", rc);
  6256. goto rw_error;
  6257. }
  6258. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
  6259. if (rc != 0) {
  6260. pr_err("error %d\n", rc);
  6261. goto rw_error;
  6262. }
  6263. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
  6264. if (rc != 0) {
  6265. pr_err("error %d\n", rc);
  6266. goto rw_error;
  6267. }
  6268. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
  6269. if (rc != 0) {
  6270. pr_err("error %d\n", rc);
  6271. goto rw_error;
  6272. }
  6273. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
  6274. if (rc != 0) {
  6275. pr_err("error %d\n", rc);
  6276. goto rw_error;
  6277. }
  6278. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
  6279. if (rc != 0) {
  6280. pr_err("error %d\n", rc);
  6281. goto rw_error;
  6282. }
  6283. return 0;
  6284. rw_error:
  6285. return rc;
  6286. }
  6287. /*============================================================================*/
  6288. /**
  6289. * \fn int set_qam32 ()
  6290. * \brief QAM32 specific setup
  6291. * \param demod instance of demod.
  6292. * \return int.
  6293. */
  6294. static int set_qam32(struct drx_demod_instance *demod)
  6295. {
  6296. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  6297. int rc;
  6298. const u8 qam_dq_qual_fun[] = {
  6299. DRXJ_16TO8(3), /* fun0 */
  6300. DRXJ_16TO8(3), /* fun1 */
  6301. DRXJ_16TO8(3), /* fun2 */
  6302. DRXJ_16TO8(3), /* fun3 */
  6303. DRXJ_16TO8(4), /* fun4 */
  6304. DRXJ_16TO8(4), /* fun5 */
  6305. };
  6306. const u8 qam_eq_cma_rad[] = {
  6307. DRXJ_16TO8(6707), /* RAD0 */
  6308. DRXJ_16TO8(6707), /* RAD1 */
  6309. DRXJ_16TO8(6707), /* RAD2 */
  6310. DRXJ_16TO8(6707), /* RAD3 */
  6311. DRXJ_16TO8(6707), /* RAD4 */
  6312. DRXJ_16TO8(6707), /* RAD5 */
  6313. };
  6314. rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
  6315. if (rc != 0) {
  6316. pr_err("error %d\n", rc);
  6317. goto rw_error;
  6318. }
  6319. rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
  6320. if (rc != 0) {
  6321. pr_err("error %d\n", rc);
  6322. goto rw_error;
  6323. }
  6324. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
  6325. if (rc != 0) {
  6326. pr_err("error %d\n", rc);
  6327. goto rw_error;
  6328. }
  6329. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
  6330. if (rc != 0) {
  6331. pr_err("error %d\n", rc);
  6332. goto rw_error;
  6333. }
  6334. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
  6335. if (rc != 0) {
  6336. pr_err("error %d\n", rc);
  6337. goto rw_error;
  6338. }
  6339. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
  6340. if (rc != 0) {
  6341. pr_err("error %d\n", rc);
  6342. goto rw_error;
  6343. }
  6344. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
  6345. if (rc != 0) {
  6346. pr_err("error %d\n", rc);
  6347. goto rw_error;
  6348. }
  6349. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
  6350. if (rc != 0) {
  6351. pr_err("error %d\n", rc);
  6352. goto rw_error;
  6353. }
  6354. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
  6355. if (rc != 0) {
  6356. pr_err("error %d\n", rc);
  6357. goto rw_error;
  6358. }
  6359. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
  6360. if (rc != 0) {
  6361. pr_err("error %d\n", rc);
  6362. goto rw_error;
  6363. }
  6364. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
  6365. if (rc != 0) {
  6366. pr_err("error %d\n", rc);
  6367. goto rw_error;
  6368. }
  6369. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
  6370. if (rc != 0) {
  6371. pr_err("error %d\n", rc);
  6372. goto rw_error;
  6373. }
  6374. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
  6375. if (rc != 0) {
  6376. pr_err("error %d\n", rc);
  6377. goto rw_error;
  6378. }
  6379. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
  6380. if (rc != 0) {
  6381. pr_err("error %d\n", rc);
  6382. goto rw_error;
  6383. }
  6384. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
  6385. if (rc != 0) {
  6386. pr_err("error %d\n", rc);
  6387. goto rw_error;
  6388. }
  6389. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
  6390. if (rc != 0) {
  6391. pr_err("error %d\n", rc);
  6392. goto rw_error;
  6393. }
  6394. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
  6395. if (rc != 0) {
  6396. pr_err("error %d\n", rc);
  6397. goto rw_error;
  6398. }
  6399. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
  6400. if (rc != 0) {
  6401. pr_err("error %d\n", rc);
  6402. goto rw_error;
  6403. }
  6404. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
  6405. if (rc != 0) {
  6406. pr_err("error %d\n", rc);
  6407. goto rw_error;
  6408. }
  6409. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
  6410. if (rc != 0) {
  6411. pr_err("error %d\n", rc);
  6412. goto rw_error;
  6413. }
  6414. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
  6415. if (rc != 0) {
  6416. pr_err("error %d\n", rc);
  6417. goto rw_error;
  6418. }
  6419. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
  6420. if (rc != 0) {
  6421. pr_err("error %d\n", rc);
  6422. goto rw_error;
  6423. }
  6424. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
  6425. if (rc != 0) {
  6426. pr_err("error %d\n", rc);
  6427. goto rw_error;
  6428. }
  6429. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
  6430. if (rc != 0) {
  6431. pr_err("error %d\n", rc);
  6432. goto rw_error;
  6433. }
  6434. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
  6435. if (rc != 0) {
  6436. pr_err("error %d\n", rc);
  6437. goto rw_error;
  6438. }
  6439. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
  6440. if (rc != 0) {
  6441. pr_err("error %d\n", rc);
  6442. goto rw_error;
  6443. }
  6444. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
  6445. if (rc != 0) {
  6446. pr_err("error %d\n", rc);
  6447. goto rw_error;
  6448. }
  6449. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
  6450. if (rc != 0) {
  6451. pr_err("error %d\n", rc);
  6452. goto rw_error;
  6453. }
  6454. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
  6455. if (rc != 0) {
  6456. pr_err("error %d\n", rc);
  6457. goto rw_error;
  6458. }
  6459. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
  6460. if (rc != 0) {
  6461. pr_err("error %d\n", rc);
  6462. goto rw_error;
  6463. }
  6464. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
  6465. if (rc != 0) {
  6466. pr_err("error %d\n", rc);
  6467. goto rw_error;
  6468. }
  6469. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
  6470. if (rc != 0) {
  6471. pr_err("error %d\n", rc);
  6472. goto rw_error;
  6473. }
  6474. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
  6475. if (rc != 0) {
  6476. pr_err("error %d\n", rc);
  6477. goto rw_error;
  6478. }
  6479. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
  6480. if (rc != 0) {
  6481. pr_err("error %d\n", rc);
  6482. goto rw_error;
  6483. }
  6484. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
  6485. if (rc != 0) {
  6486. pr_err("error %d\n", rc);
  6487. goto rw_error;
  6488. }
  6489. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
  6490. if (rc != 0) {
  6491. pr_err("error %d\n", rc);
  6492. goto rw_error;
  6493. }
  6494. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
  6495. if (rc != 0) {
  6496. pr_err("error %d\n", rc);
  6497. goto rw_error;
  6498. }
  6499. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
  6500. if (rc != 0) {
  6501. pr_err("error %d\n", rc);
  6502. goto rw_error;
  6503. }
  6504. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
  6505. if (rc != 0) {
  6506. pr_err("error %d\n", rc);
  6507. goto rw_error;
  6508. }
  6509. return 0;
  6510. rw_error:
  6511. return rc;
  6512. }
  6513. /*============================================================================*/
  6514. /**
  6515. * \fn int set_qam64 ()
  6516. * \brief QAM64 specific setup
  6517. * \param demod instance of demod.
  6518. * \return int.
  6519. */
  6520. static int set_qam64(struct drx_demod_instance *demod)
  6521. {
  6522. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  6523. int rc;
  6524. const u8 qam_dq_qual_fun[] = { /* this is hw reset value. no necessary to re-write */
  6525. DRXJ_16TO8(4), /* fun0 */
  6526. DRXJ_16TO8(4), /* fun1 */
  6527. DRXJ_16TO8(4), /* fun2 */
  6528. DRXJ_16TO8(4), /* fun3 */
  6529. DRXJ_16TO8(6), /* fun4 */
  6530. DRXJ_16TO8(6), /* fun5 */
  6531. };
  6532. const u8 qam_eq_cma_rad[] = {
  6533. DRXJ_16TO8(13336), /* RAD0 */
  6534. DRXJ_16TO8(12618), /* RAD1 */
  6535. DRXJ_16TO8(11988), /* RAD2 */
  6536. DRXJ_16TO8(13809), /* RAD3 */
  6537. DRXJ_16TO8(13809), /* RAD4 */
  6538. DRXJ_16TO8(15609), /* RAD5 */
  6539. };
  6540. rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
  6541. if (rc != 0) {
  6542. pr_err("error %d\n", rc);
  6543. goto rw_error;
  6544. }
  6545. rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
  6546. if (rc != 0) {
  6547. pr_err("error %d\n", rc);
  6548. goto rw_error;
  6549. }
  6550. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
  6551. if (rc != 0) {
  6552. pr_err("error %d\n", rc);
  6553. goto rw_error;
  6554. }
  6555. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
  6556. if (rc != 0) {
  6557. pr_err("error %d\n", rc);
  6558. goto rw_error;
  6559. }
  6560. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
  6561. if (rc != 0) {
  6562. pr_err("error %d\n", rc);
  6563. goto rw_error;
  6564. }
  6565. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
  6566. if (rc != 0) {
  6567. pr_err("error %d\n", rc);
  6568. goto rw_error;
  6569. }
  6570. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
  6571. if (rc != 0) {
  6572. pr_err("error %d\n", rc);
  6573. goto rw_error;
  6574. }
  6575. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
  6576. if (rc != 0) {
  6577. pr_err("error %d\n", rc);
  6578. goto rw_error;
  6579. }
  6580. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
  6581. if (rc != 0) {
  6582. pr_err("error %d\n", rc);
  6583. goto rw_error;
  6584. }
  6585. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
  6586. if (rc != 0) {
  6587. pr_err("error %d\n", rc);
  6588. goto rw_error;
  6589. }
  6590. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
  6591. if (rc != 0) {
  6592. pr_err("error %d\n", rc);
  6593. goto rw_error;
  6594. }
  6595. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
  6596. if (rc != 0) {
  6597. pr_err("error %d\n", rc);
  6598. goto rw_error;
  6599. }
  6600. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
  6601. if (rc != 0) {
  6602. pr_err("error %d\n", rc);
  6603. goto rw_error;
  6604. }
  6605. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
  6606. if (rc != 0) {
  6607. pr_err("error %d\n", rc);
  6608. goto rw_error;
  6609. }
  6610. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
  6611. if (rc != 0) {
  6612. pr_err("error %d\n", rc);
  6613. goto rw_error;
  6614. }
  6615. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
  6616. if (rc != 0) {
  6617. pr_err("error %d\n", rc);
  6618. goto rw_error;
  6619. }
  6620. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
  6621. if (rc != 0) {
  6622. pr_err("error %d\n", rc);
  6623. goto rw_error;
  6624. }
  6625. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
  6626. if (rc != 0) {
  6627. pr_err("error %d\n", rc);
  6628. goto rw_error;
  6629. }
  6630. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
  6631. if (rc != 0) {
  6632. pr_err("error %d\n", rc);
  6633. goto rw_error;
  6634. }
  6635. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
  6636. if (rc != 0) {
  6637. pr_err("error %d\n", rc);
  6638. goto rw_error;
  6639. }
  6640. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
  6641. if (rc != 0) {
  6642. pr_err("error %d\n", rc);
  6643. goto rw_error;
  6644. }
  6645. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
  6646. if (rc != 0) {
  6647. pr_err("error %d\n", rc);
  6648. goto rw_error;
  6649. }
  6650. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
  6651. if (rc != 0) {
  6652. pr_err("error %d\n", rc);
  6653. goto rw_error;
  6654. }
  6655. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
  6656. if (rc != 0) {
  6657. pr_err("error %d\n", rc);
  6658. goto rw_error;
  6659. }
  6660. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
  6661. if (rc != 0) {
  6662. pr_err("error %d\n", rc);
  6663. goto rw_error;
  6664. }
  6665. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
  6666. if (rc != 0) {
  6667. pr_err("error %d\n", rc);
  6668. goto rw_error;
  6669. }
  6670. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
  6671. if (rc != 0) {
  6672. pr_err("error %d\n", rc);
  6673. goto rw_error;
  6674. }
  6675. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
  6676. if (rc != 0) {
  6677. pr_err("error %d\n", rc);
  6678. goto rw_error;
  6679. }
  6680. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
  6681. if (rc != 0) {
  6682. pr_err("error %d\n", rc);
  6683. goto rw_error;
  6684. }
  6685. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
  6686. if (rc != 0) {
  6687. pr_err("error %d\n", rc);
  6688. goto rw_error;
  6689. }
  6690. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
  6691. if (rc != 0) {
  6692. pr_err("error %d\n", rc);
  6693. goto rw_error;
  6694. }
  6695. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
  6696. if (rc != 0) {
  6697. pr_err("error %d\n", rc);
  6698. goto rw_error;
  6699. }
  6700. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
  6701. if (rc != 0) {
  6702. pr_err("error %d\n", rc);
  6703. goto rw_error;
  6704. }
  6705. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
  6706. if (rc != 0) {
  6707. pr_err("error %d\n", rc);
  6708. goto rw_error;
  6709. }
  6710. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
  6711. if (rc != 0) {
  6712. pr_err("error %d\n", rc);
  6713. goto rw_error;
  6714. }
  6715. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
  6716. if (rc != 0) {
  6717. pr_err("error %d\n", rc);
  6718. goto rw_error;
  6719. }
  6720. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
  6721. if (rc != 0) {
  6722. pr_err("error %d\n", rc);
  6723. goto rw_error;
  6724. }
  6725. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
  6726. if (rc != 0) {
  6727. pr_err("error %d\n", rc);
  6728. goto rw_error;
  6729. }
  6730. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
  6731. if (rc != 0) {
  6732. pr_err("error %d\n", rc);
  6733. goto rw_error;
  6734. }
  6735. return 0;
  6736. rw_error:
  6737. return rc;
  6738. }
  6739. /*============================================================================*/
  6740. /**
  6741. * \fn int set_qam128 ()
  6742. * \brief QAM128 specific setup
  6743. * \param demod: instance of demod.
  6744. * \return int.
  6745. */
  6746. static int set_qam128(struct drx_demod_instance *demod)
  6747. {
  6748. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  6749. int rc;
  6750. const u8 qam_dq_qual_fun[] = {
  6751. DRXJ_16TO8(6), /* fun0 */
  6752. DRXJ_16TO8(6), /* fun1 */
  6753. DRXJ_16TO8(6), /* fun2 */
  6754. DRXJ_16TO8(6), /* fun3 */
  6755. DRXJ_16TO8(9), /* fun4 */
  6756. DRXJ_16TO8(9), /* fun5 */
  6757. };
  6758. const u8 qam_eq_cma_rad[] = {
  6759. DRXJ_16TO8(6164), /* RAD0 */
  6760. DRXJ_16TO8(6598), /* RAD1 */
  6761. DRXJ_16TO8(6394), /* RAD2 */
  6762. DRXJ_16TO8(6409), /* RAD3 */
  6763. DRXJ_16TO8(6656), /* RAD4 */
  6764. DRXJ_16TO8(7238), /* RAD5 */
  6765. };
  6766. rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
  6767. if (rc != 0) {
  6768. pr_err("error %d\n", rc);
  6769. goto rw_error;
  6770. }
  6771. rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
  6772. if (rc != 0) {
  6773. pr_err("error %d\n", rc);
  6774. goto rw_error;
  6775. }
  6776. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
  6777. if (rc != 0) {
  6778. pr_err("error %d\n", rc);
  6779. goto rw_error;
  6780. }
  6781. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
  6782. if (rc != 0) {
  6783. pr_err("error %d\n", rc);
  6784. goto rw_error;
  6785. }
  6786. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
  6787. if (rc != 0) {
  6788. pr_err("error %d\n", rc);
  6789. goto rw_error;
  6790. }
  6791. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
  6792. if (rc != 0) {
  6793. pr_err("error %d\n", rc);
  6794. goto rw_error;
  6795. }
  6796. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
  6797. if (rc != 0) {
  6798. pr_err("error %d\n", rc);
  6799. goto rw_error;
  6800. }
  6801. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
  6802. if (rc != 0) {
  6803. pr_err("error %d\n", rc);
  6804. goto rw_error;
  6805. }
  6806. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
  6807. if (rc != 0) {
  6808. pr_err("error %d\n", rc);
  6809. goto rw_error;
  6810. }
  6811. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
  6812. if (rc != 0) {
  6813. pr_err("error %d\n", rc);
  6814. goto rw_error;
  6815. }
  6816. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
  6817. if (rc != 0) {
  6818. pr_err("error %d\n", rc);
  6819. goto rw_error;
  6820. }
  6821. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
  6822. if (rc != 0) {
  6823. pr_err("error %d\n", rc);
  6824. goto rw_error;
  6825. }
  6826. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
  6827. if (rc != 0) {
  6828. pr_err("error %d\n", rc);
  6829. goto rw_error;
  6830. }
  6831. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
  6832. if (rc != 0) {
  6833. pr_err("error %d\n", rc);
  6834. goto rw_error;
  6835. }
  6836. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
  6837. if (rc != 0) {
  6838. pr_err("error %d\n", rc);
  6839. goto rw_error;
  6840. }
  6841. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
  6842. if (rc != 0) {
  6843. pr_err("error %d\n", rc);
  6844. goto rw_error;
  6845. }
  6846. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
  6847. if (rc != 0) {
  6848. pr_err("error %d\n", rc);
  6849. goto rw_error;
  6850. }
  6851. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
  6852. if (rc != 0) {
  6853. pr_err("error %d\n", rc);
  6854. goto rw_error;
  6855. }
  6856. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
  6857. if (rc != 0) {
  6858. pr_err("error %d\n", rc);
  6859. goto rw_error;
  6860. }
  6861. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
  6862. if (rc != 0) {
  6863. pr_err("error %d\n", rc);
  6864. goto rw_error;
  6865. }
  6866. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
  6867. if (rc != 0) {
  6868. pr_err("error %d\n", rc);
  6869. goto rw_error;
  6870. }
  6871. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
  6872. if (rc != 0) {
  6873. pr_err("error %d\n", rc);
  6874. goto rw_error;
  6875. }
  6876. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
  6877. if (rc != 0) {
  6878. pr_err("error %d\n", rc);
  6879. goto rw_error;
  6880. }
  6881. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
  6882. if (rc != 0) {
  6883. pr_err("error %d\n", rc);
  6884. goto rw_error;
  6885. }
  6886. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
  6887. if (rc != 0) {
  6888. pr_err("error %d\n", rc);
  6889. goto rw_error;
  6890. }
  6891. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
  6892. if (rc != 0) {
  6893. pr_err("error %d\n", rc);
  6894. goto rw_error;
  6895. }
  6896. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
  6897. if (rc != 0) {
  6898. pr_err("error %d\n", rc);
  6899. goto rw_error;
  6900. }
  6901. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
  6902. if (rc != 0) {
  6903. pr_err("error %d\n", rc);
  6904. goto rw_error;
  6905. }
  6906. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
  6907. if (rc != 0) {
  6908. pr_err("error %d\n", rc);
  6909. goto rw_error;
  6910. }
  6911. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
  6912. if (rc != 0) {
  6913. pr_err("error %d\n", rc);
  6914. goto rw_error;
  6915. }
  6916. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
  6917. if (rc != 0) {
  6918. pr_err("error %d\n", rc);
  6919. goto rw_error;
  6920. }
  6921. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
  6922. if (rc != 0) {
  6923. pr_err("error %d\n", rc);
  6924. goto rw_error;
  6925. }
  6926. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
  6927. if (rc != 0) {
  6928. pr_err("error %d\n", rc);
  6929. goto rw_error;
  6930. }
  6931. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
  6932. if (rc != 0) {
  6933. pr_err("error %d\n", rc);
  6934. goto rw_error;
  6935. }
  6936. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
  6937. if (rc != 0) {
  6938. pr_err("error %d\n", rc);
  6939. goto rw_error;
  6940. }
  6941. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
  6942. if (rc != 0) {
  6943. pr_err("error %d\n", rc);
  6944. goto rw_error;
  6945. }
  6946. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
  6947. if (rc != 0) {
  6948. pr_err("error %d\n", rc);
  6949. goto rw_error;
  6950. }
  6951. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
  6952. if (rc != 0) {
  6953. pr_err("error %d\n", rc);
  6954. goto rw_error;
  6955. }
  6956. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
  6957. if (rc != 0) {
  6958. pr_err("error %d\n", rc);
  6959. goto rw_error;
  6960. }
  6961. return 0;
  6962. rw_error:
  6963. return rc;
  6964. }
  6965. /*============================================================================*/
  6966. /**
  6967. * \fn int set_qam256 ()
  6968. * \brief QAM256 specific setup
  6969. * \param demod: instance of demod.
  6970. * \return int.
  6971. */
  6972. static int set_qam256(struct drx_demod_instance *demod)
  6973. {
  6974. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  6975. int rc;
  6976. const u8 qam_dq_qual_fun[] = {
  6977. DRXJ_16TO8(8), /* fun0 */
  6978. DRXJ_16TO8(8), /* fun1 */
  6979. DRXJ_16TO8(8), /* fun2 */
  6980. DRXJ_16TO8(8), /* fun3 */
  6981. DRXJ_16TO8(12), /* fun4 */
  6982. DRXJ_16TO8(12), /* fun5 */
  6983. };
  6984. const u8 qam_eq_cma_rad[] = {
  6985. DRXJ_16TO8(12345), /* RAD0 */
  6986. DRXJ_16TO8(12345), /* RAD1 */
  6987. DRXJ_16TO8(13626), /* RAD2 */
  6988. DRXJ_16TO8(12931), /* RAD3 */
  6989. DRXJ_16TO8(14719), /* RAD4 */
  6990. DRXJ_16TO8(15356), /* RAD5 */
  6991. };
  6992. rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
  6993. if (rc != 0) {
  6994. pr_err("error %d\n", rc);
  6995. goto rw_error;
  6996. }
  6997. rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
  6998. if (rc != 0) {
  6999. pr_err("error %d\n", rc);
  7000. goto rw_error;
  7001. }
  7002. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
  7003. if (rc != 0) {
  7004. pr_err("error %d\n", rc);
  7005. goto rw_error;
  7006. }
  7007. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
  7008. if (rc != 0) {
  7009. pr_err("error %d\n", rc);
  7010. goto rw_error;
  7011. }
  7012. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
  7013. if (rc != 0) {
  7014. pr_err("error %d\n", rc);
  7015. goto rw_error;
  7016. }
  7017. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
  7018. if (rc != 0) {
  7019. pr_err("error %d\n", rc);
  7020. goto rw_error;
  7021. }
  7022. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
  7023. if (rc != 0) {
  7024. pr_err("error %d\n", rc);
  7025. goto rw_error;
  7026. }
  7027. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
  7028. if (rc != 0) {
  7029. pr_err("error %d\n", rc);
  7030. goto rw_error;
  7031. }
  7032. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
  7033. if (rc != 0) {
  7034. pr_err("error %d\n", rc);
  7035. goto rw_error;
  7036. }
  7037. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
  7038. if (rc != 0) {
  7039. pr_err("error %d\n", rc);
  7040. goto rw_error;
  7041. }
  7042. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
  7043. if (rc != 0) {
  7044. pr_err("error %d\n", rc);
  7045. goto rw_error;
  7046. }
  7047. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
  7048. if (rc != 0) {
  7049. pr_err("error %d\n", rc);
  7050. goto rw_error;
  7051. }
  7052. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
  7053. if (rc != 0) {
  7054. pr_err("error %d\n", rc);
  7055. goto rw_error;
  7056. }
  7057. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
  7058. if (rc != 0) {
  7059. pr_err("error %d\n", rc);
  7060. goto rw_error;
  7061. }
  7062. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
  7063. if (rc != 0) {
  7064. pr_err("error %d\n", rc);
  7065. goto rw_error;
  7066. }
  7067. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
  7068. if (rc != 0) {
  7069. pr_err("error %d\n", rc);
  7070. goto rw_error;
  7071. }
  7072. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
  7073. if (rc != 0) {
  7074. pr_err("error %d\n", rc);
  7075. goto rw_error;
  7076. }
  7077. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
  7078. if (rc != 0) {
  7079. pr_err("error %d\n", rc);
  7080. goto rw_error;
  7081. }
  7082. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
  7083. if (rc != 0) {
  7084. pr_err("error %d\n", rc);
  7085. goto rw_error;
  7086. }
  7087. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
  7088. if (rc != 0) {
  7089. pr_err("error %d\n", rc);
  7090. goto rw_error;
  7091. }
  7092. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
  7093. if (rc != 0) {
  7094. pr_err("error %d\n", rc);
  7095. goto rw_error;
  7096. }
  7097. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
  7098. if (rc != 0) {
  7099. pr_err("error %d\n", rc);
  7100. goto rw_error;
  7101. }
  7102. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
  7103. if (rc != 0) {
  7104. pr_err("error %d\n", rc);
  7105. goto rw_error;
  7106. }
  7107. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
  7108. if (rc != 0) {
  7109. pr_err("error %d\n", rc);
  7110. goto rw_error;
  7111. }
  7112. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
  7113. if (rc != 0) {
  7114. pr_err("error %d\n", rc);
  7115. goto rw_error;
  7116. }
  7117. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
  7118. if (rc != 0) {
  7119. pr_err("error %d\n", rc);
  7120. goto rw_error;
  7121. }
  7122. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
  7123. if (rc != 0) {
  7124. pr_err("error %d\n", rc);
  7125. goto rw_error;
  7126. }
  7127. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
  7128. if (rc != 0) {
  7129. pr_err("error %d\n", rc);
  7130. goto rw_error;
  7131. }
  7132. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
  7133. if (rc != 0) {
  7134. pr_err("error %d\n", rc);
  7135. goto rw_error;
  7136. }
  7137. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
  7138. if (rc != 0) {
  7139. pr_err("error %d\n", rc);
  7140. goto rw_error;
  7141. }
  7142. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
  7143. if (rc != 0) {
  7144. pr_err("error %d\n", rc);
  7145. goto rw_error;
  7146. }
  7147. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
  7148. if (rc != 0) {
  7149. pr_err("error %d\n", rc);
  7150. goto rw_error;
  7151. }
  7152. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
  7153. if (rc != 0) {
  7154. pr_err("error %d\n", rc);
  7155. goto rw_error;
  7156. }
  7157. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
  7158. if (rc != 0) {
  7159. pr_err("error %d\n", rc);
  7160. goto rw_error;
  7161. }
  7162. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
  7163. if (rc != 0) {
  7164. pr_err("error %d\n", rc);
  7165. goto rw_error;
  7166. }
  7167. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
  7168. if (rc != 0) {
  7169. pr_err("error %d\n", rc);
  7170. goto rw_error;
  7171. }
  7172. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
  7173. if (rc != 0) {
  7174. pr_err("error %d\n", rc);
  7175. goto rw_error;
  7176. }
  7177. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
  7178. if (rc != 0) {
  7179. pr_err("error %d\n", rc);
  7180. goto rw_error;
  7181. }
  7182. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
  7183. if (rc != 0) {
  7184. pr_err("error %d\n", rc);
  7185. goto rw_error;
  7186. }
  7187. return 0;
  7188. rw_error:
  7189. return rc;
  7190. }
  7191. /*============================================================================*/
  7192. #define QAM_SET_OP_ALL 0x1
  7193. #define QAM_SET_OP_CONSTELLATION 0x2
  7194. #define QAM_SET_OP_SPECTRUM 0X4
  7195. /**
  7196. * \fn int set_qam ()
  7197. * \brief Set QAM demod.
  7198. * \param demod: instance of demod.
  7199. * \param channel: pointer to channel data.
  7200. * \return int.
  7201. */
  7202. static int
  7203. set_qam(struct drx_demod_instance *demod,
  7204. struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
  7205. {
  7206. struct i2c_device_addr *dev_addr = NULL;
  7207. struct drxj_data *ext_attr = NULL;
  7208. struct drx_common_attr *common_attr = NULL;
  7209. int rc;
  7210. u32 adc_frequency = 0;
  7211. u32 iqm_rc_rate = 0;
  7212. u16 cmd_result = 0;
  7213. u16 lc_symbol_freq = 0;
  7214. u16 iqm_rc_stretch = 0;
  7215. u16 set_env_parameters = 0;
  7216. u16 set_param_parameters[2] = { 0 };
  7217. struct drxjscu_cmd cmd_scu = { /* command */ 0,
  7218. /* parameter_len */ 0,
  7219. /* result_len */ 0,
  7220. /* parameter */ NULL,
  7221. /* result */ NULL
  7222. };
  7223. const u8 qam_a_taps[] = {
  7224. DRXJ_16TO8(-1), /* re0 */
  7225. DRXJ_16TO8(1), /* re1 */
  7226. DRXJ_16TO8(1), /* re2 */
  7227. DRXJ_16TO8(-1), /* re3 */
  7228. DRXJ_16TO8(-1), /* re4 */
  7229. DRXJ_16TO8(2), /* re5 */
  7230. DRXJ_16TO8(1), /* re6 */
  7231. DRXJ_16TO8(-2), /* re7 */
  7232. DRXJ_16TO8(0), /* re8 */
  7233. DRXJ_16TO8(3), /* re9 */
  7234. DRXJ_16TO8(-1), /* re10 */
  7235. DRXJ_16TO8(-3), /* re11 */
  7236. DRXJ_16TO8(4), /* re12 */
  7237. DRXJ_16TO8(1), /* re13 */
  7238. DRXJ_16TO8(-8), /* re14 */
  7239. DRXJ_16TO8(4), /* re15 */
  7240. DRXJ_16TO8(13), /* re16 */
  7241. DRXJ_16TO8(-13), /* re17 */
  7242. DRXJ_16TO8(-19), /* re18 */
  7243. DRXJ_16TO8(28), /* re19 */
  7244. DRXJ_16TO8(25), /* re20 */
  7245. DRXJ_16TO8(-53), /* re21 */
  7246. DRXJ_16TO8(-31), /* re22 */
  7247. DRXJ_16TO8(96), /* re23 */
  7248. DRXJ_16TO8(37), /* re24 */
  7249. DRXJ_16TO8(-190), /* re25 */
  7250. DRXJ_16TO8(-40), /* re26 */
  7251. DRXJ_16TO8(619) /* re27 */
  7252. };
  7253. const u8 qam_b64_taps[] = {
  7254. DRXJ_16TO8(0), /* re0 */
  7255. DRXJ_16TO8(-2), /* re1 */
  7256. DRXJ_16TO8(1), /* re2 */
  7257. DRXJ_16TO8(2), /* re3 */
  7258. DRXJ_16TO8(-2), /* re4 */
  7259. DRXJ_16TO8(0), /* re5 */
  7260. DRXJ_16TO8(4), /* re6 */
  7261. DRXJ_16TO8(-2), /* re7 */
  7262. DRXJ_16TO8(-4), /* re8 */
  7263. DRXJ_16TO8(4), /* re9 */
  7264. DRXJ_16TO8(3), /* re10 */
  7265. DRXJ_16TO8(-6), /* re11 */
  7266. DRXJ_16TO8(0), /* re12 */
  7267. DRXJ_16TO8(6), /* re13 */
  7268. DRXJ_16TO8(-5), /* re14 */
  7269. DRXJ_16TO8(-3), /* re15 */
  7270. DRXJ_16TO8(11), /* re16 */
  7271. DRXJ_16TO8(-4), /* re17 */
  7272. DRXJ_16TO8(-19), /* re18 */
  7273. DRXJ_16TO8(19), /* re19 */
  7274. DRXJ_16TO8(28), /* re20 */
  7275. DRXJ_16TO8(-45), /* re21 */
  7276. DRXJ_16TO8(-36), /* re22 */
  7277. DRXJ_16TO8(90), /* re23 */
  7278. DRXJ_16TO8(42), /* re24 */
  7279. DRXJ_16TO8(-185), /* re25 */
  7280. DRXJ_16TO8(-46), /* re26 */
  7281. DRXJ_16TO8(614) /* re27 */
  7282. };
  7283. const u8 qam_b256_taps[] = {
  7284. DRXJ_16TO8(-2), /* re0 */
  7285. DRXJ_16TO8(4), /* re1 */
  7286. DRXJ_16TO8(1), /* re2 */
  7287. DRXJ_16TO8(-4), /* re3 */
  7288. DRXJ_16TO8(0), /* re4 */
  7289. DRXJ_16TO8(4), /* re5 */
  7290. DRXJ_16TO8(-2), /* re6 */
  7291. DRXJ_16TO8(-4), /* re7 */
  7292. DRXJ_16TO8(5), /* re8 */
  7293. DRXJ_16TO8(2), /* re9 */
  7294. DRXJ_16TO8(-8), /* re10 */
  7295. DRXJ_16TO8(2), /* re11 */
  7296. DRXJ_16TO8(11), /* re12 */
  7297. DRXJ_16TO8(-8), /* re13 */
  7298. DRXJ_16TO8(-15), /* re14 */
  7299. DRXJ_16TO8(16), /* re15 */
  7300. DRXJ_16TO8(19), /* re16 */
  7301. DRXJ_16TO8(-27), /* re17 */
  7302. DRXJ_16TO8(-22), /* re18 */
  7303. DRXJ_16TO8(44), /* re19 */
  7304. DRXJ_16TO8(26), /* re20 */
  7305. DRXJ_16TO8(-69), /* re21 */
  7306. DRXJ_16TO8(-28), /* re22 */
  7307. DRXJ_16TO8(110), /* re23 */
  7308. DRXJ_16TO8(31), /* re24 */
  7309. DRXJ_16TO8(-201), /* re25 */
  7310. DRXJ_16TO8(-32), /* re26 */
  7311. DRXJ_16TO8(628) /* re27 */
  7312. };
  7313. const u8 qam_c_taps[] = {
  7314. DRXJ_16TO8(-3), /* re0 */
  7315. DRXJ_16TO8(3), /* re1 */
  7316. DRXJ_16TO8(2), /* re2 */
  7317. DRXJ_16TO8(-4), /* re3 */
  7318. DRXJ_16TO8(0), /* re4 */
  7319. DRXJ_16TO8(4), /* re5 */
  7320. DRXJ_16TO8(-1), /* re6 */
  7321. DRXJ_16TO8(-4), /* re7 */
  7322. DRXJ_16TO8(3), /* re8 */
  7323. DRXJ_16TO8(3), /* re9 */
  7324. DRXJ_16TO8(-5), /* re10 */
  7325. DRXJ_16TO8(0), /* re11 */
  7326. DRXJ_16TO8(9), /* re12 */
  7327. DRXJ_16TO8(-4), /* re13 */
  7328. DRXJ_16TO8(-12), /* re14 */
  7329. DRXJ_16TO8(10), /* re15 */
  7330. DRXJ_16TO8(16), /* re16 */
  7331. DRXJ_16TO8(-21), /* re17 */
  7332. DRXJ_16TO8(-20), /* re18 */
  7333. DRXJ_16TO8(37), /* re19 */
  7334. DRXJ_16TO8(25), /* re20 */
  7335. DRXJ_16TO8(-62), /* re21 */
  7336. DRXJ_16TO8(-28), /* re22 */
  7337. DRXJ_16TO8(105), /* re23 */
  7338. DRXJ_16TO8(31), /* re24 */
  7339. DRXJ_16TO8(-197), /* re25 */
  7340. DRXJ_16TO8(-33), /* re26 */
  7341. DRXJ_16TO8(626) /* re27 */
  7342. };
  7343. dev_addr = demod->my_i2c_dev_addr;
  7344. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  7345. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  7346. if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
  7347. if (ext_attr->standard == DRX_STANDARD_ITU_B) {
  7348. switch (channel->constellation) {
  7349. case DRX_CONSTELLATION_QAM256:
  7350. iqm_rc_rate = 0x00AE3562;
  7351. lc_symbol_freq =
  7352. QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
  7353. channel->symbolrate = 5360537;
  7354. iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
  7355. break;
  7356. case DRX_CONSTELLATION_QAM64:
  7357. iqm_rc_rate = 0x00C05A0E;
  7358. lc_symbol_freq = 409;
  7359. channel->symbolrate = 5056941;
  7360. iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
  7361. break;
  7362. default:
  7363. return -EINVAL;
  7364. }
  7365. } else {
  7366. adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
  7367. if (channel->symbolrate == 0) {
  7368. pr_err("error: channel symbolrate is zero!\n");
  7369. return -EIO;
  7370. }
  7371. iqm_rc_rate =
  7372. (adc_frequency / channel->symbolrate) * (1 << 21) +
  7373. (frac28
  7374. ((adc_frequency % channel->symbolrate),
  7375. channel->symbolrate) >> 7) - (1 << 23);
  7376. lc_symbol_freq =
  7377. (u16) (frac28
  7378. (channel->symbolrate +
  7379. (adc_frequency >> 13),
  7380. adc_frequency) >> 16);
  7381. if (lc_symbol_freq > 511)
  7382. lc_symbol_freq = 511;
  7383. iqm_rc_stretch = 21;
  7384. }
  7385. if (ext_attr->standard == DRX_STANDARD_ITU_A) {
  7386. set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
  7387. set_param_parameters[0] = channel->constellation; /* constellation */
  7388. set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
  7389. } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
  7390. set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
  7391. set_param_parameters[0] = channel->constellation; /* constellation */
  7392. set_param_parameters[1] = channel->interleavemode; /* interleave mode */
  7393. } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
  7394. set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
  7395. set_param_parameters[0] = channel->constellation; /* constellation */
  7396. set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
  7397. } else {
  7398. return -EINVAL;
  7399. }
  7400. }
  7401. if (op & QAM_SET_OP_ALL) {
  7402. /*
  7403. STEP 1: reset demodulator
  7404. resets IQM, QAM and FEC HW blocks
  7405. resets SCU variables
  7406. */
  7407. /* stop all comm_exec */
  7408. rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
  7409. if (rc != 0) {
  7410. pr_err("error %d\n", rc);
  7411. goto rw_error;
  7412. }
  7413. rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
  7414. if (rc != 0) {
  7415. pr_err("error %d\n", rc);
  7416. goto rw_error;
  7417. }
  7418. rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
  7419. if (rc != 0) {
  7420. pr_err("error %d\n", rc);
  7421. goto rw_error;
  7422. }
  7423. rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
  7424. if (rc != 0) {
  7425. pr_err("error %d\n", rc);
  7426. goto rw_error;
  7427. }
  7428. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
  7429. if (rc != 0) {
  7430. pr_err("error %d\n", rc);
  7431. goto rw_error;
  7432. }
  7433. rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
  7434. if (rc != 0) {
  7435. pr_err("error %d\n", rc);
  7436. goto rw_error;
  7437. }
  7438. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
  7439. if (rc != 0) {
  7440. pr_err("error %d\n", rc);
  7441. goto rw_error;
  7442. }
  7443. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
  7444. SCU_RAM_COMMAND_CMD_DEMOD_RESET;
  7445. cmd_scu.parameter_len = 0;
  7446. cmd_scu.result_len = 1;
  7447. cmd_scu.parameter = NULL;
  7448. cmd_scu.result = &cmd_result;
  7449. rc = scu_command(dev_addr, &cmd_scu);
  7450. if (rc != 0) {
  7451. pr_err("error %d\n", rc);
  7452. goto rw_error;
  7453. }
  7454. }
  7455. if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
  7456. /*
  7457. STEP 2: configure demodulator
  7458. -set env
  7459. -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
  7460. */
  7461. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
  7462. SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
  7463. cmd_scu.parameter_len = 1;
  7464. cmd_scu.result_len = 1;
  7465. cmd_scu.parameter = &set_env_parameters;
  7466. cmd_scu.result = &cmd_result;
  7467. rc = scu_command(dev_addr, &cmd_scu);
  7468. if (rc != 0) {
  7469. pr_err("error %d\n", rc);
  7470. goto rw_error;
  7471. }
  7472. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
  7473. SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
  7474. cmd_scu.parameter_len = 2;
  7475. cmd_scu.result_len = 1;
  7476. cmd_scu.parameter = set_param_parameters;
  7477. cmd_scu.result = &cmd_result;
  7478. rc = scu_command(dev_addr, &cmd_scu);
  7479. if (rc != 0) {
  7480. pr_err("error %d\n", rc);
  7481. goto rw_error;
  7482. }
  7483. /* set symbol rate */
  7484. rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
  7485. if (rc != 0) {
  7486. pr_err("error %d\n", rc);
  7487. goto rw_error;
  7488. }
  7489. ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
  7490. rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
  7491. if (rc != 0) {
  7492. pr_err("error %d\n", rc);
  7493. goto rw_error;
  7494. }
  7495. }
  7496. /* STEP 3: enable the system in a mode where the ADC provides valid signal
  7497. setup constellation independent registers */
  7498. /* from qam_cmd.py script (qam_driver_b) */
  7499. /* TODO: remove re-writes of HW reset values */
  7500. if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
  7501. rc = set_frequency(demod, channel, tuner_freq_offset);
  7502. if (rc != 0) {
  7503. pr_err("error %d\n", rc);
  7504. goto rw_error;
  7505. }
  7506. }
  7507. if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
  7508. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
  7509. if (rc != 0) {
  7510. pr_err("error %d\n", rc);
  7511. goto rw_error;
  7512. }
  7513. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
  7514. if (rc != 0) {
  7515. pr_err("error %d\n", rc);
  7516. goto rw_error;
  7517. }
  7518. }
  7519. if (op & QAM_SET_OP_ALL) {
  7520. if (!ext_attr->has_lna) {
  7521. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
  7522. if (rc != 0) {
  7523. pr_err("error %d\n", rc);
  7524. goto rw_error;
  7525. }
  7526. }
  7527. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
  7528. if (rc != 0) {
  7529. pr_err("error %d\n", rc);
  7530. goto rw_error;
  7531. }
  7532. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
  7533. if (rc != 0) {
  7534. pr_err("error %d\n", rc);
  7535. goto rw_error;
  7536. }
  7537. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
  7538. if (rc != 0) {
  7539. pr_err("error %d\n", rc);
  7540. goto rw_error;
  7541. }
  7542. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
  7543. if (rc != 0) {
  7544. pr_err("error %d\n", rc);
  7545. goto rw_error;
  7546. } /* scu temporary shut down agc */
  7547. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
  7548. if (rc != 0) {
  7549. pr_err("error %d\n", rc);
  7550. goto rw_error;
  7551. }
  7552. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
  7553. if (rc != 0) {
  7554. pr_err("error %d\n", rc);
  7555. goto rw_error;
  7556. }
  7557. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
  7558. if (rc != 0) {
  7559. pr_err("error %d\n", rc);
  7560. goto rw_error;
  7561. }
  7562. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
  7563. if (rc != 0) {
  7564. pr_err("error %d\n", rc);
  7565. goto rw_error;
  7566. }
  7567. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);
  7568. if (rc != 0) {
  7569. pr_err("error %d\n", rc);
  7570. goto rw_error;
  7571. }
  7572. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
  7573. if (rc != 0) {
  7574. pr_err("error %d\n", rc);
  7575. goto rw_error;
  7576. }
  7577. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
  7578. if (rc != 0) {
  7579. pr_err("error %d\n", rc);
  7580. goto rw_error;
  7581. }
  7582. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
  7583. if (rc != 0) {
  7584. pr_err("error %d\n", rc);
  7585. goto rw_error;
  7586. }
  7587. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
  7588. if (rc != 0) {
  7589. pr_err("error %d\n", rc);
  7590. goto rw_error;
  7591. } /*! reset default val ! */
  7592. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
  7593. if (rc != 0) {
  7594. pr_err("error %d\n", rc);
  7595. goto rw_error;
  7596. } /*! reset default val ! */
  7597. if (ext_attr->standard == DRX_STANDARD_ITU_B) {
  7598. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
  7599. if (rc != 0) {
  7600. pr_err("error %d\n", rc);
  7601. goto rw_error;
  7602. } /*! reset default val ! */
  7603. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
  7604. if (rc != 0) {
  7605. pr_err("error %d\n", rc);
  7606. goto rw_error;
  7607. } /*! reset default val ! */
  7608. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
  7609. if (rc != 0) {
  7610. pr_err("error %d\n", rc);
  7611. goto rw_error;
  7612. } /*! reset default val ! */
  7613. } else {
  7614. switch (channel->constellation) {
  7615. case DRX_CONSTELLATION_QAM16:
  7616. case DRX_CONSTELLATION_QAM64:
  7617. case DRX_CONSTELLATION_QAM256:
  7618. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
  7619. if (rc != 0) {
  7620. pr_err("error %d\n", rc);
  7621. goto rw_error;
  7622. }
  7623. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
  7624. if (rc != 0) {
  7625. pr_err("error %d\n", rc);
  7626. goto rw_error;
  7627. }
  7628. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
  7629. if (rc != 0) {
  7630. pr_err("error %d\n", rc);
  7631. goto rw_error;
  7632. } /*! reset default val ! */
  7633. break;
  7634. case DRX_CONSTELLATION_QAM32:
  7635. case DRX_CONSTELLATION_QAM128:
  7636. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
  7637. if (rc != 0) {
  7638. pr_err("error %d\n", rc);
  7639. goto rw_error;
  7640. }
  7641. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
  7642. if (rc != 0) {
  7643. pr_err("error %d\n", rc);
  7644. goto rw_error;
  7645. }
  7646. rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
  7647. if (rc != 0) {
  7648. pr_err("error %d\n", rc);
  7649. goto rw_error;
  7650. }
  7651. break;
  7652. default:
  7653. return -EIO;
  7654. } /* switch */
  7655. }
  7656. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
  7657. if (rc != 0) {
  7658. pr_err("error %d\n", rc);
  7659. goto rw_error;
  7660. } /*! reset default val ! */
  7661. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
  7662. if (rc != 0) {
  7663. pr_err("error %d\n", rc);
  7664. goto rw_error;
  7665. }
  7666. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
  7667. if (rc != 0) {
  7668. pr_err("error %d\n", rc);
  7669. goto rw_error;
  7670. }
  7671. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
  7672. if (rc != 0) {
  7673. pr_err("error %d\n", rc);
  7674. goto rw_error;
  7675. }
  7676. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);
  7677. if (rc != 0) {
  7678. pr_err("error %d\n", rc);
  7679. goto rw_error;
  7680. }
  7681. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
  7682. if (rc != 0) {
  7683. pr_err("error %d\n", rc);
  7684. goto rw_error;
  7685. }
  7686. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
  7687. if (rc != 0) {
  7688. pr_err("error %d\n", rc);
  7689. goto rw_error;
  7690. }
  7691. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
  7692. if (rc != 0) {
  7693. pr_err("error %d\n", rc);
  7694. goto rw_error;
  7695. }
  7696. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
  7697. if (rc != 0) {
  7698. pr_err("error %d\n", rc);
  7699. goto rw_error;
  7700. }
  7701. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
  7702. if (rc != 0) {
  7703. pr_err("error %d\n", rc);
  7704. goto rw_error;
  7705. }
  7706. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
  7707. if (rc != 0) {
  7708. pr_err("error %d\n", rc);
  7709. goto rw_error;
  7710. }
  7711. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
  7712. if (rc != 0) {
  7713. pr_err("error %d\n", rc);
  7714. goto rw_error;
  7715. }
  7716. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
  7717. if (rc != 0) {
  7718. pr_err("error %d\n", rc);
  7719. goto rw_error;
  7720. }
  7721. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
  7722. if (rc != 0) {
  7723. pr_err("error %d\n", rc);
  7724. goto rw_error;
  7725. }
  7726. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
  7727. if (rc != 0) {
  7728. pr_err("error %d\n", rc);
  7729. goto rw_error;
  7730. }
  7731. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
  7732. if (rc != 0) {
  7733. pr_err("error %d\n", rc);
  7734. goto rw_error;
  7735. }
  7736. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
  7737. if (rc != 0) {
  7738. pr_err("error %d\n", rc);
  7739. goto rw_error;
  7740. }
  7741. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
  7742. if (rc != 0) {
  7743. pr_err("error %d\n", rc);
  7744. goto rw_error;
  7745. }
  7746. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
  7747. if (rc != 0) {
  7748. pr_err("error %d\n", rc);
  7749. goto rw_error;
  7750. }
  7751. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
  7752. if (rc != 0) {
  7753. pr_err("error %d\n", rc);
  7754. goto rw_error;
  7755. }
  7756. rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
  7757. if (rc != 0) {
  7758. pr_err("error %d\n", rc);
  7759. goto rw_error;
  7760. }
  7761. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
  7762. if (rc != 0) {
  7763. pr_err("error %d\n", rc);
  7764. goto rw_error;
  7765. }
  7766. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
  7767. if (rc != 0) {
  7768. pr_err("error %d\n", rc);
  7769. goto rw_error;
  7770. }
  7771. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
  7772. if (rc != 0) {
  7773. pr_err("error %d\n", rc);
  7774. goto rw_error;
  7775. }
  7776. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
  7777. if (rc != 0) {
  7778. pr_err("error %d\n", rc);
  7779. goto rw_error;
  7780. }
  7781. /* No more resets of the IQM, current standard correctly set =>
  7782. now AGCs can be configured. */
  7783. /* turn on IQMAF. It has to be in front of setAgc**() */
  7784. rc = set_iqm_af(demod, true);
  7785. if (rc != 0) {
  7786. pr_err("error %d\n", rc);
  7787. goto rw_error;
  7788. }
  7789. rc = adc_synchronization(demod);
  7790. if (rc != 0) {
  7791. pr_err("error %d\n", rc);
  7792. goto rw_error;
  7793. }
  7794. rc = init_agc(demod);
  7795. if (rc != 0) {
  7796. pr_err("error %d\n", rc);
  7797. goto rw_error;
  7798. }
  7799. rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
  7800. if (rc != 0) {
  7801. pr_err("error %d\n", rc);
  7802. goto rw_error;
  7803. }
  7804. rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
  7805. if (rc != 0) {
  7806. pr_err("error %d\n", rc);
  7807. goto rw_error;
  7808. }
  7809. {
  7810. /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
  7811. of only the gain */
  7812. struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
  7813. qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
  7814. rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
  7815. if (rc != 0) {
  7816. pr_err("error %d\n", rc);
  7817. goto rw_error;
  7818. }
  7819. }
  7820. rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
  7821. if (rc != 0) {
  7822. pr_err("error %d\n", rc);
  7823. goto rw_error;
  7824. }
  7825. }
  7826. if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
  7827. if (ext_attr->standard == DRX_STANDARD_ITU_A) {
  7828. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
  7829. if (rc != 0) {
  7830. pr_err("error %d\n", rc);
  7831. goto rw_error;
  7832. }
  7833. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
  7834. if (rc != 0) {
  7835. pr_err("error %d\n", rc);
  7836. goto rw_error;
  7837. }
  7838. } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
  7839. switch (channel->constellation) {
  7840. case DRX_CONSTELLATION_QAM64:
  7841. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
  7842. if (rc != 0) {
  7843. pr_err("error %d\n", rc);
  7844. goto rw_error;
  7845. }
  7846. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
  7847. if (rc != 0) {
  7848. pr_err("error %d\n", rc);
  7849. goto rw_error;
  7850. }
  7851. break;
  7852. case DRX_CONSTELLATION_QAM256:
  7853. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
  7854. if (rc != 0) {
  7855. pr_err("error %d\n", rc);
  7856. goto rw_error;
  7857. }
  7858. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
  7859. if (rc != 0) {
  7860. pr_err("error %d\n", rc);
  7861. goto rw_error;
  7862. }
  7863. break;
  7864. default:
  7865. return -EIO;
  7866. }
  7867. } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
  7868. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
  7869. if (rc != 0) {
  7870. pr_err("error %d\n", rc);
  7871. goto rw_error;
  7872. }
  7873. rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
  7874. if (rc != 0) {
  7875. pr_err("error %d\n", rc);
  7876. goto rw_error;
  7877. }
  7878. }
  7879. /* SETP 4: constellation specific setup */
  7880. switch (channel->constellation) {
  7881. case DRX_CONSTELLATION_QAM16:
  7882. rc = set_qam16(demod);
  7883. if (rc != 0) {
  7884. pr_err("error %d\n", rc);
  7885. goto rw_error;
  7886. }
  7887. break;
  7888. case DRX_CONSTELLATION_QAM32:
  7889. rc = set_qam32(demod);
  7890. if (rc != 0) {
  7891. pr_err("error %d\n", rc);
  7892. goto rw_error;
  7893. }
  7894. break;
  7895. case DRX_CONSTELLATION_QAM64:
  7896. rc = set_qam64(demod);
  7897. if (rc != 0) {
  7898. pr_err("error %d\n", rc);
  7899. goto rw_error;
  7900. }
  7901. break;
  7902. case DRX_CONSTELLATION_QAM128:
  7903. rc = set_qam128(demod);
  7904. if (rc != 0) {
  7905. pr_err("error %d\n", rc);
  7906. goto rw_error;
  7907. }
  7908. break;
  7909. case DRX_CONSTELLATION_QAM256:
  7910. rc = set_qam256(demod);
  7911. if (rc != 0) {
  7912. pr_err("error %d\n", rc);
  7913. goto rw_error;
  7914. }
  7915. break;
  7916. default:
  7917. return -EIO;
  7918. } /* switch */
  7919. }
  7920. if ((op & QAM_SET_OP_ALL)) {
  7921. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
  7922. if (rc != 0) {
  7923. pr_err("error %d\n", rc);
  7924. goto rw_error;
  7925. }
  7926. /* Mpeg output has to be in front of FEC active */
  7927. rc = set_mpegtei_handling(demod);
  7928. if (rc != 0) {
  7929. pr_err("error %d\n", rc);
  7930. goto rw_error;
  7931. }
  7932. rc = bit_reverse_mpeg_output(demod);
  7933. if (rc != 0) {
  7934. pr_err("error %d\n", rc);
  7935. goto rw_error;
  7936. }
  7937. rc = set_mpeg_start_width(demod);
  7938. if (rc != 0) {
  7939. pr_err("error %d\n", rc);
  7940. goto rw_error;
  7941. }
  7942. {
  7943. /* TODO: move to set_standard after hardware reset value problem is solved */
  7944. /* Configure initial MPEG output */
  7945. struct drx_cfg_mpeg_output cfg_mpeg_output;
  7946. memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
  7947. cfg_mpeg_output.enable_mpeg_output = true;
  7948. rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
  7949. if (rc != 0) {
  7950. pr_err("error %d\n", rc);
  7951. goto rw_error;
  7952. }
  7953. }
  7954. }
  7955. if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
  7956. /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
  7957. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
  7958. SCU_RAM_COMMAND_CMD_DEMOD_START;
  7959. cmd_scu.parameter_len = 0;
  7960. cmd_scu.result_len = 1;
  7961. cmd_scu.parameter = NULL;
  7962. cmd_scu.result = &cmd_result;
  7963. rc = scu_command(dev_addr, &cmd_scu);
  7964. if (rc != 0) {
  7965. pr_err("error %d\n", rc);
  7966. goto rw_error;
  7967. }
  7968. }
  7969. rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
  7970. if (rc != 0) {
  7971. pr_err("error %d\n", rc);
  7972. goto rw_error;
  7973. }
  7974. rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
  7975. if (rc != 0) {
  7976. pr_err("error %d\n", rc);
  7977. goto rw_error;
  7978. }
  7979. rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
  7980. if (rc != 0) {
  7981. pr_err("error %d\n", rc);
  7982. goto rw_error;
  7983. }
  7984. return 0;
  7985. rw_error:
  7986. return rc;
  7987. }
  7988. /*============================================================================*/
  7989. static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
  7990. static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
  7991. {
  7992. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  7993. struct drxj_data *ext_attr = demod->my_ext_attr;
  7994. int rc;
  7995. u32 iqm_fs_rate_ofs = 0;
  7996. u32 iqm_fs_rate_lo = 0;
  7997. u16 qam_ctl_ena = 0;
  7998. u16 data = 0;
  7999. u16 equ_mode = 0;
  8000. u16 fsm_state = 0;
  8001. int i = 0;
  8002. int ofsofs = 0;
  8003. /* Silence the controlling of lc, equ, and the acquisition state machine */
  8004. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
  8005. if (rc != 0) {
  8006. pr_err("error %d\n", rc);
  8007. goto rw_error;
  8008. }
  8009. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), 0);
  8010. if (rc != 0) {
  8011. pr_err("error %d\n", rc);
  8012. goto rw_error;
  8013. }
  8014. /* freeze the frequency control loop */
  8015. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);
  8016. if (rc != 0) {
  8017. pr_err("error %d\n", rc);
  8018. goto rw_error;
  8019. }
  8020. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);
  8021. if (rc != 0) {
  8022. pr_err("error %d\n", rc);
  8023. goto rw_error;
  8024. }
  8025. rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
  8026. if (rc != 0) {
  8027. pr_err("error %d\n", rc);
  8028. goto rw_error;
  8029. }
  8030. rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
  8031. if (rc != 0) {
  8032. pr_err("error %d\n", rc);
  8033. goto rw_error;
  8034. }
  8035. ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
  8036. iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
  8037. iqm_fs_rate_ofs -= 2 * ofsofs;
  8038. /* freeze dq/fq updating */
  8039. rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
  8040. if (rc != 0) {
  8041. pr_err("error %d\n", rc);
  8042. goto rw_error;
  8043. }
  8044. data = (data & 0xfff9);
  8045. rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
  8046. if (rc != 0) {
  8047. pr_err("error %d\n", rc);
  8048. goto rw_error;
  8049. }
  8050. rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
  8051. if (rc != 0) {
  8052. pr_err("error %d\n", rc);
  8053. goto rw_error;
  8054. }
  8055. /* lc_cp / _ci / _ca */
  8056. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);
  8057. if (rc != 0) {
  8058. pr_err("error %d\n", rc);
  8059. goto rw_error;
  8060. }
  8061. rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);
  8062. if (rc != 0) {
  8063. pr_err("error %d\n", rc);
  8064. goto rw_error;
  8065. }
  8066. rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
  8067. if (rc != 0) {
  8068. pr_err("error %d\n", rc);
  8069. goto rw_error;
  8070. }
  8071. /* flip the spec */
  8072. rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
  8073. if (rc != 0) {
  8074. pr_err("error %d\n", rc);
  8075. goto rw_error;
  8076. }
  8077. ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
  8078. ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
  8079. /* freeze dq/fq updating */
  8080. rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
  8081. if (rc != 0) {
  8082. pr_err("error %d\n", rc);
  8083. goto rw_error;
  8084. }
  8085. equ_mode = data;
  8086. data = (data & 0xfff9);
  8087. rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
  8088. if (rc != 0) {
  8089. pr_err("error %d\n", rc);
  8090. goto rw_error;
  8091. }
  8092. rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
  8093. if (rc != 0) {
  8094. pr_err("error %d\n", rc);
  8095. goto rw_error;
  8096. }
  8097. for (i = 0; i < 28; i++) {
  8098. rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
  8099. if (rc != 0) {
  8100. pr_err("error %d\n", rc);
  8101. goto rw_error;
  8102. }
  8103. rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
  8104. if (rc != 0) {
  8105. pr_err("error %d\n", rc);
  8106. goto rw_error;
  8107. }
  8108. }
  8109. for (i = 0; i < 24; i++) {
  8110. rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
  8111. if (rc != 0) {
  8112. pr_err("error %d\n", rc);
  8113. goto rw_error;
  8114. }
  8115. rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
  8116. if (rc != 0) {
  8117. pr_err("error %d\n", rc);
  8118. goto rw_error;
  8119. }
  8120. }
  8121. data = equ_mode;
  8122. rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
  8123. if (rc != 0) {
  8124. pr_err("error %d\n", rc);
  8125. goto rw_error;
  8126. }
  8127. rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
  8128. if (rc != 0) {
  8129. pr_err("error %d\n", rc);
  8130. goto rw_error;
  8131. }
  8132. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
  8133. if (rc != 0) {
  8134. pr_err("error %d\n", rc);
  8135. goto rw_error;
  8136. }
  8137. i = 0;
  8138. while ((fsm_state != 4) && (i++ < 100)) {
  8139. rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
  8140. if (rc != 0) {
  8141. pr_err("error %d\n", rc);
  8142. goto rw_error;
  8143. }
  8144. }
  8145. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
  8146. if (rc != 0) {
  8147. pr_err("error %d\n", rc);
  8148. goto rw_error;
  8149. }
  8150. return 0;
  8151. rw_error:
  8152. return rc;
  8153. }
  8154. #define NO_LOCK 0x0
  8155. #define DEMOD_LOCKED 0x1
  8156. #define SYNC_FLIPPED 0x2
  8157. #define SPEC_MIRRORED 0x4
  8158. /**
  8159. * \fn int qam64auto ()
  8160. * \brief auto do sync pattern switching and mirroring.
  8161. * \param demod: instance of demod.
  8162. * \param channel: pointer to channel data.
  8163. * \param tuner_freq_offset: tuner frequency offset.
  8164. * \param lock_status: pointer to lock status.
  8165. * \return int.
  8166. */
  8167. static int
  8168. qam64auto(struct drx_demod_instance *demod,
  8169. struct drx_channel *channel,
  8170. s32 tuner_freq_offset, enum drx_lock_status *lock_status)
  8171. {
  8172. struct drxj_data *ext_attr = demod->my_ext_attr;
  8173. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  8174. struct drx39xxj_state *state = dev_addr->user_data;
  8175. struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
  8176. int rc;
  8177. u32 lck_state = NO_LOCK;
  8178. u32 start_time = 0;
  8179. u32 d_locked_time = 0;
  8180. u32 timeout_ofs = 0;
  8181. u16 data = 0;
  8182. /* external attributes for storing acquired channel constellation */
  8183. *lock_status = DRX_NOT_LOCKED;
  8184. start_time = jiffies_to_msecs(jiffies);
  8185. lck_state = NO_LOCK;
  8186. do {
  8187. rc = ctrl_lock_status(demod, lock_status);
  8188. if (rc != 0) {
  8189. pr_err("error %d\n", rc);
  8190. goto rw_error;
  8191. }
  8192. switch (lck_state) {
  8193. case NO_LOCK:
  8194. if (*lock_status == DRXJ_DEMOD_LOCK) {
  8195. rc = ctrl_get_qam_sig_quality(demod);
  8196. if (rc != 0) {
  8197. pr_err("error %d\n", rc);
  8198. goto rw_error;
  8199. }
  8200. if (p->cnr.stat[0].svalue > 20800) {
  8201. lck_state = DEMOD_LOCKED;
  8202. /* some delay to see if fec_lock possible TODO find the right value */
  8203. timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
  8204. d_locked_time = jiffies_to_msecs(jiffies);
  8205. }
  8206. }
  8207. break;
  8208. case DEMOD_LOCKED:
  8209. if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
  8210. ((jiffies_to_msecs(jiffies) - d_locked_time) >
  8211. DRXJ_QAM_FEC_LOCK_WAITTIME)) {
  8212. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
  8213. if (rc != 0) {
  8214. pr_err("error %d\n", rc);
  8215. goto rw_error;
  8216. }
  8217. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
  8218. if (rc != 0) {
  8219. pr_err("error %d\n", rc);
  8220. goto rw_error;
  8221. }
  8222. lck_state = SYNC_FLIPPED;
  8223. msleep(10);
  8224. }
  8225. break;
  8226. case SYNC_FLIPPED:
  8227. if (*lock_status == DRXJ_DEMOD_LOCK) {
  8228. if (channel->mirror == DRX_MIRROR_AUTO) {
  8229. /* flip sync pattern back */
  8230. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
  8231. if (rc != 0) {
  8232. pr_err("error %d\n", rc);
  8233. goto rw_error;
  8234. }
  8235. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
  8236. if (rc != 0) {
  8237. pr_err("error %d\n", rc);
  8238. goto rw_error;
  8239. }
  8240. /* flip spectrum */
  8241. ext_attr->mirror = DRX_MIRROR_YES;
  8242. rc = qam_flip_spec(demod, channel);
  8243. if (rc != 0) {
  8244. pr_err("error %d\n", rc);
  8245. goto rw_error;
  8246. }
  8247. lck_state = SPEC_MIRRORED;
  8248. /* reset timer TODO: still need 500ms? */
  8249. start_time = d_locked_time =
  8250. jiffies_to_msecs(jiffies);
  8251. timeout_ofs = 0;
  8252. } else { /* no need to wait lock */
  8253. start_time =
  8254. jiffies_to_msecs(jiffies) -
  8255. DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
  8256. }
  8257. }
  8258. break;
  8259. case SPEC_MIRRORED:
  8260. if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
  8261. ((jiffies_to_msecs(jiffies) - d_locked_time) >
  8262. DRXJ_QAM_FEC_LOCK_WAITTIME)) {
  8263. rc = ctrl_get_qam_sig_quality(demod);
  8264. if (rc != 0) {
  8265. pr_err("error %d\n", rc);
  8266. goto rw_error;
  8267. }
  8268. if (p->cnr.stat[0].svalue > 20800) {
  8269. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
  8270. if (rc != 0) {
  8271. pr_err("error %d\n", rc);
  8272. goto rw_error;
  8273. }
  8274. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
  8275. if (rc != 0) {
  8276. pr_err("error %d\n", rc);
  8277. goto rw_error;
  8278. }
  8279. /* no need to wait lock */
  8280. start_time =
  8281. jiffies_to_msecs(jiffies) -
  8282. DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
  8283. }
  8284. }
  8285. break;
  8286. default:
  8287. break;
  8288. }
  8289. msleep(10);
  8290. } while
  8291. ((*lock_status != DRX_LOCKED) &&
  8292. (*lock_status != DRX_NEVER_LOCK) &&
  8293. ((jiffies_to_msecs(jiffies) - start_time) <
  8294. (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
  8295. );
  8296. /* Returning control to apllication ... */
  8297. return 0;
  8298. rw_error:
  8299. return rc;
  8300. }
  8301. /**
  8302. * \fn int qam256auto ()
  8303. * \brief auto do sync pattern switching and mirroring.
  8304. * \param demod: instance of demod.
  8305. * \param channel: pointer to channel data.
  8306. * \param tuner_freq_offset: tuner frequency offset.
  8307. * \param lock_status: pointer to lock status.
  8308. * \return int.
  8309. */
  8310. static int
  8311. qam256auto(struct drx_demod_instance *demod,
  8312. struct drx_channel *channel,
  8313. s32 tuner_freq_offset, enum drx_lock_status *lock_status)
  8314. {
  8315. struct drxj_data *ext_attr = demod->my_ext_attr;
  8316. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  8317. struct drx39xxj_state *state = dev_addr->user_data;
  8318. struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
  8319. int rc;
  8320. u32 lck_state = NO_LOCK;
  8321. u32 start_time = 0;
  8322. u32 d_locked_time = 0;
  8323. u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
  8324. /* external attributes for storing acquired channel constellation */
  8325. *lock_status = DRX_NOT_LOCKED;
  8326. start_time = jiffies_to_msecs(jiffies);
  8327. lck_state = NO_LOCK;
  8328. do {
  8329. rc = ctrl_lock_status(demod, lock_status);
  8330. if (rc != 0) {
  8331. pr_err("error %d\n", rc);
  8332. goto rw_error;
  8333. }
  8334. switch (lck_state) {
  8335. case NO_LOCK:
  8336. if (*lock_status == DRXJ_DEMOD_LOCK) {
  8337. rc = ctrl_get_qam_sig_quality(demod);
  8338. if (rc != 0) {
  8339. pr_err("error %d\n", rc);
  8340. goto rw_error;
  8341. }
  8342. if (p->cnr.stat[0].svalue > 26800) {
  8343. lck_state = DEMOD_LOCKED;
  8344. timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
  8345. d_locked_time = jiffies_to_msecs(jiffies);
  8346. }
  8347. }
  8348. break;
  8349. case DEMOD_LOCKED:
  8350. if (*lock_status == DRXJ_DEMOD_LOCK) {
  8351. if ((channel->mirror == DRX_MIRROR_AUTO) &&
  8352. ((jiffies_to_msecs(jiffies) - d_locked_time) >
  8353. DRXJ_QAM_FEC_LOCK_WAITTIME)) {
  8354. ext_attr->mirror = DRX_MIRROR_YES;
  8355. rc = qam_flip_spec(demod, channel);
  8356. if (rc != 0) {
  8357. pr_err("error %d\n", rc);
  8358. goto rw_error;
  8359. }
  8360. lck_state = SPEC_MIRRORED;
  8361. /* reset timer TODO: still need 300ms? */
  8362. start_time = jiffies_to_msecs(jiffies);
  8363. timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
  8364. }
  8365. }
  8366. break;
  8367. case SPEC_MIRRORED:
  8368. break;
  8369. default:
  8370. break;
  8371. }
  8372. msleep(10);
  8373. } while
  8374. ((*lock_status < DRX_LOCKED) &&
  8375. (*lock_status != DRX_NEVER_LOCK) &&
  8376. ((jiffies_to_msecs(jiffies) - start_time) <
  8377. (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
  8378. return 0;
  8379. rw_error:
  8380. return rc;
  8381. }
  8382. /**
  8383. * \fn int set_qam_channel ()
  8384. * \brief Set QAM channel according to the requested constellation.
  8385. * \param demod: instance of demod.
  8386. * \param channel: pointer to channel data.
  8387. * \return int.
  8388. */
  8389. static int
  8390. set_qam_channel(struct drx_demod_instance *demod,
  8391. struct drx_channel *channel, s32 tuner_freq_offset)
  8392. {
  8393. struct drxj_data *ext_attr = NULL;
  8394. int rc;
  8395. enum drx_lock_status lock_status = DRX_NOT_LOCKED;
  8396. bool auto_flag = false;
  8397. /* external attributes for storing acquired channel constellation */
  8398. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  8399. /* set QAM channel constellation */
  8400. switch (channel->constellation) {
  8401. case DRX_CONSTELLATION_QAM16:
  8402. case DRX_CONSTELLATION_QAM32:
  8403. case DRX_CONSTELLATION_QAM128:
  8404. return -EINVAL;
  8405. case DRX_CONSTELLATION_QAM64:
  8406. case DRX_CONSTELLATION_QAM256:
  8407. if (ext_attr->standard != DRX_STANDARD_ITU_B)
  8408. return -EINVAL;
  8409. ext_attr->constellation = channel->constellation;
  8410. if (channel->mirror == DRX_MIRROR_AUTO)
  8411. ext_attr->mirror = DRX_MIRROR_NO;
  8412. else
  8413. ext_attr->mirror = channel->mirror;
  8414. rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
  8415. if (rc != 0) {
  8416. pr_err("error %d\n", rc);
  8417. goto rw_error;
  8418. }
  8419. if (channel->constellation == DRX_CONSTELLATION_QAM64)
  8420. rc = qam64auto(demod, channel, tuner_freq_offset,
  8421. &lock_status);
  8422. else
  8423. rc = qam256auto(demod, channel, tuner_freq_offset,
  8424. &lock_status);
  8425. if (rc != 0) {
  8426. pr_err("error %d\n", rc);
  8427. goto rw_error;
  8428. }
  8429. break;
  8430. case DRX_CONSTELLATION_AUTO: /* for channel scan */
  8431. if (ext_attr->standard == DRX_STANDARD_ITU_B) {
  8432. u16 qam_ctl_ena = 0;
  8433. auto_flag = true;
  8434. /* try to lock default QAM constellation: QAM256 */
  8435. channel->constellation = DRX_CONSTELLATION_QAM256;
  8436. ext_attr->constellation = DRX_CONSTELLATION_QAM256;
  8437. if (channel->mirror == DRX_MIRROR_AUTO)
  8438. ext_attr->mirror = DRX_MIRROR_NO;
  8439. else
  8440. ext_attr->mirror = channel->mirror;
  8441. rc = set_qam(demod, channel, tuner_freq_offset,
  8442. QAM_SET_OP_ALL);
  8443. if (rc != 0) {
  8444. pr_err("error %d\n", rc);
  8445. goto rw_error;
  8446. }
  8447. rc = qam256auto(demod, channel, tuner_freq_offset,
  8448. &lock_status);
  8449. if (rc != 0) {
  8450. pr_err("error %d\n", rc);
  8451. goto rw_error;
  8452. }
  8453. if (lock_status >= DRX_LOCKED) {
  8454. channel->constellation = DRX_CONSTELLATION_AUTO;
  8455. break;
  8456. }
  8457. /* QAM254 not locked. Try QAM64 constellation */
  8458. channel->constellation = DRX_CONSTELLATION_QAM64;
  8459. ext_attr->constellation = DRX_CONSTELLATION_QAM64;
  8460. if (channel->mirror == DRX_MIRROR_AUTO)
  8461. ext_attr->mirror = DRX_MIRROR_NO;
  8462. else
  8463. ext_attr->mirror = channel->mirror;
  8464. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
  8465. SCU_RAM_QAM_CTL_ENA__A,
  8466. &qam_ctl_ena, 0);
  8467. if (rc != 0) {
  8468. pr_err("error %d\n", rc);
  8469. goto rw_error;
  8470. }
  8471. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
  8472. SCU_RAM_QAM_CTL_ENA__A,
  8473. qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
  8474. if (rc != 0) {
  8475. pr_err("error %d\n", rc);
  8476. goto rw_error;
  8477. }
  8478. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
  8479. SCU_RAM_QAM_FSM_STATE_TGT__A,
  8480. 0x2, 0);
  8481. if (rc != 0) {
  8482. pr_err("error %d\n", rc);
  8483. goto rw_error;
  8484. } /* force to rate hunting */
  8485. rc = set_qam(demod, channel, tuner_freq_offset,
  8486. QAM_SET_OP_CONSTELLATION);
  8487. if (rc != 0) {
  8488. pr_err("error %d\n", rc);
  8489. goto rw_error;
  8490. }
  8491. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
  8492. SCU_RAM_QAM_CTL_ENA__A,
  8493. qam_ctl_ena, 0);
  8494. if (rc != 0) {
  8495. pr_err("error %d\n", rc);
  8496. goto rw_error;
  8497. }
  8498. rc = qam64auto(demod, channel, tuner_freq_offset,
  8499. &lock_status);
  8500. if (rc != 0) {
  8501. pr_err("error %d\n", rc);
  8502. goto rw_error;
  8503. }
  8504. channel->constellation = DRX_CONSTELLATION_AUTO;
  8505. } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
  8506. u16 qam_ctl_ena = 0;
  8507. channel->constellation = DRX_CONSTELLATION_QAM64;
  8508. ext_attr->constellation = DRX_CONSTELLATION_QAM64;
  8509. auto_flag = true;
  8510. if (channel->mirror == DRX_MIRROR_AUTO)
  8511. ext_attr->mirror = DRX_MIRROR_NO;
  8512. else
  8513. ext_attr->mirror = channel->mirror;
  8514. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
  8515. SCU_RAM_QAM_CTL_ENA__A,
  8516. &qam_ctl_ena, 0);
  8517. if (rc != 0) {
  8518. pr_err("error %d\n", rc);
  8519. goto rw_error;
  8520. }
  8521. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
  8522. SCU_RAM_QAM_CTL_ENA__A,
  8523. qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
  8524. if (rc != 0) {
  8525. pr_err("error %d\n", rc);
  8526. goto rw_error;
  8527. }
  8528. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
  8529. SCU_RAM_QAM_FSM_STATE_TGT__A,
  8530. 0x2, 0);
  8531. if (rc != 0) {
  8532. pr_err("error %d\n", rc);
  8533. goto rw_error;
  8534. } /* force to rate hunting */
  8535. rc = set_qam(demod, channel, tuner_freq_offset,
  8536. QAM_SET_OP_CONSTELLATION);
  8537. if (rc != 0) {
  8538. pr_err("error %d\n", rc);
  8539. goto rw_error;
  8540. }
  8541. rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
  8542. SCU_RAM_QAM_CTL_ENA__A,
  8543. qam_ctl_ena, 0);
  8544. if (rc != 0) {
  8545. pr_err("error %d\n", rc);
  8546. goto rw_error;
  8547. }
  8548. rc = qam64auto(demod, channel, tuner_freq_offset,
  8549. &lock_status);
  8550. if (rc != 0) {
  8551. pr_err("error %d\n", rc);
  8552. goto rw_error;
  8553. }
  8554. channel->constellation = DRX_CONSTELLATION_AUTO;
  8555. } else {
  8556. return -EINVAL;
  8557. }
  8558. break;
  8559. default:
  8560. return -EINVAL;
  8561. }
  8562. return 0;
  8563. rw_error:
  8564. /* restore starting value */
  8565. if (auto_flag)
  8566. channel->constellation = DRX_CONSTELLATION_AUTO;
  8567. return rc;
  8568. }
  8569. /*============================================================================*/
  8570. /**
  8571. * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
  8572. * \brief Get RS error count in QAM mode (used for post RS BER calculation)
  8573. * \return Error code
  8574. *
  8575. * precondition: measurement period & measurement prescale must be set
  8576. *
  8577. */
  8578. static int
  8579. get_qamrs_err_count(struct i2c_device_addr *dev_addr,
  8580. struct drxjrs_errors *rs_errors)
  8581. {
  8582. int rc;
  8583. u16 nr_bit_errors = 0,
  8584. nr_symbol_errors = 0,
  8585. nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
  8586. /* check arguments */
  8587. if (dev_addr == NULL)
  8588. return -EINVAL;
  8589. /* all reported errors are received in the */
  8590. /* most recently finished measurment period */
  8591. /* no of pre RS bit errors */
  8592. rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
  8593. if (rc != 0) {
  8594. pr_err("error %d\n", rc);
  8595. goto rw_error;
  8596. }
  8597. /* no of symbol errors */
  8598. rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
  8599. if (rc != 0) {
  8600. pr_err("error %d\n", rc);
  8601. goto rw_error;
  8602. }
  8603. /* no of packet errors */
  8604. rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
  8605. if (rc != 0) {
  8606. pr_err("error %d\n", rc);
  8607. goto rw_error;
  8608. }
  8609. /* no of failures to decode */
  8610. rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
  8611. if (rc != 0) {
  8612. pr_err("error %d\n", rc);
  8613. goto rw_error;
  8614. }
  8615. /* no of post RS bit erros */
  8616. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
  8617. if (rc != 0) {
  8618. pr_err("error %d\n", rc);
  8619. goto rw_error;
  8620. }
  8621. /* TODO: NOTE */
  8622. /* These register values are fetched in non-atomic fashion */
  8623. /* It is possible that the read values contain unrelated information */
  8624. rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
  8625. rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
  8626. rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
  8627. rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
  8628. rs_errors->nr_snc_par_fail_count =
  8629. nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
  8630. return 0;
  8631. rw_error:
  8632. return rc;
  8633. }
  8634. /*============================================================================*/
  8635. /**
  8636. * \fn int get_sig_strength()
  8637. * \brief Retrieve signal strength for VSB and QAM.
  8638. * \param demod Pointer to demod instance
  8639. * \param u16-t Pointer to signal strength data; range 0, .. , 100.
  8640. * \return int.
  8641. * \retval 0 sig_strength contains valid data.
  8642. * \retval -EINVAL sig_strength is NULL.
  8643. * \retval -EIO Erroneous data, sig_strength contains invalid data.
  8644. */
  8645. #define DRXJ_AGC_TOP 0x2800
  8646. #define DRXJ_AGC_SNS 0x1600
  8647. #define DRXJ_RFAGC_MAX 0x3fff
  8648. #define DRXJ_RFAGC_MIN 0x800
  8649. static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
  8650. {
  8651. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  8652. int rc;
  8653. u16 rf_gain = 0;
  8654. u16 if_gain = 0;
  8655. u16 if_agc_sns = 0;
  8656. u16 if_agc_top = 0;
  8657. u16 rf_agc_max = 0;
  8658. u16 rf_agc_min = 0;
  8659. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
  8660. if (rc != 0) {
  8661. pr_err("error %d\n", rc);
  8662. goto rw_error;
  8663. }
  8664. if_gain &= IQM_AF_AGC_IF__M;
  8665. rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
  8666. if (rc != 0) {
  8667. pr_err("error %d\n", rc);
  8668. goto rw_error;
  8669. }
  8670. rf_gain &= IQM_AF_AGC_RF__M;
  8671. if_agc_sns = DRXJ_AGC_SNS;
  8672. if_agc_top = DRXJ_AGC_TOP;
  8673. rf_agc_max = DRXJ_RFAGC_MAX;
  8674. rf_agc_min = DRXJ_RFAGC_MIN;
  8675. if (if_gain > if_agc_top) {
  8676. if (rf_gain > rf_agc_max)
  8677. *sig_strength = 100;
  8678. else if (rf_gain > rf_agc_min) {
  8679. if (rf_agc_max == rf_agc_min) {
  8680. pr_err("error: rf_agc_max == rf_agc_min\n");
  8681. return -EIO;
  8682. }
  8683. *sig_strength =
  8684. 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
  8685. rf_agc_min);
  8686. } else
  8687. *sig_strength = 75;
  8688. } else if (if_gain > if_agc_sns) {
  8689. if (if_agc_top == if_agc_sns) {
  8690. pr_err("error: if_agc_top == if_agc_sns\n");
  8691. return -EIO;
  8692. }
  8693. *sig_strength =
  8694. 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
  8695. } else {
  8696. if (!if_agc_sns) {
  8697. pr_err("error: if_agc_sns is zero!\n");
  8698. return -EIO;
  8699. }
  8700. *sig_strength = (20 * if_gain / if_agc_sns);
  8701. }
  8702. if (*sig_strength <= 7)
  8703. *sig_strength = 0;
  8704. return 0;
  8705. rw_error:
  8706. return rc;
  8707. }
  8708. /**
  8709. * \fn int ctrl_get_qam_sig_quality()
  8710. * \brief Retrieve QAM signal quality from device.
  8711. * \param devmod Pointer to demodulator instance.
  8712. * \param sig_quality Pointer to signal quality data.
  8713. * \return int.
  8714. * \retval 0 sig_quality contains valid data.
  8715. * \retval -EINVAL sig_quality is NULL.
  8716. * \retval -EIO Erroneous data, sig_quality contains invalid data.
  8717. * Pre-condition: Device must be started and in lock.
  8718. */
  8719. static int
  8720. ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
  8721. {
  8722. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  8723. struct drxj_data *ext_attr = demod->my_ext_attr;
  8724. struct drx39xxj_state *state = dev_addr->user_data;
  8725. struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
  8726. struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
  8727. enum drx_modulation constellation = ext_attr->constellation;
  8728. int rc;
  8729. u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
  8730. u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
  8731. u32 pkt_errs = 0; /* no of packet errors in RS */
  8732. u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
  8733. u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
  8734. u16 fec_oc_period = 0; /* SNC sync failure measurement period */
  8735. u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
  8736. u16 fec_rs_period = 0; /* Value for corresponding I2C register */
  8737. /* calculation constants */
  8738. u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
  8739. u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
  8740. /* intermediate results */
  8741. u32 e = 0; /* exponent value used for QAM BER/SER */
  8742. u32 m = 0; /* mantisa value used for QAM BER/SER */
  8743. u32 ber_cnt = 0; /* BER count */
  8744. /* signal quality info */
  8745. u32 qam_sl_mer = 0; /* QAM MER */
  8746. u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
  8747. u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
  8748. u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
  8749. u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
  8750. u16 qam_vd_period = 0; /* Viterbi Measurement period */
  8751. u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
  8752. p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  8753. /* read the physical registers */
  8754. /* Get the RS error data */
  8755. rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
  8756. if (rc != 0) {
  8757. pr_err("error %d\n", rc);
  8758. goto rw_error;
  8759. }
  8760. /* get the register value needed for MER */
  8761. rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
  8762. if (rc != 0) {
  8763. pr_err("error %d\n", rc);
  8764. goto rw_error;
  8765. }
  8766. /* get the register value needed for post RS BER */
  8767. rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
  8768. if (rc != 0) {
  8769. pr_err("error %d\n", rc);
  8770. goto rw_error;
  8771. }
  8772. /* get constants needed for signal quality calculation */
  8773. fec_rs_period = ext_attr->fec_rs_period;
  8774. fec_rs_prescale = ext_attr->fec_rs_prescale;
  8775. rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
  8776. qam_vd_period = ext_attr->qam_vd_period;
  8777. qam_vd_prescale = ext_attr->qam_vd_prescale;
  8778. vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
  8779. /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
  8780. switch (constellation) {
  8781. case DRX_CONSTELLATION_QAM16:
  8782. qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
  8783. break;
  8784. case DRX_CONSTELLATION_QAM32:
  8785. qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
  8786. break;
  8787. case DRX_CONSTELLATION_QAM64:
  8788. qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
  8789. break;
  8790. case DRX_CONSTELLATION_QAM128:
  8791. qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
  8792. break;
  8793. case DRX_CONSTELLATION_QAM256:
  8794. qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
  8795. break;
  8796. default:
  8797. return -EIO;
  8798. }
  8799. /* ------------------------------ */
  8800. /* MER Calculation */
  8801. /* ------------------------------ */
  8802. /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
  8803. /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
  8804. if (qam_sl_err_power == 0)
  8805. qam_sl_mer = 0;
  8806. else
  8807. qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
  8808. /* ----------------------------------------- */
  8809. /* Pre Viterbi Symbol Error Rate Calculation */
  8810. /* ----------------------------------------- */
  8811. /* pre viterbi SER is good if it is below 0.025 */
  8812. /* get the register value */
  8813. /* no of quadrature symbol errors */
  8814. rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
  8815. if (rc != 0) {
  8816. pr_err("error %d\n", rc);
  8817. goto rw_error;
  8818. }
  8819. /* Extract the Exponent and the Mantisa */
  8820. /* of number of quadrature symbol errors */
  8821. e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
  8822. QAM_VD_NR_QSYM_ERRORS_EXP__B;
  8823. m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
  8824. QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
  8825. if ((m << e) >> 3 > 549752)
  8826. qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
  8827. else
  8828. qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
  8829. /* --------------------------------------- */
  8830. /* pre and post RedSolomon BER Calculation */
  8831. /* --------------------------------------- */
  8832. /* pre RS BER is good if it is below 3.5e-4 */
  8833. /* get the register values */
  8834. pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
  8835. pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
  8836. /* Extract the Exponent and the Mantisa of the */
  8837. /* pre Reed-Solomon bit error count */
  8838. e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
  8839. FEC_RS_NR_BIT_ERRORS_EXP__B;
  8840. m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
  8841. FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
  8842. ber_cnt = m << e;
  8843. /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
  8844. if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
  8845. qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
  8846. else
  8847. qam_pre_rs_ber = ber_cnt;
  8848. /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
  8849. /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
  8850. /*
  8851. => c = (1000000*100*11.17)/1504 =
  8852. post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
  8853. (100 * FEC_OC_SNC_FAIL_PERIOD__A)
  8854. *100 and /100 is for more precision.
  8855. => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
  8856. Precision errors still possible.
  8857. */
  8858. e = post_bit_err_rs * 742686;
  8859. m = fec_oc_period * 100;
  8860. if (fec_oc_period == 0)
  8861. qam_post_rs_ber = 0xFFFFFFFF;
  8862. else
  8863. qam_post_rs_ber = e / m;
  8864. /* fill signal quality data structure */
  8865. p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
  8866. p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
  8867. p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
  8868. p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
  8869. p->block_error.stat[0].scale = FE_SCALE_COUNTER;
  8870. p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
  8871. p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
  8872. if (ext_attr->standard == DRX_STANDARD_ITU_B) {
  8873. p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
  8874. p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
  8875. } else {
  8876. p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
  8877. p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
  8878. }
  8879. p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
  8880. p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
  8881. p->block_error.stat[0].uvalue += pkt_errs;
  8882. #ifdef DRXJ_SIGNAL_ACCUM_ERR
  8883. rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
  8884. if (rc != 0) {
  8885. pr_err("error %d\n", rc);
  8886. goto rw_error;
  8887. }
  8888. #endif
  8889. return 0;
  8890. rw_error:
  8891. p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  8892. p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  8893. p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  8894. p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  8895. p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  8896. p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  8897. return rc;
  8898. }
  8899. #endif /* #ifndef DRXJ_VSB_ONLY */
  8900. /*============================================================================*/
  8901. /*== END QAM DATAPATH FUNCTIONS ==*/
  8902. /*============================================================================*/
  8903. /*============================================================================*/
  8904. /*============================================================================*/
  8905. /*== ATV DATAPATH FUNCTIONS ==*/
  8906. /*============================================================================*/
  8907. /*============================================================================*/
  8908. /*
  8909. Implementation notes.
  8910. NTSC/FM AGCs
  8911. Four AGCs are used for NTSC:
  8912. (1) RF (used to attenuate the input signal in case of to much power)
  8913. (2) IF (used to attenuate the input signal in case of to much power)
  8914. (3) Video AGC (used to amplify the output signal in case input to low)
  8915. (4) SIF AGC (used to amplify the output signal in case input to low)
  8916. Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
  8917. that the coupling between Video AGC and the RF and IF AGCs also works in
  8918. favor of the SIF AGC.
  8919. Three AGCs are used for FM:
  8920. (1) RF (used to attenuate the input signal in case of to much power)
  8921. (2) IF (used to attenuate the input signal in case of to much power)
  8922. (3) SIF AGC (used to amplify the output signal in case input to low)
  8923. The SIF AGC is now coupled to the RF/IF AGCs.
  8924. The SIF AGC is needed for both SIF ouput and the internal SIF signal to
  8925. the AUD block.
  8926. RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
  8927. the ATV block. The AGC control algorithms are all implemented in
  8928. microcode.
  8929. ATV SETTINGS
  8930. (Shadow settings will not be used for now, they will be implemented
  8931. later on because of the schedule)
  8932. Several HW/SCU "settings" can be used for ATV. The standard selection
  8933. will reset most of these settings. To avoid that the end user apllication
  8934. has to perform these settings each time the ATV or FM standards is
  8935. selected the driver will shadow these settings. This enables the end user
  8936. to perform the settings only once after a drx_open(). The driver must
  8937. write the shadow settings to HW/SCU incase:
  8938. ( setstandard FM/ATV) ||
  8939. ( settings have changed && FM/ATV standard is active)
  8940. The shadow settings will be stored in the device specific data container.
  8941. A set of flags will be defined to flag changes in shadow settings.
  8942. A routine will be implemented to write all changed shadow settings to
  8943. HW/SCU.
  8944. The "settings" will consist of: AGC settings, filter settings etc.
  8945. Disadvantage of use of shadow settings:
  8946. Direct changes in HW/SCU registers will not be reflected in the
  8947. shadow settings and these changes will be overwritten during a next
  8948. update. This can happen during evaluation. This will not be a problem
  8949. for normal customer usage.
  8950. */
  8951. /* -------------------------------------------------------------------------- */
  8952. /**
  8953. * \fn int power_down_atv ()
  8954. * \brief Power down ATV.
  8955. * \param demod instance of demodulator
  8956. * \param standard either NTSC or FM (sub strandard for ATV )
  8957. * \return int.
  8958. *
  8959. * Stops and thus resets ATV and IQM block
  8960. * SIF and CVBS ADC are powered down
  8961. * Calls audio power down
  8962. */
  8963. static int
  8964. power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
  8965. {
  8966. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  8967. struct drxjscu_cmd cmd_scu = { /* command */ 0,
  8968. /* parameter_len */ 0,
  8969. /* result_len */ 0,
  8970. /* *parameter */ NULL,
  8971. /* *result */ NULL
  8972. };
  8973. int rc;
  8974. u16 cmd_result = 0;
  8975. /* ATV NTSC */
  8976. /* Stop ATV SCU (will reset ATV and IQM hardware */
  8977. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
  8978. SCU_RAM_COMMAND_CMD_DEMOD_STOP;
  8979. cmd_scu.parameter_len = 0;
  8980. cmd_scu.result_len = 1;
  8981. cmd_scu.parameter = NULL;
  8982. cmd_scu.result = &cmd_result;
  8983. rc = scu_command(dev_addr, &cmd_scu);
  8984. if (rc != 0) {
  8985. pr_err("error %d\n", rc);
  8986. goto rw_error;
  8987. }
  8988. /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
  8989. rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
  8990. if (rc != 0) {
  8991. pr_err("error %d\n", rc);
  8992. goto rw_error;
  8993. }
  8994. rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
  8995. if (rc != 0) {
  8996. pr_err("error %d\n", rc);
  8997. goto rw_error;
  8998. }
  8999. if (primary) {
  9000. rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
  9001. if (rc != 0) {
  9002. pr_err("error %d\n", rc);
  9003. goto rw_error;
  9004. }
  9005. rc = set_iqm_af(demod, false);
  9006. if (rc != 0) {
  9007. pr_err("error %d\n", rc);
  9008. goto rw_error;
  9009. }
  9010. } else {
  9011. rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
  9012. if (rc != 0) {
  9013. pr_err("error %d\n", rc);
  9014. goto rw_error;
  9015. }
  9016. rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
  9017. if (rc != 0) {
  9018. pr_err("error %d\n", rc);
  9019. goto rw_error;
  9020. }
  9021. rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
  9022. if (rc != 0) {
  9023. pr_err("error %d\n", rc);
  9024. goto rw_error;
  9025. }
  9026. rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
  9027. if (rc != 0) {
  9028. pr_err("error %d\n", rc);
  9029. goto rw_error;
  9030. }
  9031. rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
  9032. if (rc != 0) {
  9033. pr_err("error %d\n", rc);
  9034. goto rw_error;
  9035. }
  9036. }
  9037. rc = power_down_aud(demod);
  9038. if (rc != 0) {
  9039. pr_err("error %d\n", rc);
  9040. goto rw_error;
  9041. }
  9042. return 0;
  9043. rw_error:
  9044. return rc;
  9045. }
  9046. /*============================================================================*/
  9047. /**
  9048. * \brief Power up AUD.
  9049. * \param demod instance of demodulator
  9050. * \return int.
  9051. *
  9052. */
  9053. static int power_down_aud(struct drx_demod_instance *demod)
  9054. {
  9055. struct i2c_device_addr *dev_addr = NULL;
  9056. struct drxj_data *ext_attr = NULL;
  9057. int rc;
  9058. dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
  9059. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  9060. rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
  9061. if (rc != 0) {
  9062. pr_err("error %d\n", rc);
  9063. goto rw_error;
  9064. }
  9065. ext_attr->aud_data.audio_is_active = false;
  9066. return 0;
  9067. rw_error:
  9068. return rc;
  9069. }
  9070. /**
  9071. * \fn int set_orx_nsu_aox()
  9072. * \brief Configure OrxNsuAox for OOB
  9073. * \param demod instance of demodulator.
  9074. * \param active
  9075. * \return int.
  9076. */
  9077. static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
  9078. {
  9079. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  9080. int rc;
  9081. u16 data = 0;
  9082. /* Configure NSU_AOX */
  9083. rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
  9084. if (rc != 0) {
  9085. pr_err("error %d\n", rc);
  9086. goto rw_error;
  9087. }
  9088. if (!active)
  9089. data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
  9090. else
  9091. data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
  9092. rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
  9093. if (rc != 0) {
  9094. pr_err("error %d\n", rc);
  9095. goto rw_error;
  9096. }
  9097. return 0;
  9098. rw_error:
  9099. return rc;
  9100. }
  9101. /**
  9102. * \fn int ctrl_set_oob()
  9103. * \brief Set OOB channel to be used.
  9104. * \param demod instance of demodulator
  9105. * \param oob_param OOB parameters for channel setting.
  9106. * \frequency should be in KHz
  9107. * \return int.
  9108. *
  9109. * Accepts only. Returns error otherwise.
  9110. * Demapper value is written after scu_command START
  9111. * because START command causes COMM_EXEC transition
  9112. * from 0 to 1 which causes all registers to be
  9113. * overwritten with initial value
  9114. *
  9115. */
  9116. /* Nyquist filter impulse response */
  9117. #define IMPULSE_COSINE_ALPHA_0_3 {-3, -4, -1, 6, 10, 7, -5, -20, -25, -10, 29, 79, 123, 140} /*sqrt raised-cosine filter with alpha=0.3 */
  9118. #define IMPULSE_COSINE_ALPHA_0_5 { 2, 0, -2, -2, 2, 5, 2, -10, -20, -14, 20, 74, 125, 145} /*sqrt raised-cosine filter with alpha=0.5 */
  9119. #define IMPULSE_COSINE_ALPHA_RO_0_5 { 0, 0, 1, 2, 3, 0, -7, -15, -16, 0, 34, 77, 114, 128} /*full raised-cosine filter with alpha=0.5 (receiver only) */
  9120. /* Coefficients for the nyquist fitler (total: 27 taps) */
  9121. #define NYQFILTERLEN 27
  9122. static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
  9123. {
  9124. int rc;
  9125. s32 freq = 0; /* KHz */
  9126. struct i2c_device_addr *dev_addr = NULL;
  9127. struct drxj_data *ext_attr = NULL;
  9128. u16 i = 0;
  9129. bool mirror_freq_spect_oob = false;
  9130. u16 trk_filter_value = 0;
  9131. struct drxjscu_cmd scu_cmd;
  9132. u16 set_param_parameters[3];
  9133. u16 cmd_result[2] = { 0, 0 };
  9134. s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
  9135. IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
  9136. IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
  9137. IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
  9138. IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
  9139. };
  9140. u8 mode_val[4] = { 2, 2, 0, 1 };
  9141. u8 pfi_coeffs[4][6] = {
  9142. {DRXJ_16TO8(-92), DRXJ_16TO8(-108), DRXJ_16TO8(100)}, /* TARGET_MODE = 0: PFI_A = -23/32; PFI_B = -54/32; PFI_C = 25/32; fg = 0.5 MHz (Att=26dB) */
  9143. {DRXJ_16TO8(-64), DRXJ_16TO8(-80), DRXJ_16TO8(80)}, /* TARGET_MODE = 1: PFI_A = -16/32; PFI_B = -40/32; PFI_C = 20/32; fg = 1.0 MHz (Att=28dB) */
  9144. {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}, /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
  9145. {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)} /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
  9146. };
  9147. u16 mode_index;
  9148. dev_addr = demod->my_i2c_dev_addr;
  9149. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  9150. mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
  9151. /* Check parameters */
  9152. if (oob_param == NULL) {
  9153. /* power off oob module */
  9154. scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
  9155. | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
  9156. scu_cmd.parameter_len = 0;
  9157. scu_cmd.result_len = 1;
  9158. scu_cmd.result = cmd_result;
  9159. rc = scu_command(dev_addr, &scu_cmd);
  9160. if (rc != 0) {
  9161. pr_err("error %d\n", rc);
  9162. goto rw_error;
  9163. }
  9164. rc = set_orx_nsu_aox(demod, false);
  9165. if (rc != 0) {
  9166. pr_err("error %d\n", rc);
  9167. goto rw_error;
  9168. }
  9169. rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
  9170. if (rc != 0) {
  9171. pr_err("error %d\n", rc);
  9172. goto rw_error;
  9173. }
  9174. ext_attr->oob_power_on = false;
  9175. return 0;
  9176. }
  9177. freq = oob_param->frequency;
  9178. if ((freq < 70000) || (freq > 130000))
  9179. return -EIO;
  9180. freq = (freq - 50000) / 50;
  9181. {
  9182. u16 index = 0;
  9183. u16 remainder = 0;
  9184. u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
  9185. index = (u16) ((freq - 400) / 200);
  9186. remainder = (u16) ((freq - 400) % 200);
  9187. trk_filter_value =
  9188. trk_filtercfg[index] - (trk_filtercfg[index] -
  9189. trk_filtercfg[index +
  9190. 1]) / 10 * remainder /
  9191. 20;
  9192. }
  9193. /*********/
  9194. /* Stop */
  9195. /*********/
  9196. rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
  9197. if (rc != 0) {
  9198. pr_err("error %d\n", rc);
  9199. goto rw_error;
  9200. }
  9201. scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
  9202. | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
  9203. scu_cmd.parameter_len = 0;
  9204. scu_cmd.result_len = 1;
  9205. scu_cmd.result = cmd_result;
  9206. rc = scu_command(dev_addr, &scu_cmd);
  9207. if (rc != 0) {
  9208. pr_err("error %d\n", rc);
  9209. goto rw_error;
  9210. }
  9211. /*********/
  9212. /* Reset */
  9213. /*********/
  9214. scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
  9215. | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
  9216. scu_cmd.parameter_len = 0;
  9217. scu_cmd.result_len = 1;
  9218. scu_cmd.result = cmd_result;
  9219. rc = scu_command(dev_addr, &scu_cmd);
  9220. if (rc != 0) {
  9221. pr_err("error %d\n", rc);
  9222. goto rw_error;
  9223. }
  9224. /***********/
  9225. /* SET_ENV */
  9226. /***********/
  9227. /* set frequency, spectrum inversion and data rate */
  9228. scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
  9229. | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
  9230. scu_cmd.parameter_len = 3;
  9231. /* 1-data rate;2-frequency */
  9232. switch (oob_param->standard) {
  9233. case DRX_OOB_MODE_A:
  9234. if (
  9235. /* signal is transmitted inverted */
  9236. ((oob_param->spectrum_inverted == true) &&
  9237. /* and tuner is not mirroring the signal */
  9238. (!mirror_freq_spect_oob)) |
  9239. /* or */
  9240. /* signal is transmitted noninverted */
  9241. ((oob_param->spectrum_inverted == false) &&
  9242. /* and tuner is mirroring the signal */
  9243. (mirror_freq_spect_oob))
  9244. )
  9245. set_param_parameters[0] =
  9246. SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
  9247. else
  9248. set_param_parameters[0] =
  9249. SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
  9250. break;
  9251. case DRX_OOB_MODE_B_GRADE_A:
  9252. if (
  9253. /* signal is transmitted inverted */
  9254. ((oob_param->spectrum_inverted == true) &&
  9255. /* and tuner is not mirroring the signal */
  9256. (!mirror_freq_spect_oob)) |
  9257. /* or */
  9258. /* signal is transmitted noninverted */
  9259. ((oob_param->spectrum_inverted == false) &&
  9260. /* and tuner is mirroring the signal */
  9261. (mirror_freq_spect_oob))
  9262. )
  9263. set_param_parameters[0] =
  9264. SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
  9265. else
  9266. set_param_parameters[0] =
  9267. SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
  9268. break;
  9269. case DRX_OOB_MODE_B_GRADE_B:
  9270. default:
  9271. if (
  9272. /* signal is transmitted inverted */
  9273. ((oob_param->spectrum_inverted == true) &&
  9274. /* and tuner is not mirroring the signal */
  9275. (!mirror_freq_spect_oob)) |
  9276. /* or */
  9277. /* signal is transmitted noninverted */
  9278. ((oob_param->spectrum_inverted == false) &&
  9279. /* and tuner is mirroring the signal */
  9280. (mirror_freq_spect_oob))
  9281. )
  9282. set_param_parameters[0] =
  9283. SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
  9284. else
  9285. set_param_parameters[0] =
  9286. SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
  9287. break;
  9288. }
  9289. set_param_parameters[1] = (u16) (freq & 0xFFFF);
  9290. set_param_parameters[2] = trk_filter_value;
  9291. scu_cmd.parameter = set_param_parameters;
  9292. scu_cmd.result_len = 1;
  9293. scu_cmd.result = cmd_result;
  9294. mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
  9295. rc = scu_command(dev_addr, &scu_cmd);
  9296. if (rc != 0) {
  9297. pr_err("error %d\n", rc);
  9298. goto rw_error;
  9299. }
  9300. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
  9301. if (rc != 0) {
  9302. pr_err("error %d\n", rc);
  9303. goto rw_error;
  9304. } /* Write magic word to enable pdr reg write */
  9305. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
  9306. if (rc != 0) {
  9307. pr_err("error %d\n", rc);
  9308. goto rw_error;
  9309. }
  9310. rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
  9311. if (rc != 0) {
  9312. pr_err("error %d\n", rc);
  9313. goto rw_error;
  9314. }
  9315. rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
  9316. if (rc != 0) {
  9317. pr_err("error %d\n", rc);
  9318. goto rw_error;
  9319. } /* Write magic word to disable pdr reg write */
  9320. rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
  9321. if (rc != 0) {
  9322. pr_err("error %d\n", rc);
  9323. goto rw_error;
  9324. }
  9325. rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
  9326. if (rc != 0) {
  9327. pr_err("error %d\n", rc);
  9328. goto rw_error;
  9329. }
  9330. rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
  9331. if (rc != 0) {
  9332. pr_err("error %d\n", rc);
  9333. goto rw_error;
  9334. }
  9335. /* ddc */
  9336. rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
  9337. if (rc != 0) {
  9338. pr_err("error %d\n", rc);
  9339. goto rw_error;
  9340. }
  9341. /* nsu */
  9342. rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
  9343. if (rc != 0) {
  9344. pr_err("error %d\n", rc);
  9345. goto rw_error;
  9346. }
  9347. /* initialization for target mode */
  9348. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
  9349. if (rc != 0) {
  9350. pr_err("error %d\n", rc);
  9351. goto rw_error;
  9352. }
  9353. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
  9354. if (rc != 0) {
  9355. pr_err("error %d\n", rc);
  9356. goto rw_error;
  9357. }
  9358. /* Reset bits for timing and freq. recovery */
  9359. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
  9360. if (rc != 0) {
  9361. pr_err("error %d\n", rc);
  9362. goto rw_error;
  9363. }
  9364. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
  9365. if (rc != 0) {
  9366. pr_err("error %d\n", rc);
  9367. goto rw_error;
  9368. }
  9369. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
  9370. if (rc != 0) {
  9371. pr_err("error %d\n", rc);
  9372. goto rw_error;
  9373. }
  9374. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
  9375. if (rc != 0) {
  9376. pr_err("error %d\n", rc);
  9377. goto rw_error;
  9378. }
  9379. /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
  9380. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
  9381. if (rc != 0) {
  9382. pr_err("error %d\n", rc);
  9383. goto rw_error;
  9384. }
  9385. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
  9386. if (rc != 0) {
  9387. pr_err("error %d\n", rc);
  9388. goto rw_error;
  9389. }
  9390. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
  9391. if (rc != 0) {
  9392. pr_err("error %d\n", rc);
  9393. goto rw_error;
  9394. }
  9395. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
  9396. if (rc != 0) {
  9397. pr_err("error %d\n", rc);
  9398. goto rw_error;
  9399. }
  9400. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
  9401. if (rc != 0) {
  9402. pr_err("error %d\n", rc);
  9403. goto rw_error;
  9404. }
  9405. /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
  9406. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
  9407. if (rc != 0) {
  9408. pr_err("error %d\n", rc);
  9409. goto rw_error;
  9410. }
  9411. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
  9412. if (rc != 0) {
  9413. pr_err("error %d\n", rc);
  9414. goto rw_error;
  9415. }
  9416. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
  9417. if (rc != 0) {
  9418. pr_err("error %d\n", rc);
  9419. goto rw_error;
  9420. }
  9421. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
  9422. if (rc != 0) {
  9423. pr_err("error %d\n", rc);
  9424. goto rw_error;
  9425. }
  9426. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
  9427. if (rc != 0) {
  9428. pr_err("error %d\n", rc);
  9429. goto rw_error;
  9430. }
  9431. /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
  9432. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
  9433. if (rc != 0) {
  9434. pr_err("error %d\n", rc);
  9435. goto rw_error;
  9436. }
  9437. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
  9438. if (rc != 0) {
  9439. pr_err("error %d\n", rc);
  9440. goto rw_error;
  9441. }
  9442. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
  9443. if (rc != 0) {
  9444. pr_err("error %d\n", rc);
  9445. goto rw_error;
  9446. }
  9447. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
  9448. if (rc != 0) {
  9449. pr_err("error %d\n", rc);
  9450. goto rw_error;
  9451. }
  9452. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
  9453. if (rc != 0) {
  9454. pr_err("error %d\n", rc);
  9455. goto rw_error;
  9456. }
  9457. /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
  9458. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
  9459. if (rc != 0) {
  9460. pr_err("error %d\n", rc);
  9461. goto rw_error;
  9462. }
  9463. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
  9464. if (rc != 0) {
  9465. pr_err("error %d\n", rc);
  9466. goto rw_error;
  9467. }
  9468. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
  9469. if (rc != 0) {
  9470. pr_err("error %d\n", rc);
  9471. goto rw_error;
  9472. }
  9473. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
  9474. if (rc != 0) {
  9475. pr_err("error %d\n", rc);
  9476. goto rw_error;
  9477. }
  9478. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
  9479. if (rc != 0) {
  9480. pr_err("error %d\n", rc);
  9481. goto rw_error;
  9482. }
  9483. /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
  9484. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
  9485. if (rc != 0) {
  9486. pr_err("error %d\n", rc);
  9487. goto rw_error;
  9488. }
  9489. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
  9490. if (rc != 0) {
  9491. pr_err("error %d\n", rc);
  9492. goto rw_error;
  9493. }
  9494. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
  9495. if (rc != 0) {
  9496. pr_err("error %d\n", rc);
  9497. goto rw_error;
  9498. }
  9499. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
  9500. if (rc != 0) {
  9501. pr_err("error %d\n", rc);
  9502. goto rw_error;
  9503. }
  9504. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
  9505. if (rc != 0) {
  9506. pr_err("error %d\n", rc);
  9507. goto rw_error;
  9508. }
  9509. /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
  9510. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
  9511. if (rc != 0) {
  9512. pr_err("error %d\n", rc);
  9513. goto rw_error;
  9514. }
  9515. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
  9516. if (rc != 0) {
  9517. pr_err("error %d\n", rc);
  9518. goto rw_error;
  9519. }
  9520. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
  9521. if (rc != 0) {
  9522. pr_err("error %d\n", rc);
  9523. goto rw_error;
  9524. }
  9525. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
  9526. if (rc != 0) {
  9527. pr_err("error %d\n", rc);
  9528. goto rw_error;
  9529. }
  9530. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
  9531. if (rc != 0) {
  9532. pr_err("error %d\n", rc);
  9533. goto rw_error;
  9534. }
  9535. /* PRE-Filter coefficients (PFI) */
  9536. rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
  9537. if (rc != 0) {
  9538. pr_err("error %d\n", rc);
  9539. goto rw_error;
  9540. }
  9541. rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
  9542. if (rc != 0) {
  9543. pr_err("error %d\n", rc);
  9544. goto rw_error;
  9545. }
  9546. /* NYQUIST-Filter coefficients (NYQ) */
  9547. for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
  9548. rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
  9549. if (rc != 0) {
  9550. pr_err("error %d\n", rc);
  9551. goto rw_error;
  9552. }
  9553. rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
  9554. if (rc != 0) {
  9555. pr_err("error %d\n", rc);
  9556. goto rw_error;
  9557. }
  9558. }
  9559. rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
  9560. if (rc != 0) {
  9561. pr_err("error %d\n", rc);
  9562. goto rw_error;
  9563. }
  9564. rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
  9565. if (rc != 0) {
  9566. pr_err("error %d\n", rc);
  9567. goto rw_error;
  9568. }
  9569. /*********/
  9570. /* Start */
  9571. /*********/
  9572. scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
  9573. | SCU_RAM_COMMAND_CMD_DEMOD_START;
  9574. scu_cmd.parameter_len = 0;
  9575. scu_cmd.result_len = 1;
  9576. scu_cmd.result = cmd_result;
  9577. rc = scu_command(dev_addr, &scu_cmd);
  9578. if (rc != 0) {
  9579. pr_err("error %d\n", rc);
  9580. goto rw_error;
  9581. }
  9582. rc = set_orx_nsu_aox(demod, true);
  9583. if (rc != 0) {
  9584. pr_err("error %d\n", rc);
  9585. goto rw_error;
  9586. }
  9587. rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
  9588. if (rc != 0) {
  9589. pr_err("error %d\n", rc);
  9590. goto rw_error;
  9591. }
  9592. ext_attr->oob_power_on = true;
  9593. return 0;
  9594. rw_error:
  9595. return rc;
  9596. }
  9597. /*============================================================================*/
  9598. /*== END OOB DATAPATH FUNCTIONS ==*/
  9599. /*============================================================================*/
  9600. /*=============================================================================
  9601. ===== MC command related functions ==========================================
  9602. ===========================================================================*/
  9603. /*=============================================================================
  9604. ===== ctrl_set_channel() ==========================================================
  9605. ===========================================================================*/
  9606. /**
  9607. * \fn int ctrl_set_channel()
  9608. * \brief Select a new transmission channel.
  9609. * \param demod instance of demod.
  9610. * \param channel Pointer to channel data.
  9611. * \return int.
  9612. *
  9613. * In case the tuner module is not used and in case of NTSC/FM the pogrammer
  9614. * must tune the tuner to the centre frequency of the NTSC/FM channel.
  9615. *
  9616. */
  9617. static int
  9618. ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
  9619. {
  9620. int rc;
  9621. s32 tuner_freq_offset = 0;
  9622. struct drxj_data *ext_attr = NULL;
  9623. struct i2c_device_addr *dev_addr = NULL;
  9624. enum drx_standard standard = DRX_STANDARD_UNKNOWN;
  9625. #ifndef DRXJ_VSB_ONLY
  9626. u32 min_symbol_rate = 0;
  9627. u32 max_symbol_rate = 0;
  9628. int bandwidth_temp = 0;
  9629. int bandwidth = 0;
  9630. #endif
  9631. /*== check arguments ======================================================*/
  9632. if ((demod == NULL) || (channel == NULL))
  9633. return -EINVAL;
  9634. dev_addr = demod->my_i2c_dev_addr;
  9635. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  9636. standard = ext_attr->standard;
  9637. /* check valid standards */
  9638. switch (standard) {
  9639. case DRX_STANDARD_8VSB:
  9640. #ifndef DRXJ_VSB_ONLY
  9641. case DRX_STANDARD_ITU_A:
  9642. case DRX_STANDARD_ITU_B:
  9643. case DRX_STANDARD_ITU_C:
  9644. #endif /* DRXJ_VSB_ONLY */
  9645. break;
  9646. case DRX_STANDARD_UNKNOWN:
  9647. default:
  9648. return -EINVAL;
  9649. }
  9650. /* check bandwidth QAM annex B, NTSC and 8VSB */
  9651. if ((standard == DRX_STANDARD_ITU_B) ||
  9652. (standard == DRX_STANDARD_8VSB) ||
  9653. (standard == DRX_STANDARD_NTSC)) {
  9654. switch (channel->bandwidth) {
  9655. case DRX_BANDWIDTH_6MHZ:
  9656. case DRX_BANDWIDTH_UNKNOWN: /* fall through */
  9657. channel->bandwidth = DRX_BANDWIDTH_6MHZ;
  9658. break;
  9659. case DRX_BANDWIDTH_8MHZ: /* fall through */
  9660. case DRX_BANDWIDTH_7MHZ: /* fall through */
  9661. default:
  9662. return -EINVAL;
  9663. }
  9664. }
  9665. /* For QAM annex A and annex C:
  9666. -check symbolrate and constellation
  9667. -derive bandwidth from symbolrate (input bandwidth is ignored)
  9668. */
  9669. #ifndef DRXJ_VSB_ONLY
  9670. if ((standard == DRX_STANDARD_ITU_A) ||
  9671. (standard == DRX_STANDARD_ITU_C)) {
  9672. struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
  9673. int bw_rolloff_factor = 0;
  9674. bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
  9675. min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
  9676. max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
  9677. /* config SMA_TX pin to SAW switch mode */
  9678. rc = ctrl_set_uio_cfg(demod, &uio_cfg);
  9679. if (rc != 0) {
  9680. pr_err("error %d\n", rc);
  9681. goto rw_error;
  9682. }
  9683. if (channel->symbolrate < min_symbol_rate ||
  9684. channel->symbolrate > max_symbol_rate) {
  9685. return -EINVAL;
  9686. }
  9687. switch (channel->constellation) {
  9688. case DRX_CONSTELLATION_QAM16: /* fall through */
  9689. case DRX_CONSTELLATION_QAM32: /* fall through */
  9690. case DRX_CONSTELLATION_QAM64: /* fall through */
  9691. case DRX_CONSTELLATION_QAM128: /* fall through */
  9692. case DRX_CONSTELLATION_QAM256:
  9693. bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
  9694. bandwidth = bandwidth_temp / 100;
  9695. if ((bandwidth_temp % 100) >= 50)
  9696. bandwidth++;
  9697. if (bandwidth <= 6100000) {
  9698. channel->bandwidth = DRX_BANDWIDTH_6MHZ;
  9699. } else if ((bandwidth > 6100000)
  9700. && (bandwidth <= 7100000)) {
  9701. channel->bandwidth = DRX_BANDWIDTH_7MHZ;
  9702. } else if (bandwidth > 7100000) {
  9703. channel->bandwidth = DRX_BANDWIDTH_8MHZ;
  9704. }
  9705. break;
  9706. default:
  9707. return -EINVAL;
  9708. }
  9709. }
  9710. /* For QAM annex B:
  9711. -check constellation
  9712. */
  9713. if (standard == DRX_STANDARD_ITU_B) {
  9714. switch (channel->constellation) {
  9715. case DRX_CONSTELLATION_AUTO:
  9716. case DRX_CONSTELLATION_QAM256:
  9717. case DRX_CONSTELLATION_QAM64:
  9718. break;
  9719. default:
  9720. return -EINVAL;
  9721. }
  9722. switch (channel->interleavemode) {
  9723. case DRX_INTERLEAVEMODE_I128_J1:
  9724. case DRX_INTERLEAVEMODE_I128_J1_V2:
  9725. case DRX_INTERLEAVEMODE_I128_J2:
  9726. case DRX_INTERLEAVEMODE_I64_J2:
  9727. case DRX_INTERLEAVEMODE_I128_J3:
  9728. case DRX_INTERLEAVEMODE_I32_J4:
  9729. case DRX_INTERLEAVEMODE_I128_J4:
  9730. case DRX_INTERLEAVEMODE_I16_J8:
  9731. case DRX_INTERLEAVEMODE_I128_J5:
  9732. case DRX_INTERLEAVEMODE_I8_J16:
  9733. case DRX_INTERLEAVEMODE_I128_J6:
  9734. case DRX_INTERLEAVEMODE_I128_J7:
  9735. case DRX_INTERLEAVEMODE_I128_J8:
  9736. case DRX_INTERLEAVEMODE_I12_J17:
  9737. case DRX_INTERLEAVEMODE_I5_J4:
  9738. case DRX_INTERLEAVEMODE_B52_M240:
  9739. case DRX_INTERLEAVEMODE_B52_M720:
  9740. case DRX_INTERLEAVEMODE_UNKNOWN:
  9741. case DRX_INTERLEAVEMODE_AUTO:
  9742. break;
  9743. default:
  9744. return -EINVAL;
  9745. }
  9746. }
  9747. if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
  9748. /* SAW SW, user UIO is used for switchable SAW */
  9749. struct drxuio_data uio1 = { DRX_UIO1, false };
  9750. switch (channel->bandwidth) {
  9751. case DRX_BANDWIDTH_8MHZ:
  9752. uio1.value = true;
  9753. break;
  9754. case DRX_BANDWIDTH_7MHZ:
  9755. uio1.value = false;
  9756. break;
  9757. case DRX_BANDWIDTH_6MHZ:
  9758. uio1.value = false;
  9759. break;
  9760. case DRX_BANDWIDTH_UNKNOWN:
  9761. default:
  9762. return -EINVAL;
  9763. }
  9764. rc = ctrl_uio_write(demod, &uio1);
  9765. if (rc != 0) {
  9766. pr_err("error %d\n", rc);
  9767. goto rw_error;
  9768. }
  9769. }
  9770. #endif /* DRXJ_VSB_ONLY */
  9771. rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
  9772. if (rc != 0) {
  9773. pr_err("error %d\n", rc);
  9774. goto rw_error;
  9775. }
  9776. tuner_freq_offset = 0;
  9777. /*== Setup demod for specific standard ====================================*/
  9778. switch (standard) {
  9779. case DRX_STANDARD_8VSB:
  9780. if (channel->mirror == DRX_MIRROR_AUTO)
  9781. ext_attr->mirror = DRX_MIRROR_NO;
  9782. else
  9783. ext_attr->mirror = channel->mirror;
  9784. rc = set_vsb(demod);
  9785. if (rc != 0) {
  9786. pr_err("error %d\n", rc);
  9787. goto rw_error;
  9788. }
  9789. rc = set_frequency(demod, channel, tuner_freq_offset);
  9790. if (rc != 0) {
  9791. pr_err("error %d\n", rc);
  9792. goto rw_error;
  9793. }
  9794. break;
  9795. #ifndef DRXJ_VSB_ONLY
  9796. case DRX_STANDARD_ITU_A: /* fallthrough */
  9797. case DRX_STANDARD_ITU_B: /* fallthrough */
  9798. case DRX_STANDARD_ITU_C:
  9799. rc = set_qam_channel(demod, channel, tuner_freq_offset);
  9800. if (rc != 0) {
  9801. pr_err("error %d\n", rc);
  9802. goto rw_error;
  9803. }
  9804. break;
  9805. #endif
  9806. case DRX_STANDARD_UNKNOWN:
  9807. default:
  9808. return -EIO;
  9809. }
  9810. /* flag the packet error counter reset */
  9811. ext_attr->reset_pkt_err_acc = true;
  9812. return 0;
  9813. rw_error:
  9814. return rc;
  9815. }
  9816. /*=============================================================================
  9817. ===== SigQuality() ==========================================================
  9818. ===========================================================================*/
  9819. /**
  9820. * \fn int ctrl_sig_quality()
  9821. * \brief Retrieve signal quality form device.
  9822. * \param devmod Pointer to demodulator instance.
  9823. * \param sig_quality Pointer to signal quality data.
  9824. * \return int.
  9825. * \retval 0 sig_quality contains valid data.
  9826. * \retval -EINVAL sig_quality is NULL.
  9827. * \retval -EIO Erroneous data, sig_quality contains invalid data.
  9828. */
  9829. static int
  9830. ctrl_sig_quality(struct drx_demod_instance *demod,
  9831. enum drx_lock_status lock_status)
  9832. {
  9833. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  9834. struct drxj_data *ext_attr = demod->my_ext_attr;
  9835. struct drx39xxj_state *state = dev_addr->user_data;
  9836. struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
  9837. enum drx_standard standard = ext_attr->standard;
  9838. int rc;
  9839. u32 ber, cnt, err, pkt;
  9840. u16 mer, strength = 0;
  9841. rc = get_sig_strength(demod, &strength);
  9842. if (rc < 0) {
  9843. pr_err("error getting signal strength %d\n", rc);
  9844. p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9845. } else {
  9846. p->strength.stat[0].scale = FE_SCALE_RELATIVE;
  9847. p->strength.stat[0].uvalue = 65535UL * strength/ 100;
  9848. }
  9849. switch (standard) {
  9850. case DRX_STANDARD_8VSB:
  9851. #ifdef DRXJ_SIGNAL_ACCUM_ERR
  9852. rc = get_acc_pkt_err(demod, &pkt);
  9853. if (rc != 0) {
  9854. pr_err("error %d\n", rc);
  9855. goto rw_error;
  9856. }
  9857. #endif
  9858. if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
  9859. p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9860. p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9861. p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9862. p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9863. p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9864. p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9865. p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9866. } else {
  9867. rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
  9868. if (rc != 0) {
  9869. pr_err("error %d getting UCB\n", rc);
  9870. p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9871. } else {
  9872. p->block_error.stat[0].scale = FE_SCALE_COUNTER;
  9873. p->block_error.stat[0].uvalue += err;
  9874. p->block_count.stat[0].scale = FE_SCALE_COUNTER;
  9875. p->block_count.stat[0].uvalue += pkt;
  9876. }
  9877. /* PostViterbi is compute in steps of 10^(-6) */
  9878. rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
  9879. if (rc != 0) {
  9880. pr_err("error %d getting pre-ber\n", rc);
  9881. p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9882. } else {
  9883. p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
  9884. p->pre_bit_error.stat[0].uvalue += ber;
  9885. p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
  9886. p->pre_bit_count.stat[0].uvalue += cnt;
  9887. }
  9888. rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
  9889. if (rc != 0) {
  9890. pr_err("error %d getting post-ber\n", rc);
  9891. p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9892. } else {
  9893. p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
  9894. p->post_bit_error.stat[0].uvalue += ber;
  9895. p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
  9896. p->post_bit_count.stat[0].uvalue += cnt;
  9897. }
  9898. rc = get_vsbmer(dev_addr, &mer);
  9899. if (rc != 0) {
  9900. pr_err("error %d getting MER\n", rc);
  9901. p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  9902. } else {
  9903. p->cnr.stat[0].svalue = mer * 100;
  9904. p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
  9905. }
  9906. }
  9907. break;
  9908. #ifndef DRXJ_VSB_ONLY
  9909. case DRX_STANDARD_ITU_A:
  9910. case DRX_STANDARD_ITU_B:
  9911. case DRX_STANDARD_ITU_C:
  9912. rc = ctrl_get_qam_sig_quality(demod);
  9913. if (rc != 0) {
  9914. pr_err("error %d\n", rc);
  9915. goto rw_error;
  9916. }
  9917. break;
  9918. #endif
  9919. default:
  9920. return -EIO;
  9921. }
  9922. return 0;
  9923. rw_error:
  9924. return rc;
  9925. }
  9926. /*============================================================================*/
  9927. /**
  9928. * \fn int ctrl_lock_status()
  9929. * \brief Retrieve lock status .
  9930. * \param dev_addr Pointer to demodulator device address.
  9931. * \param lock_stat Pointer to lock status structure.
  9932. * \return int.
  9933. *
  9934. */
  9935. static int
  9936. ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
  9937. {
  9938. enum drx_standard standard = DRX_STANDARD_UNKNOWN;
  9939. struct drxj_data *ext_attr = NULL;
  9940. struct i2c_device_addr *dev_addr = NULL;
  9941. struct drxjscu_cmd cmd_scu = { /* command */ 0,
  9942. /* parameter_len */ 0,
  9943. /* result_len */ 0,
  9944. /* *parameter */ NULL,
  9945. /* *result */ NULL
  9946. };
  9947. int rc;
  9948. u16 cmd_result[2] = { 0, 0 };
  9949. u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
  9950. /* check arguments */
  9951. if ((demod == NULL) || (lock_stat == NULL))
  9952. return -EINVAL;
  9953. dev_addr = demod->my_i2c_dev_addr;
  9954. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  9955. standard = ext_attr->standard;
  9956. *lock_stat = DRX_NOT_LOCKED;
  9957. /* define the SCU command code */
  9958. switch (standard) {
  9959. case DRX_STANDARD_8VSB:
  9960. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
  9961. SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
  9962. demod_lock |= 0x6;
  9963. break;
  9964. #ifndef DRXJ_VSB_ONLY
  9965. case DRX_STANDARD_ITU_A:
  9966. case DRX_STANDARD_ITU_B:
  9967. case DRX_STANDARD_ITU_C:
  9968. cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
  9969. SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
  9970. break;
  9971. #endif
  9972. case DRX_STANDARD_UNKNOWN: /* fallthrough */
  9973. default:
  9974. return -EIO;
  9975. }
  9976. /* define the SCU command parameters and execute the command */
  9977. cmd_scu.parameter_len = 0;
  9978. cmd_scu.result_len = 2;
  9979. cmd_scu.parameter = NULL;
  9980. cmd_scu.result = cmd_result;
  9981. rc = scu_command(dev_addr, &cmd_scu);
  9982. if (rc != 0) {
  9983. pr_err("error %d\n", rc);
  9984. goto rw_error;
  9985. }
  9986. /* set the lock status */
  9987. if (cmd_scu.result[1] < demod_lock) {
  9988. /* 0x0000 NOT LOCKED */
  9989. *lock_stat = DRX_NOT_LOCKED;
  9990. } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
  9991. *lock_stat = DRXJ_DEMOD_LOCK;
  9992. } else if (cmd_scu.result[1] <
  9993. SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
  9994. /* 0x8000 DEMOD + FEC LOCKED (system lock) */
  9995. *lock_stat = DRX_LOCKED;
  9996. } else {
  9997. /* 0xC000 NEVER LOCKED */
  9998. /* (system will never be able to lock to the signal) */
  9999. *lock_stat = DRX_NEVER_LOCK;
  10000. }
  10001. return 0;
  10002. rw_error:
  10003. return rc;
  10004. }
  10005. /*============================================================================*/
  10006. /**
  10007. * \fn int ctrl_set_standard()
  10008. * \brief Set modulation standard to be used.
  10009. * \param standard Modulation standard.
  10010. * \return int.
  10011. *
  10012. * Setup stuff for the desired demodulation standard.
  10013. * Disable and power down the previous selected demodulation standard
  10014. *
  10015. */
  10016. static int
  10017. ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
  10018. {
  10019. struct drxj_data *ext_attr = NULL;
  10020. int rc;
  10021. enum drx_standard prev_standard;
  10022. /* check arguments */
  10023. if ((standard == NULL) || (demod == NULL))
  10024. return -EINVAL;
  10025. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  10026. prev_standard = ext_attr->standard;
  10027. /*
  10028. Stop and power down previous standard
  10029. */
  10030. switch (prev_standard) {
  10031. #ifndef DRXJ_VSB_ONLY
  10032. case DRX_STANDARD_ITU_A: /* fallthrough */
  10033. case DRX_STANDARD_ITU_B: /* fallthrough */
  10034. case DRX_STANDARD_ITU_C:
  10035. rc = power_down_qam(demod, false);
  10036. if (rc != 0) {
  10037. pr_err("error %d\n", rc);
  10038. goto rw_error;
  10039. }
  10040. break;
  10041. #endif
  10042. case DRX_STANDARD_8VSB:
  10043. rc = power_down_vsb(demod, false);
  10044. if (rc != 0) {
  10045. pr_err("error %d\n", rc);
  10046. goto rw_error;
  10047. }
  10048. break;
  10049. case DRX_STANDARD_UNKNOWN:
  10050. /* Do nothing */
  10051. break;
  10052. case DRX_STANDARD_AUTO: /* fallthrough */
  10053. default:
  10054. return -EINVAL;
  10055. }
  10056. /*
  10057. Initialize channel independent registers
  10058. Power up new standard
  10059. */
  10060. ext_attr->standard = *standard;
  10061. switch (*standard) {
  10062. #ifndef DRXJ_VSB_ONLY
  10063. case DRX_STANDARD_ITU_A: /* fallthrough */
  10064. case DRX_STANDARD_ITU_B: /* fallthrough */
  10065. case DRX_STANDARD_ITU_C:
  10066. do {
  10067. u16 dummy;
  10068. rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
  10069. if (rc != 0) {
  10070. pr_err("error %d\n", rc);
  10071. goto rw_error;
  10072. }
  10073. } while (0);
  10074. break;
  10075. #endif
  10076. case DRX_STANDARD_8VSB:
  10077. rc = set_vsb_leak_n_gain(demod);
  10078. if (rc != 0) {
  10079. pr_err("error %d\n", rc);
  10080. goto rw_error;
  10081. }
  10082. break;
  10083. default:
  10084. ext_attr->standard = DRX_STANDARD_UNKNOWN;
  10085. return -EINVAL;
  10086. break;
  10087. }
  10088. return 0;
  10089. rw_error:
  10090. /* Don't know what the standard is now ... try again */
  10091. ext_attr->standard = DRX_STANDARD_UNKNOWN;
  10092. return rc;
  10093. }
  10094. /*============================================================================*/
  10095. static void drxj_reset_mode(struct drxj_data *ext_attr)
  10096. {
  10097. /* Initialize default AFE configuartion for QAM */
  10098. if (ext_attr->has_lna) {
  10099. /* IF AGC off, PGA active */
  10100. #ifndef DRXJ_VSB_ONLY
  10101. ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
  10102. ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
  10103. ext_attr->qam_pga_cfg = 140 + (11 * 13);
  10104. #endif
  10105. ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
  10106. ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
  10107. ext_attr->vsb_pga_cfg = 140 + (11 * 13);
  10108. } else {
  10109. /* IF AGC on, PGA not active */
  10110. #ifndef DRXJ_VSB_ONLY
  10111. ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
  10112. ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
  10113. ext_attr->qam_if_agc_cfg.min_output_level = 0;
  10114. ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
  10115. ext_attr->qam_if_agc_cfg.speed = 3;
  10116. ext_attr->qam_if_agc_cfg.top = 1297;
  10117. ext_attr->qam_pga_cfg = 140;
  10118. #endif
  10119. ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
  10120. ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
  10121. ext_attr->vsb_if_agc_cfg.min_output_level = 0;
  10122. ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
  10123. ext_attr->vsb_if_agc_cfg.speed = 3;
  10124. ext_attr->vsb_if_agc_cfg.top = 1024;
  10125. ext_attr->vsb_pga_cfg = 140;
  10126. }
  10127. /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
  10128. /* mc has not used them */
  10129. #ifndef DRXJ_VSB_ONLY
  10130. ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
  10131. ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
  10132. ext_attr->qam_rf_agc_cfg.min_output_level = 0;
  10133. ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
  10134. ext_attr->qam_rf_agc_cfg.speed = 3;
  10135. ext_attr->qam_rf_agc_cfg.top = 9500;
  10136. ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
  10137. ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
  10138. ext_attr->qam_pre_saw_cfg.reference = 0x07;
  10139. ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
  10140. #endif
  10141. /* Initialize default AFE configuartion for VSB */
  10142. ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
  10143. ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
  10144. ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
  10145. ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
  10146. ext_attr->vsb_rf_agc_cfg.speed = 3;
  10147. ext_attr->vsb_rf_agc_cfg.top = 9500;
  10148. ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
  10149. ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
  10150. ext_attr->vsb_pre_saw_cfg.reference = 0x07;
  10151. ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
  10152. }
  10153. /**
  10154. * \fn int ctrl_power_mode()
  10155. * \brief Set the power mode of the device to the specified power mode
  10156. * \param demod Pointer to demodulator instance.
  10157. * \param mode Pointer to new power mode.
  10158. * \return int.
  10159. * \retval 0 Success
  10160. * \retval -EIO I2C error or other failure
  10161. * \retval -EINVAL Invalid mode argument.
  10162. *
  10163. *
  10164. */
  10165. static int
  10166. ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
  10167. {
  10168. struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
  10169. struct drxj_data *ext_attr = (struct drxj_data *) NULL;
  10170. struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
  10171. int rc;
  10172. u16 sio_cc_pwd_mode = 0;
  10173. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  10174. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  10175. dev_addr = demod->my_i2c_dev_addr;
  10176. /* Check arguments */
  10177. if (mode == NULL)
  10178. return -EINVAL;
  10179. /* If already in requested power mode, do nothing */
  10180. if (common_attr->current_power_mode == *mode)
  10181. return 0;
  10182. switch (*mode) {
  10183. case DRX_POWER_UP:
  10184. case DRXJ_POWER_DOWN_MAIN_PATH:
  10185. sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
  10186. break;
  10187. case DRXJ_POWER_DOWN_CORE:
  10188. sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
  10189. break;
  10190. case DRXJ_POWER_DOWN_PLL:
  10191. sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
  10192. break;
  10193. case DRX_POWER_DOWN:
  10194. sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
  10195. break;
  10196. default:
  10197. /* Unknow sleep mode */
  10198. return -EINVAL;
  10199. break;
  10200. }
  10201. /* Check if device needs to be powered up */
  10202. if ((common_attr->current_power_mode != DRX_POWER_UP)) {
  10203. rc = power_up_device(demod);
  10204. if (rc != 0) {
  10205. pr_err("error %d\n", rc);
  10206. goto rw_error;
  10207. }
  10208. }
  10209. if ((*mode == DRX_POWER_UP)) {
  10210. /* Restore analog & pin configuartion */
  10211. /* Initialize default AFE configuartion for VSB */
  10212. drxj_reset_mode(ext_attr);
  10213. } else {
  10214. /* Power down to requested mode */
  10215. /* Backup some register settings */
  10216. /* Set pins with possible pull-ups connected to them in input mode */
  10217. /* Analog power down */
  10218. /* ADC power down */
  10219. /* Power down device */
  10220. /* stop all comm_exec */
  10221. /*
  10222. Stop and power down previous standard
  10223. */
  10224. switch (ext_attr->standard) {
  10225. case DRX_STANDARD_ITU_A:
  10226. case DRX_STANDARD_ITU_B:
  10227. case DRX_STANDARD_ITU_C:
  10228. rc = power_down_qam(demod, true);
  10229. if (rc != 0) {
  10230. pr_err("error %d\n", rc);
  10231. goto rw_error;
  10232. }
  10233. break;
  10234. case DRX_STANDARD_8VSB:
  10235. rc = power_down_vsb(demod, true);
  10236. if (rc != 0) {
  10237. pr_err("error %d\n", rc);
  10238. goto rw_error;
  10239. }
  10240. break;
  10241. case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
  10242. case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
  10243. case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
  10244. case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
  10245. case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
  10246. case DRX_STANDARD_NTSC: /* fallthrough */
  10247. case DRX_STANDARD_FM:
  10248. rc = power_down_atv(demod, ext_attr->standard, true);
  10249. if (rc != 0) {
  10250. pr_err("error %d\n", rc);
  10251. goto rw_error;
  10252. }
  10253. break;
  10254. case DRX_STANDARD_UNKNOWN:
  10255. /* Do nothing */
  10256. break;
  10257. case DRX_STANDARD_AUTO: /* fallthrough */
  10258. default:
  10259. return -EIO;
  10260. }
  10261. ext_attr->standard = DRX_STANDARD_UNKNOWN;
  10262. }
  10263. if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
  10264. rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
  10265. if (rc != 0) {
  10266. pr_err("error %d\n", rc);
  10267. goto rw_error;
  10268. }
  10269. rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
  10270. if (rc != 0) {
  10271. pr_err("error %d\n", rc);
  10272. goto rw_error;
  10273. }
  10274. if ((*mode != DRX_POWER_UP)) {
  10275. /* Initialize HI, wakeup key especially before put IC to sleep */
  10276. rc = init_hi(demod);
  10277. if (rc != 0) {
  10278. pr_err("error %d\n", rc);
  10279. goto rw_error;
  10280. }
  10281. ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
  10282. rc = hi_cfg_command(demod);
  10283. if (rc != 0) {
  10284. pr_err("error %d\n", rc);
  10285. goto rw_error;
  10286. }
  10287. }
  10288. }
  10289. common_attr->current_power_mode = *mode;
  10290. return 0;
  10291. rw_error:
  10292. return rc;
  10293. }
  10294. /*============================================================================*/
  10295. /*== CTRL Set/Get Config related functions ===================================*/
  10296. /*============================================================================*/
  10297. /**
  10298. * \fn int ctrl_set_cfg_pre_saw()
  10299. * \brief Set Pre-saw reference.
  10300. * \param demod demod instance
  10301. * \param u16 *
  10302. * \return int.
  10303. *
  10304. * Check arguments
  10305. * Dispatch handling to standard specific function.
  10306. *
  10307. */
  10308. static int
  10309. ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
  10310. {
  10311. struct i2c_device_addr *dev_addr = NULL;
  10312. struct drxj_data *ext_attr = NULL;
  10313. int rc;
  10314. dev_addr = demod->my_i2c_dev_addr;
  10315. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  10316. /* check arguments */
  10317. if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
  10318. ) {
  10319. return -EINVAL;
  10320. }
  10321. /* Only if standard is currently active */
  10322. if ((ext_attr->standard == pre_saw->standard) ||
  10323. (DRXJ_ISQAMSTD(ext_attr->standard) &&
  10324. DRXJ_ISQAMSTD(pre_saw->standard)) ||
  10325. (DRXJ_ISATVSTD(ext_attr->standard) &&
  10326. DRXJ_ISATVSTD(pre_saw->standard))) {
  10327. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
  10328. if (rc != 0) {
  10329. pr_err("error %d\n", rc);
  10330. goto rw_error;
  10331. }
  10332. }
  10333. /* Store pre-saw settings */
  10334. switch (pre_saw->standard) {
  10335. case DRX_STANDARD_8VSB:
  10336. ext_attr->vsb_pre_saw_cfg = *pre_saw;
  10337. break;
  10338. #ifndef DRXJ_VSB_ONLY
  10339. case DRX_STANDARD_ITU_A: /* fallthrough */
  10340. case DRX_STANDARD_ITU_B: /* fallthrough */
  10341. case DRX_STANDARD_ITU_C:
  10342. ext_attr->qam_pre_saw_cfg = *pre_saw;
  10343. break;
  10344. #endif
  10345. default:
  10346. return -EINVAL;
  10347. }
  10348. return 0;
  10349. rw_error:
  10350. return rc;
  10351. }
  10352. /*============================================================================*/
  10353. /**
  10354. * \fn int ctrl_set_cfg_afe_gain()
  10355. * \brief Set AFE Gain.
  10356. * \param demod demod instance
  10357. * \param u16 *
  10358. * \return int.
  10359. *
  10360. * Check arguments
  10361. * Dispatch handling to standard specific function.
  10362. *
  10363. */
  10364. static int
  10365. ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
  10366. {
  10367. struct i2c_device_addr *dev_addr = NULL;
  10368. struct drxj_data *ext_attr = NULL;
  10369. int rc;
  10370. u8 gain = 0;
  10371. /* check arguments */
  10372. if (afe_gain == NULL)
  10373. return -EINVAL;
  10374. dev_addr = demod->my_i2c_dev_addr;
  10375. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  10376. switch (afe_gain->standard) {
  10377. case DRX_STANDARD_8VSB: /* fallthrough */
  10378. #ifndef DRXJ_VSB_ONLY
  10379. case DRX_STANDARD_ITU_A: /* fallthrough */
  10380. case DRX_STANDARD_ITU_B: /* fallthrough */
  10381. case DRX_STANDARD_ITU_C:
  10382. #endif
  10383. /* Do nothing */
  10384. break;
  10385. default:
  10386. return -EINVAL;
  10387. }
  10388. /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
  10389. So I (PJ) think interface requires choice between auto, user mode */
  10390. if (afe_gain->gain >= 329)
  10391. gain = 15;
  10392. else if (afe_gain->gain <= 147)
  10393. gain = 0;
  10394. else
  10395. gain = (afe_gain->gain - 140 + 6) / 13;
  10396. /* Only if standard is currently active */
  10397. if (ext_attr->standard == afe_gain->standard) {
  10398. rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
  10399. if (rc != 0) {
  10400. pr_err("error %d\n", rc);
  10401. goto rw_error;
  10402. }
  10403. }
  10404. /* Store AFE Gain settings */
  10405. switch (afe_gain->standard) {
  10406. case DRX_STANDARD_8VSB:
  10407. ext_attr->vsb_pga_cfg = gain * 13 + 140;
  10408. break;
  10409. #ifndef DRXJ_VSB_ONLY
  10410. case DRX_STANDARD_ITU_A: /* fallthrough */
  10411. case DRX_STANDARD_ITU_B: /* fallthrough */
  10412. case DRX_STANDARD_ITU_C:
  10413. ext_attr->qam_pga_cfg = gain * 13 + 140;
  10414. break;
  10415. #endif
  10416. default:
  10417. return -EIO;
  10418. }
  10419. return 0;
  10420. rw_error:
  10421. return rc;
  10422. }
  10423. /*============================================================================*/
  10424. /*=============================================================================
  10425. ===== EXPORTED FUNCTIONS ====================================================*/
  10426. static int drx_ctrl_u_code(struct drx_demod_instance *demod,
  10427. struct drxu_code_info *mc_info,
  10428. enum drxu_code_action action);
  10429. static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
  10430. /**
  10431. * \fn drxj_open()
  10432. * \brief Open the demod instance, configure device, configure drxdriver
  10433. * \return Status_t Return status.
  10434. *
  10435. * drxj_open() can be called with a NULL ucode image => no ucode upload.
  10436. * This means that drxj_open() must NOT contain SCU commands or, in general,
  10437. * rely on SCU or AUD ucode to be present.
  10438. *
  10439. */
  10440. static int drxj_open(struct drx_demod_instance *demod)
  10441. {
  10442. struct i2c_device_addr *dev_addr = NULL;
  10443. struct drxj_data *ext_attr = NULL;
  10444. struct drx_common_attr *common_attr = NULL;
  10445. u32 driver_version = 0;
  10446. struct drxu_code_info ucode_info;
  10447. struct drx_cfg_mpeg_output cfg_mpeg_output;
  10448. int rc;
  10449. enum drx_power_mode power_mode = DRX_POWER_UP;
  10450. if ((demod == NULL) ||
  10451. (demod->my_common_attr == NULL) ||
  10452. (demod->my_ext_attr == NULL) ||
  10453. (demod->my_i2c_dev_addr == NULL) ||
  10454. (demod->my_common_attr->is_opened)) {
  10455. return -EINVAL;
  10456. }
  10457. /* Check arguments */
  10458. if (demod->my_ext_attr == NULL)
  10459. return -EINVAL;
  10460. dev_addr = demod->my_i2c_dev_addr;
  10461. ext_attr = (struct drxj_data *) demod->my_ext_attr;
  10462. common_attr = (struct drx_common_attr *) demod->my_common_attr;
  10463. rc = ctrl_power_mode(demod, &power_mode);
  10464. if (rc != 0) {
  10465. pr_err("error %d\n", rc);
  10466. goto rw_error;
  10467. }
  10468. if (power_mode != DRX_POWER_UP) {
  10469. rc = -EINVAL;
  10470. pr_err("failed to powerup device\n");
  10471. goto rw_error;
  10472. }
  10473. /* has to be in front of setIqmAf and setOrxNsuAox */
  10474. rc = get_device_capabilities(demod);
  10475. if (rc != 0) {
  10476. pr_err("error %d\n", rc);
  10477. goto rw_error;
  10478. }
  10479. /*
  10480. * Soft reset of sys- and osc-clockdomain
  10481. *
  10482. * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
  10483. * As we didn't load the firmware here yet, we should do the same.
  10484. * Btw, this is coherent with DRX-K, where we send reset codes
  10485. * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
  10486. */
  10487. rc = drxj_dap_write_reg16(dev_addr, SIO_CC_SOFT_RST__A, (0x04 | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
  10488. if (rc != 0) {
  10489. pr_err("error %d\n", rc);
  10490. goto rw_error;
  10491. }
  10492. rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
  10493. if (rc != 0) {
  10494. pr_err("error %d\n", rc);
  10495. goto rw_error;
  10496. }
  10497. msleep(1);
  10498. /* TODO first make sure that everything keeps working before enabling this */
  10499. /* PowerDownAnalogBlocks() */
  10500. rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
  10501. if (rc != 0) {
  10502. pr_err("error %d\n", rc);
  10503. goto rw_error;
  10504. }
  10505. rc = set_iqm_af(demod, false);
  10506. if (rc != 0) {
  10507. pr_err("error %d\n", rc);
  10508. goto rw_error;
  10509. }
  10510. rc = set_orx_nsu_aox(demod, false);
  10511. if (rc != 0) {
  10512. pr_err("error %d\n", rc);
  10513. goto rw_error;
  10514. }
  10515. rc = init_hi(demod);
  10516. if (rc != 0) {
  10517. pr_err("error %d\n", rc);
  10518. goto rw_error;
  10519. }
  10520. /* disable mpegoutput pins */
  10521. memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
  10522. cfg_mpeg_output.enable_mpeg_output = false;
  10523. rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
  10524. if (rc != 0) {
  10525. pr_err("error %d\n", rc);
  10526. goto rw_error;
  10527. }
  10528. /* Stop AUD Inform SetAudio it will need to do all setting */
  10529. rc = power_down_aud(demod);
  10530. if (rc != 0) {
  10531. pr_err("error %d\n", rc);
  10532. goto rw_error;
  10533. }
  10534. /* Stop SCU */
  10535. rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
  10536. if (rc != 0) {
  10537. pr_err("error %d\n", rc);
  10538. goto rw_error;
  10539. }
  10540. /* Upload microcode */
  10541. if (common_attr->microcode_file != NULL) {
  10542. /* Dirty trick to use common ucode upload & verify,
  10543. pretend device is already open */
  10544. common_attr->is_opened = true;
  10545. ucode_info.mc_file = common_attr->microcode_file;
  10546. if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
  10547. pr_err("Should powerup before loading the firmware.");
  10548. return -EINVAL;
  10549. }
  10550. rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
  10551. if (rc != 0) {
  10552. pr_err("error %d while uploading the firmware\n", rc);
  10553. goto rw_error;
  10554. }
  10555. if (common_attr->verify_microcode == true) {
  10556. rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);
  10557. if (rc != 0) {
  10558. pr_err("error %d while verifying the firmware\n",
  10559. rc);
  10560. goto rw_error;
  10561. }
  10562. }
  10563. common_attr->is_opened = false;
  10564. }
  10565. /* Run SCU for a little while to initialize microcode version numbers */
  10566. rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
  10567. if (rc != 0) {
  10568. pr_err("error %d\n", rc);
  10569. goto rw_error;
  10570. }
  10571. /* Initialize scan timeout */
  10572. common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
  10573. common_attr->scan_desired_lock = DRX_LOCKED;
  10574. drxj_reset_mode(ext_attr);
  10575. ext_attr->standard = DRX_STANDARD_UNKNOWN;
  10576. rc = smart_ant_init(demod);
  10577. if (rc != 0) {
  10578. pr_err("error %d\n", rc);
  10579. goto rw_error;
  10580. }
  10581. /* Stamp driver version number in SCU data RAM in BCD code
  10582. Done to enable field application engineers to retrieve drxdriver version
  10583. via I2C from SCU RAM
  10584. */
  10585. driver_version = (VERSION_MAJOR / 100) % 10;
  10586. driver_version <<= 4;
  10587. driver_version += (VERSION_MAJOR / 10) % 10;
  10588. driver_version <<= 4;
  10589. driver_version += (VERSION_MAJOR % 10);
  10590. driver_version <<= 4;
  10591. driver_version += (VERSION_MINOR % 10);
  10592. driver_version <<= 4;
  10593. driver_version += (VERSION_PATCH / 1000) % 10;
  10594. driver_version <<= 4;
  10595. driver_version += (VERSION_PATCH / 100) % 10;
  10596. driver_version <<= 4;
  10597. driver_version += (VERSION_PATCH / 10) % 10;
  10598. driver_version <<= 4;
  10599. driver_version += (VERSION_PATCH % 10);
  10600. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
  10601. if (rc != 0) {
  10602. pr_err("error %d\n", rc);
  10603. goto rw_error;
  10604. }
  10605. rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
  10606. if (rc != 0) {
  10607. pr_err("error %d\n", rc);
  10608. goto rw_error;
  10609. }
  10610. rc = ctrl_set_oob(demod, NULL);
  10611. if (rc != 0) {
  10612. pr_err("error %d\n", rc);
  10613. goto rw_error;
  10614. }
  10615. /* refresh the audio data structure with default */
  10616. ext_attr->aud_data = drxj_default_aud_data_g;
  10617. demod->my_common_attr->is_opened = true;
  10618. drxj_set_lna_state(demod, false);
  10619. return 0;
  10620. rw_error:
  10621. common_attr->is_opened = false;
  10622. return rc;
  10623. }
  10624. /*============================================================================*/
  10625. /**
  10626. * \fn drxj_close()
  10627. * \brief Close the demod instance, power down the device
  10628. * \return Status_t Return status.
  10629. *
  10630. */
  10631. static int drxj_close(struct drx_demod_instance *demod)
  10632. {
  10633. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  10634. int rc;
  10635. enum drx_power_mode power_mode = DRX_POWER_UP;
  10636. if ((demod->my_common_attr == NULL) ||
  10637. (demod->my_ext_attr == NULL) ||
  10638. (demod->my_i2c_dev_addr == NULL) ||
  10639. (!demod->my_common_attr->is_opened)) {
  10640. return -EINVAL;
  10641. }
  10642. /* power up */
  10643. rc = ctrl_power_mode(demod, &power_mode);
  10644. if (rc != 0) {
  10645. pr_err("error %d\n", rc);
  10646. goto rw_error;
  10647. }
  10648. rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
  10649. if (rc != 0) {
  10650. pr_err("error %d\n", rc);
  10651. goto rw_error;
  10652. }
  10653. power_mode = DRX_POWER_DOWN;
  10654. rc = ctrl_power_mode(demod, &power_mode);
  10655. if (rc != 0) {
  10656. pr_err("error %d\n", rc);
  10657. goto rw_error;
  10658. }
  10659. DRX_ATTR_ISOPENED(demod) = false;
  10660. return 0;
  10661. rw_error:
  10662. DRX_ATTR_ISOPENED(demod) = false;
  10663. return rc;
  10664. }
  10665. /*
  10666. * Microcode related functions
  10667. */
  10668. /**
  10669. * drx_u_code_compute_crc - Compute CRC of block of microcode data.
  10670. * @block_data: Pointer to microcode data.
  10671. * @nr_words: Size of microcode block (number of 16 bits words).
  10672. *
  10673. * returns The computed CRC residue.
  10674. */
  10675. static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
  10676. {
  10677. u16 i = 0;
  10678. u16 j = 0;
  10679. u32 crc_word = 0;
  10680. u32 carry = 0;
  10681. while (i < nr_words) {
  10682. crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
  10683. for (j = 0; j < 16; j++) {
  10684. crc_word <<= 1;
  10685. if (carry != 0)
  10686. crc_word ^= 0x80050000UL;
  10687. carry = crc_word & 0x80000000UL;
  10688. }
  10689. i++;
  10690. block_data += (sizeof(u16));
  10691. }
  10692. return (u16)(crc_word >> 16);
  10693. }
  10694. /**
  10695. * drx_check_firmware - checks if the loaded firmware is valid
  10696. *
  10697. * @demod: demod structure
  10698. * @mc_data: pointer to the start of the firmware
  10699. * @size: firmware size
  10700. */
  10701. static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
  10702. unsigned size)
  10703. {
  10704. struct drxu_code_block_hdr block_hdr;
  10705. int i;
  10706. unsigned count = 2 * sizeof(u16);
  10707. u32 mc_dev_type, mc_version, mc_base_version;
  10708. u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
  10709. /*
  10710. * Scan microcode blocks first for version info
  10711. * and firmware check
  10712. */
  10713. /* Clear version block */
  10714. DRX_ATTR_MCRECORD(demod).aux_type = 0;
  10715. DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
  10716. DRX_ATTR_MCRECORD(demod).mc_version = 0;
  10717. DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
  10718. for (i = 0; i < mc_nr_of_blks; i++) {
  10719. if (count + 3 * sizeof(u16) + sizeof(u32) > size)
  10720. goto eof;
  10721. /* Process block header */
  10722. block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
  10723. count += sizeof(u32);
  10724. block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
  10725. count += sizeof(u16);
  10726. block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
  10727. count += sizeof(u16);
  10728. block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
  10729. count += sizeof(u16);
  10730. pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
  10731. count, block_hdr.addr, block_hdr.size, block_hdr.flags,
  10732. block_hdr.CRC);
  10733. if (block_hdr.flags & 0x8) {
  10734. u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
  10735. u16 auxtype;
  10736. if (block_hdr.addr + sizeof(u16) > size)
  10737. goto eof;
  10738. auxtype = be16_to_cpu(*(__be16 *)(auxblk));
  10739. /* Aux block. Check type */
  10740. if (DRX_ISMCVERTYPE(auxtype)) {
  10741. if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
  10742. goto eof;
  10743. auxblk += sizeof(u16);
  10744. mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
  10745. auxblk += sizeof(u32);
  10746. mc_version = be32_to_cpu(*(__be32 *)(auxblk));
  10747. auxblk += sizeof(u32);
  10748. mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
  10749. DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
  10750. DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
  10751. DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
  10752. DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
  10753. pr_info("Firmware dev %x, ver %x, base ver %x\n",
  10754. mc_dev_type, mc_version, mc_base_version);
  10755. }
  10756. } else if (count + block_hdr.size * sizeof(u16) > size)
  10757. goto eof;
  10758. count += block_hdr.size * sizeof(u16);
  10759. }
  10760. return 0;
  10761. eof:
  10762. pr_err("Firmware is truncated at pos %u/%u\n", count, size);
  10763. return -EINVAL;
  10764. }
  10765. /**
  10766. * drx_ctrl_u_code - Handle microcode upload or verify.
  10767. * @dev_addr: Address of device.
  10768. * @mc_info: Pointer to information about microcode data.
  10769. * @action: Either UCODE_UPLOAD or UCODE_VERIFY
  10770. *
  10771. * This function returns:
  10772. * 0:
  10773. * - In case of UCODE_UPLOAD: code is successfully uploaded.
  10774. * - In case of UCODE_VERIFY: image on device is equal to
  10775. * image provided to this control function.
  10776. * -EIO:
  10777. * - In case of UCODE_UPLOAD: I2C error.
  10778. * - In case of UCODE_VERIFY: I2C error or image on device
  10779. * is not equal to image provided to this control function.
  10780. * -EINVAL:
  10781. * - Invalid arguments.
  10782. * - Provided image is corrupt
  10783. */
  10784. static int drx_ctrl_u_code(struct drx_demod_instance *demod,
  10785. struct drxu_code_info *mc_info,
  10786. enum drxu_code_action action)
  10787. {
  10788. struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
  10789. int rc;
  10790. u16 i = 0;
  10791. u16 mc_nr_of_blks = 0;
  10792. u16 mc_magic_word = 0;
  10793. const u8 *mc_data_init = NULL;
  10794. u8 *mc_data = NULL;
  10795. unsigned size;
  10796. char *mc_file;
  10797. /* Check arguments */
  10798. if (!mc_info || !mc_info->mc_file)
  10799. return -EINVAL;
  10800. mc_file = mc_info->mc_file;
  10801. if (!demod->firmware) {
  10802. const struct firmware *fw = NULL;
  10803. rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
  10804. if (rc < 0) {
  10805. pr_err("Couldn't read firmware %s\n", mc_file);
  10806. return rc;
  10807. }
  10808. demod->firmware = fw;
  10809. if (demod->firmware->size < 2 * sizeof(u16)) {
  10810. rc = -EINVAL;
  10811. pr_err("Firmware is too short!\n");
  10812. goto release;
  10813. }
  10814. pr_info("Firmware %s, size %zu\n",
  10815. mc_file, demod->firmware->size);
  10816. }
  10817. mc_data_init = demod->firmware->data;
  10818. size = demod->firmware->size;
  10819. mc_data = (void *)mc_data_init;
  10820. /* Check data */
  10821. mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
  10822. mc_data += sizeof(u16);
  10823. mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
  10824. mc_data += sizeof(u16);
  10825. if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
  10826. rc = -EINVAL;
  10827. pr_err("Firmware magic word doesn't match\n");
  10828. goto release;
  10829. }
  10830. if (action == UCODE_UPLOAD) {
  10831. rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
  10832. if (rc)
  10833. goto release;
  10834. pr_info("Uploading firmware %s\n", mc_file);
  10835. } else {
  10836. pr_info("Verifying if firmware upload was ok.\n");
  10837. }
  10838. /* Process microcode blocks */
  10839. for (i = 0; i < mc_nr_of_blks; i++) {
  10840. struct drxu_code_block_hdr block_hdr;
  10841. u16 mc_block_nr_bytes = 0;
  10842. /* Process block header */
  10843. block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
  10844. mc_data += sizeof(u32);
  10845. block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
  10846. mc_data += sizeof(u16);
  10847. block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
  10848. mc_data += sizeof(u16);
  10849. block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
  10850. mc_data += sizeof(u16);
  10851. pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
  10852. (unsigned)(mc_data - mc_data_init), block_hdr.addr,
  10853. block_hdr.size, block_hdr.flags, block_hdr.CRC);
  10854. /* Check block header on:
  10855. - data larger than 64Kb
  10856. - if CRC enabled check CRC
  10857. */
  10858. if ((block_hdr.size > 0x7FFF) ||
  10859. (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
  10860. (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
  10861. ) {
  10862. /* Wrong data ! */
  10863. rc = -EINVAL;
  10864. pr_err("firmware CRC is wrong\n");
  10865. goto release;
  10866. }
  10867. if (!block_hdr.size)
  10868. continue;
  10869. mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
  10870. /* Perform the desired action */
  10871. switch (action) {
  10872. case UCODE_UPLOAD: /* Upload microcode */
  10873. if (drxdap_fasi_write_block(dev_addr,
  10874. block_hdr.addr,
  10875. mc_block_nr_bytes,
  10876. mc_data, 0x0000)) {
  10877. rc = -EIO;
  10878. pr_err("error writing firmware at pos %u\n",
  10879. (unsigned)(mc_data - mc_data_init));
  10880. goto release;
  10881. }
  10882. break;
  10883. case UCODE_VERIFY: { /* Verify uploaded microcode */
  10884. int result = 0;
  10885. u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
  10886. u32 bytes_to_comp = 0;
  10887. u32 bytes_left = mc_block_nr_bytes;
  10888. u32 curr_addr = block_hdr.addr;
  10889. u8 *curr_ptr = mc_data;
  10890. while (bytes_left != 0) {
  10891. if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
  10892. bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
  10893. else
  10894. bytes_to_comp = bytes_left;
  10895. if (drxdap_fasi_read_block(dev_addr,
  10896. curr_addr,
  10897. (u16)bytes_to_comp,
  10898. (u8 *)mc_data_buffer,
  10899. 0x0000)) {
  10900. pr_err("error reading firmware at pos %u\n",
  10901. (unsigned)(mc_data - mc_data_init));
  10902. return -EIO;
  10903. }
  10904. result = memcmp(curr_ptr, mc_data_buffer,
  10905. bytes_to_comp);
  10906. if (result) {
  10907. pr_err("error verifying firmware at pos %u\n",
  10908. (unsigned)(mc_data - mc_data_init));
  10909. return -EIO;
  10910. }
  10911. curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
  10912. curr_ptr =&(curr_ptr[bytes_to_comp]);
  10913. bytes_left -=((u32) bytes_to_comp);
  10914. }
  10915. break;
  10916. }
  10917. default:
  10918. return -EINVAL;
  10919. break;
  10920. }
  10921. mc_data += mc_block_nr_bytes;
  10922. }
  10923. return 0;
  10924. release:
  10925. release_firmware(demod->firmware);
  10926. demod->firmware = NULL;
  10927. return rc;
  10928. }
  10929. /* caller is expected to check if lna is supported before enabling */
  10930. static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
  10931. {
  10932. struct drxuio_cfg uio_cfg;
  10933. struct drxuio_data uio_data;
  10934. int result;
  10935. uio_cfg.uio = DRX_UIO1;
  10936. uio_cfg.mode = DRX_UIO_MODE_READWRITE;
  10937. /* Configure user-I/O #3: enable read/write */
  10938. result = ctrl_set_uio_cfg(demod, &uio_cfg);
  10939. if (result) {
  10940. pr_err("Failed to setup LNA GPIO!\n");
  10941. return result;
  10942. }
  10943. uio_data.uio = DRX_UIO1;
  10944. uio_data.value = state;
  10945. result = ctrl_uio_write(demod, &uio_data);
  10946. if (result != 0) {
  10947. pr_err("Failed to %sable LNA!\n",
  10948. state ? "en" : "dis");
  10949. return result;
  10950. }
  10951. return 0;
  10952. }
  10953. /*
  10954. * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
  10955. *
  10956. * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
  10957. */
  10958. static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
  10959. {
  10960. struct drx39xxj_state *state = fe->demodulator_priv;
  10961. struct drx_demod_instance *demod = state->demod;
  10962. int result;
  10963. enum drx_power_mode power_mode;
  10964. if (enable)
  10965. power_mode = DRX_POWER_UP;
  10966. else
  10967. power_mode = DRX_POWER_DOWN;
  10968. result = ctrl_power_mode(demod, &power_mode);
  10969. if (result != 0) {
  10970. pr_err("Power state change failed\n");
  10971. return 0;
  10972. }
  10973. return 0;
  10974. }
  10975. static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
  10976. {
  10977. struct drx39xxj_state *state = fe->demodulator_priv;
  10978. struct drx_demod_instance *demod = state->demod;
  10979. int result;
  10980. enum drx_lock_status lock_status;
  10981. *status = 0;
  10982. result = ctrl_lock_status(demod, &lock_status);
  10983. if (result != 0) {
  10984. pr_err("drx39xxj: could not get lock status!\n");
  10985. *status = 0;
  10986. }
  10987. switch (lock_status) {
  10988. case DRX_NEVER_LOCK:
  10989. *status = 0;
  10990. pr_err("drx says NEVER_LOCK\n");
  10991. break;
  10992. case DRX_NOT_LOCKED:
  10993. *status = 0;
  10994. break;
  10995. case DRX_LOCK_STATE_1:
  10996. case DRX_LOCK_STATE_2:
  10997. case DRX_LOCK_STATE_3:
  10998. case DRX_LOCK_STATE_4:
  10999. case DRX_LOCK_STATE_5:
  11000. case DRX_LOCK_STATE_6:
  11001. case DRX_LOCK_STATE_7:
  11002. case DRX_LOCK_STATE_8:
  11003. case DRX_LOCK_STATE_9:
  11004. *status = FE_HAS_SIGNAL
  11005. | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
  11006. break;
  11007. case DRX_LOCKED:
  11008. *status = FE_HAS_SIGNAL
  11009. | FE_HAS_CARRIER
  11010. | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
  11011. break;
  11012. default:
  11013. pr_err("Lock state unknown %d\n", lock_status);
  11014. }
  11015. ctrl_sig_quality(demod, lock_status);
  11016. return 0;
  11017. }
  11018. static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
  11019. {
  11020. struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  11021. if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
  11022. *ber = 0;
  11023. return 0;
  11024. }
  11025. if (!p->pre_bit_count.stat[0].uvalue) {
  11026. if (!p->pre_bit_error.stat[0].uvalue)
  11027. *ber = 0;
  11028. else
  11029. *ber = 1000000;
  11030. } else {
  11031. *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
  11032. p->pre_bit_count.stat[0].uvalue);
  11033. }
  11034. return 0;
  11035. }
  11036. static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
  11037. u16 *strength)
  11038. {
  11039. struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  11040. if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
  11041. *strength = 0;
  11042. return 0;
  11043. }
  11044. *strength = p->strength.stat[0].uvalue;
  11045. return 0;
  11046. }
  11047. static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
  11048. {
  11049. struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  11050. u64 tmp64;
  11051. if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
  11052. *snr = 0;
  11053. return 0;
  11054. }
  11055. tmp64 = p->cnr.stat[0].svalue;
  11056. do_div(tmp64, 10);
  11057. *snr = tmp64;
  11058. return 0;
  11059. }
  11060. static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
  11061. {
  11062. struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  11063. if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
  11064. *ucb = 0;
  11065. return 0;
  11066. }
  11067. *ucb = p->block_error.stat[0].uvalue;
  11068. return 0;
  11069. }
  11070. static int drx39xxj_set_frontend(struct dvb_frontend *fe)
  11071. {
  11072. #ifdef DJH_DEBUG
  11073. int i;
  11074. #endif
  11075. struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  11076. struct drx39xxj_state *state = fe->demodulator_priv;
  11077. struct drx_demod_instance *demod = state->demod;
  11078. enum drx_standard standard = DRX_STANDARD_8VSB;
  11079. struct drx_channel channel;
  11080. int result;
  11081. static const struct drx_channel def_channel = {
  11082. /* frequency */ 0,
  11083. /* bandwidth */ DRX_BANDWIDTH_6MHZ,
  11084. /* mirror */ DRX_MIRROR_NO,
  11085. /* constellation */ DRX_CONSTELLATION_AUTO,
  11086. /* hierarchy */ DRX_HIERARCHY_UNKNOWN,
  11087. /* priority */ DRX_PRIORITY_UNKNOWN,
  11088. /* coderate */ DRX_CODERATE_UNKNOWN,
  11089. /* guard */ DRX_GUARD_UNKNOWN,
  11090. /* fftmode */ DRX_FFTMODE_UNKNOWN,
  11091. /* classification */ DRX_CLASSIFICATION_AUTO,
  11092. /* symbolrate */ 5057000,
  11093. /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
  11094. /* ldpc */ DRX_LDPC_UNKNOWN,
  11095. /* carrier */ DRX_CARRIER_UNKNOWN,
  11096. /* frame mode */ DRX_FRAMEMODE_UNKNOWN
  11097. };
  11098. u32 constellation = DRX_CONSTELLATION_AUTO;
  11099. /* Bring the demod out of sleep */
  11100. drx39xxj_set_powerstate(fe, 1);
  11101. if (fe->ops.tuner_ops.set_params) {
  11102. u32 int_freq;
  11103. if (fe->ops.i2c_gate_ctrl)
  11104. fe->ops.i2c_gate_ctrl(fe, 1);
  11105. /* Set tuner to desired frequency and standard */
  11106. fe->ops.tuner_ops.set_params(fe);
  11107. /* Use the tuner's IF */
  11108. if (fe->ops.tuner_ops.get_if_frequency) {
  11109. fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
  11110. demod->my_common_attr->intermediate_freq = int_freq / 1000;
  11111. }
  11112. if (fe->ops.i2c_gate_ctrl)
  11113. fe->ops.i2c_gate_ctrl(fe, 0);
  11114. }
  11115. switch (p->delivery_system) {
  11116. case SYS_ATSC:
  11117. standard = DRX_STANDARD_8VSB;
  11118. break;
  11119. case SYS_DVBC_ANNEX_B:
  11120. standard = DRX_STANDARD_ITU_B;
  11121. switch (p->modulation) {
  11122. case QAM_64:
  11123. constellation = DRX_CONSTELLATION_QAM64;
  11124. break;
  11125. case QAM_256:
  11126. constellation = DRX_CONSTELLATION_QAM256;
  11127. break;
  11128. default:
  11129. constellation = DRX_CONSTELLATION_AUTO;
  11130. break;
  11131. }
  11132. break;
  11133. default:
  11134. return -EINVAL;
  11135. }
  11136. /* Set the standard (will be powered up if necessary */
  11137. result = ctrl_set_standard(demod, &standard);
  11138. if (result != 0) {
  11139. pr_err("Failed to set standard! result=%02x\n",
  11140. result);
  11141. return -EINVAL;
  11142. }
  11143. /* set channel parameters */
  11144. channel = def_channel;
  11145. channel.frequency = p->frequency / 1000;
  11146. channel.bandwidth = DRX_BANDWIDTH_6MHZ;
  11147. channel.constellation = constellation;
  11148. /* program channel */
  11149. result = ctrl_set_channel(demod, &channel);
  11150. if (result != 0) {
  11151. pr_err("Failed to set channel!\n");
  11152. return -EINVAL;
  11153. }
  11154. /* Just for giggles, let's shut off the LNA again.... */
  11155. drxj_set_lna_state(demod, false);
  11156. /* After set_frontend, except for strength, stats aren't available */
  11157. p->strength.stat[0].scale = FE_SCALE_RELATIVE;
  11158. return 0;
  11159. }
  11160. static int drx39xxj_sleep(struct dvb_frontend *fe)
  11161. {
  11162. /* power-down the demodulator */
  11163. return drx39xxj_set_powerstate(fe, 0);
  11164. }
  11165. static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
  11166. {
  11167. struct drx39xxj_state *state = fe->demodulator_priv;
  11168. struct drx_demod_instance *demod = state->demod;
  11169. bool i2c_gate_state;
  11170. int result;
  11171. #ifdef DJH_DEBUG
  11172. pr_debug("i2c gate call: enable=%d state=%d\n", enable,
  11173. state->i2c_gate_open);
  11174. #endif
  11175. if (enable)
  11176. i2c_gate_state = true;
  11177. else
  11178. i2c_gate_state = false;
  11179. if (state->i2c_gate_open == enable) {
  11180. /* We're already in the desired state */
  11181. return 0;
  11182. }
  11183. result = ctrl_i2c_bridge(demod, &i2c_gate_state);
  11184. if (result != 0) {
  11185. pr_err("drx39xxj: could not open i2c gate [%d]\n",
  11186. result);
  11187. dump_stack();
  11188. } else {
  11189. state->i2c_gate_open = enable;
  11190. }
  11191. return 0;
  11192. }
  11193. static int drx39xxj_init(struct dvb_frontend *fe)
  11194. {
  11195. struct drx39xxj_state *state = fe->demodulator_priv;
  11196. struct drx_demod_instance *demod = state->demod;
  11197. int rc = 0;
  11198. if (fe->exit == DVB_FE_DEVICE_RESUME) {
  11199. /* so drxj_open() does what it needs to do */
  11200. demod->my_common_attr->is_opened = false;
  11201. rc = drxj_open(demod);
  11202. if (rc != 0)
  11203. pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
  11204. } else
  11205. drx39xxj_set_powerstate(fe, 1);
  11206. return rc;
  11207. }
  11208. static int drx39xxj_set_lna(struct dvb_frontend *fe)
  11209. {
  11210. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  11211. struct drx39xxj_state *state = fe->demodulator_priv;
  11212. struct drx_demod_instance *demod = state->demod;
  11213. struct drxj_data *ext_attr = demod->my_ext_attr;
  11214. if (c->lna) {
  11215. if (!ext_attr->has_lna) {
  11216. pr_err("LNA is not supported on this device!\n");
  11217. return -EINVAL;
  11218. }
  11219. }
  11220. return drxj_set_lna_state(demod, c->lna);
  11221. }
  11222. static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
  11223. struct dvb_frontend_tune_settings *tune)
  11224. {
  11225. tune->min_delay_ms = 1000;
  11226. return 0;
  11227. }
  11228. static void drx39xxj_release(struct dvb_frontend *fe)
  11229. {
  11230. struct drx39xxj_state *state = fe->demodulator_priv;
  11231. struct drx_demod_instance *demod = state->demod;
  11232. /* if device is removed don't access it */
  11233. if (fe->exit != DVB_FE_DEVICE_REMOVED)
  11234. drxj_close(demod);
  11235. kfree(demod->my_ext_attr);
  11236. kfree(demod->my_common_attr);
  11237. kfree(demod->my_i2c_dev_addr);
  11238. release_firmware(demod->firmware);
  11239. kfree(demod);
  11240. kfree(state);
  11241. }
  11242. static struct dvb_frontend_ops drx39xxj_ops;
  11243. struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
  11244. {
  11245. struct drx39xxj_state *state = NULL;
  11246. struct i2c_device_addr *demod_addr = NULL;
  11247. struct drx_common_attr *demod_comm_attr = NULL;
  11248. struct drxj_data *demod_ext_attr = NULL;
  11249. struct drx_demod_instance *demod = NULL;
  11250. struct dtv_frontend_properties *p;
  11251. int result;
  11252. /* allocate memory for the internal state */
  11253. state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);
  11254. if (state == NULL)
  11255. goto error;
  11256. demod = kmalloc(sizeof(struct drx_demod_instance), GFP_KERNEL);
  11257. if (demod == NULL)
  11258. goto error;
  11259. demod_addr = kmemdup(&drxj_default_addr_g,
  11260. sizeof(struct i2c_device_addr), GFP_KERNEL);
  11261. if (demod_addr == NULL)
  11262. goto error;
  11263. demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
  11264. sizeof(struct drx_common_attr), GFP_KERNEL);
  11265. if (demod_comm_attr == NULL)
  11266. goto error;
  11267. demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
  11268. GFP_KERNEL);
  11269. if (demod_ext_attr == NULL)
  11270. goto error;
  11271. /* setup the state */
  11272. state->i2c = i2c;
  11273. state->demod = demod;
  11274. /* setup the demod data */
  11275. memcpy(demod, &drxj_default_demod_g, sizeof(struct drx_demod_instance));
  11276. demod->my_i2c_dev_addr = demod_addr;
  11277. demod->my_common_attr = demod_comm_attr;
  11278. demod->my_i2c_dev_addr->user_data = state;
  11279. demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
  11280. demod->my_common_attr->verify_microcode = true;
  11281. demod->my_common_attr->intermediate_freq = 5000;
  11282. demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
  11283. demod->my_ext_attr = demod_ext_attr;
  11284. ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
  11285. demod->i2c = i2c;
  11286. result = drxj_open(demod);
  11287. if (result != 0) {
  11288. pr_err("DRX open failed! Aborting\n");
  11289. goto error;
  11290. }
  11291. /* create dvb_frontend */
  11292. memcpy(&state->frontend.ops, &drx39xxj_ops,
  11293. sizeof(struct dvb_frontend_ops));
  11294. state->frontend.demodulator_priv = state;
  11295. /* Initialize stats - needed for DVBv5 stats to work */
  11296. p = &state->frontend.dtv_property_cache;
  11297. p->strength.len = 1;
  11298. p->pre_bit_count.len = 1;
  11299. p->pre_bit_error.len = 1;
  11300. p->post_bit_count.len = 1;
  11301. p->post_bit_error.len = 1;
  11302. p->block_count.len = 1;
  11303. p->block_error.len = 1;
  11304. p->cnr.len = 1;
  11305. p->strength.stat[0].scale = FE_SCALE_RELATIVE;
  11306. p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  11307. p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  11308. p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  11309. p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  11310. p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  11311. p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  11312. p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  11313. return &state->frontend;
  11314. error:
  11315. kfree(demod_ext_attr);
  11316. kfree(demod_comm_attr);
  11317. kfree(demod_addr);
  11318. kfree(demod);
  11319. kfree(state);
  11320. return NULL;
  11321. }
  11322. EXPORT_SYMBOL(drx39xxj_attach);
  11323. static struct dvb_frontend_ops drx39xxj_ops = {
  11324. .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
  11325. .info = {
  11326. .name = "Micronas DRX39xxj family Frontend",
  11327. .frequency_stepsize = 62500,
  11328. .frequency_min = 51000000,
  11329. .frequency_max = 858000000,
  11330. .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
  11331. },
  11332. .init = drx39xxj_init,
  11333. .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
  11334. .sleep = drx39xxj_sleep,
  11335. .set_frontend = drx39xxj_set_frontend,
  11336. .get_tune_settings = drx39xxj_get_tune_settings,
  11337. .read_status = drx39xxj_read_status,
  11338. .read_ber = drx39xxj_read_ber,
  11339. .read_signal_strength = drx39xxj_read_signal_strength,
  11340. .read_snr = drx39xxj_read_snr,
  11341. .read_ucblocks = drx39xxj_read_ucblocks,
  11342. .release = drx39xxj_release,
  11343. .set_lna = drx39xxj_set_lna,
  11344. };
  11345. MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
  11346. MODULE_AUTHOR("Devin Heitmueller");
  11347. MODULE_LICENSE("GPL");
  11348. MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);