12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271 |
- diff -Nur linux-2.6.37.orig/arch/mips/Kconfig linux-2.6.37/arch/mips/Kconfig
- --- linux-2.6.37.orig/arch/mips/Kconfig 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/Kconfig 2011-01-11 20:44:43.000000000 +0100
- @@ -210,7 +210,7 @@
-
- config MACH_LOONGSON
- bool "Loongson family of machines"
- - select SYS_SUPPORTS_ZBOOT
- + select SYS_SUPPORTS_ZBOOT_UART16550
- help
- This enables the support of Loongson family of machines.
-
- @@ -1101,6 +1101,8 @@
- bool "Loongson 2E"
- depends on SYS_HAS_CPU_LOONGSON2E
- select CPU_LOONGSON2
- + select GENERIC_GPIO
- + select ARCH_REQUIRE_GPIOLIB
- help
- The Loongson 2E processor implements the MIPS III instruction set
- with many extensions.
- @@ -2099,6 +2101,18 @@
- source "kernel/time/Kconfig"
-
- #
- +# High Resolution sched_clock() Configuration
- +#
- +
- +config CPU_HAS_FIXED_C0_COUNT
- + bool
- +
- +config CPU_SUPPORTS_HR_SCHED_CLOCK
- + bool
- + depends on CPU_HAS_FIXED_C0_COUNT || !CPU_FREQ
- + default y
- +
- +#
- # Timer Interrupt Frequency Configuration
- #
-
- diff -Nur linux-2.6.37.orig/arch/mips/include/asm/dma-mapping.h linux-2.6.37/arch/mips/include/asm/dma-mapping.h
- --- linux-2.6.37.orig/arch/mips/include/asm/dma-mapping.h 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/include/asm/dma-mapping.h 2011-01-11 20:44:43.000000000 +0100
- @@ -85,4 +85,8 @@
- void dma_free_noncoherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-
- +#define ARCH_HAS_DMA_MMAP_COHERENT
- +extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- + void *cpu_addr, dma_addr_t handle, size_t size);
- +
- #endif /* _ASM_DMA_MAPPING_H */
- diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
- --- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2011-01-11 20:44:43.000000000 +0100
- @@ -255,21 +255,12 @@
- * IDE STANDARD
- */
- #define IDE_CAP 0x00
- -#define IDE_CONFIG 0x01
- -#define IDE_SMI 0x02
- -#define IDE_ERROR 0x03
- -#define IDE_PM 0x04
- -#define IDE_DIAG 0x05
- -
- -/*
- - * IDE SPEC.
- - */
- #define IDE_IO_BAR 0x08
- #define IDE_CFG 0x10
- #define IDE_DTC 0x12
- #define IDE_CAST 0x13
- #define IDE_ETC 0x14
- -#define IDE_INTERNAL_PM 0x15
- +#define IDE_PM 0x15
-
- /*
- * ACC STANDARD
- @@ -301,5 +292,40 @@
- /* GPIO : I/O SPACE; REG : 32BITS */
- #define GPIOL_OUT_VAL 0x00
- #define GPIOL_OUT_EN 0x04
- +#define GPIOL_OUT_AUX1_SEL 0x10
- +/* SMB : I/O SPACE, REG : 8BITS WIDTH */
- +#define SMB_SDA 0x00
- +#define SMB_STS 0x01
- +#define SMB_STS_SLVSTP (1 << 7)
- +#define SMB_STS_SDAST (1 << 6)
- +#define SMB_STS_BER (1 << 5)
- +#define SMB_STS_NEGACK (1 << 4)
- +#define SMB_STS_STASTR (1 << 3)
- +#define SMB_STS_NMATCH (1 << 2)
- +#define SMB_STS_MASTER (1 << 1)
- +#define SMB_STS_XMIT (1 << 0)
- +#define SMB_CTRL_STS 0x02
- +#define SMB_CSTS_TGSTL (1 << 5)
- +#define SMB_CSTS_TSDA (1 << 4)
- +#define SMB_CSTS_GCMTCH (1 << 3)
- +#define SMB_CSTS_MATCH (1 << 2)
- +#define SMB_CSTS_BB (1 << 1)
- +#define SMB_CSTS_BUSY (1 << 0)
- +#define SMB_CTRL1 0x03
- +#define SMB_CTRL1_STASTRE (1 << 7)
- +#define SMB_CTRL1_NMINTE (1 << 6)
- +#define SMB_CTRL1_GCMEN (1 << 5)
- +#define SMB_CTRL1_ACK (1 << 4)
- +#define SMB_CTRL1_RSVD (1 << 3)
- +#define SMB_CTRL1_INTEN (1 << 2)
- +#define SMB_CTRL1_STOP (1 << 1)
- +#define SMB_CTRL1_START (1 << 0)
- +#define SMB_ADDR 0x04
- +#define SMB_ADDR_SAEN (1 << 7)
- +#define SMB_CONTROLLER_ADDR (0xef << 0)
- +#define SMB_CTRL2 0x05
- +#define SMB_FREQ (0x20 << 1)
- +#define SMB_ENABLE (0x01 << 0)
- +#define SMB_CTRL3 0x06
-
- #endif /* _CS5536_H */
- diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
- --- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2011-01-11 20:44:43.000000000 +0100
- @@ -32,4 +32,9 @@
- #define MFGPT0_CNT (MFGPT_BASE + 4)
- #define MFGPT0_SETUP (MFGPT_BASE + 6)
-
- +#define MFGPT2_CMP1 (MFGPT_BASE + 0x10)
- +#define MFGPT2_CMP2 (MFGPT_BASE + 0x12)
- +#define MFGPT2_CNT (MFGPT_BASE + 0x14)
- +#define MFGPT2_SETUP (MFGPT_BASE + 0x16)
- +
- #endif /*!_CS5536_MFGPT_H */
- diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h linux-2.6.37/arch/mips/include/asm/mach-loongson/ec_kb3310b.h
- --- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,191 @@
- +/*
- + * KB3310B Embedded Controller
- + *
- + * Copyright (C) 2008 Lemote Inc.
- + * Author: liujl <liujl@lemote.com>, 2008-03-14
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef _EC_KB3310B_H
- +#define _EC_KB3310B_H
- +
- +extern unsigned char ec_read(unsigned short addr);
- +extern void ec_write(unsigned short addr, unsigned char val);
- +extern int ec_query_seq(unsigned char cmd);
- +extern int ec_query_event_num(void);
- +extern int ec_get_event_num(void);
- +
- +typedef int (*sci_handler) (int status);
- +extern sci_handler yeeloong_report_lid_status;
- +
- +#define SCI_IRQ_NUM 0x0A
- +
- +/*
- + * The following registers are determined by the EC index configuration.
- + * 1, fill the PORT_HIGH as EC register high part.
- + * 2, fill the PORT_LOW as EC register low part.
- + * 3, fill the PORT_DATA as EC register write data or get the data from it.
- + */
- +#define EC_IO_PORT_HIGH 0x0381
- +#define EC_IO_PORT_LOW 0x0382
- +#define EC_IO_PORT_DATA 0x0383
- +
- +/*
- + * EC delay time is 500us for register and status access
- + */
- +#define EC_REG_DELAY 500 /* unit : us */
- +#define EC_CMD_TIMEOUT 0x1000
- +
- +/*
- + * EC access port for SCI communication
- + */
- +#define EC_CMD_PORT 0x66
- +#define EC_STS_PORT 0x66
- +#define EC_DAT_PORT 0x62
- +#define CMD_INIT_IDLE_MODE 0xdd
- +#define CMD_EXIT_IDLE_MODE 0xdf
- +#define CMD_INIT_RESET_MODE 0xd8
- +#define CMD_REBOOT_SYSTEM 0x8c
- +#define CMD_GET_EVENT_NUM 0x84
- +#define CMD_PROGRAM_PIECE 0xda
- +
- +/* Temperature & Fan registers */
- +#define REG_TEMPERATURE_VALUE 0xF458
- +#define REG_FAN_AUTO_MAN_SWITCH 0xF459
- +#define BIT_FAN_AUTO 0
- +#define BIT_FAN_MANUAL 1
- +#define REG_FAN_CONTROL 0xF4D2
- +#define BIT_FAN_CONTROL_ON (1 << 0)
- +#define BIT_FAN_CONTROL_OFF (0 << 0)
- +#define REG_FAN_STATUS 0xF4DA
- +#define BIT_FAN_STATUS_ON (1 << 0)
- +#define BIT_FAN_STATUS_OFF (0 << 0)
- +#define REG_FAN_SPEED_HIGH 0xFE22
- +#define REG_FAN_SPEED_LOW 0xFE23
- +#define REG_FAN_SPEED_LEVEL 0xF4CC
- +/* Fan speed divider */
- +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
- +
- +/* Battery registers */
- +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
- +#define REG_BAT_DESIGN_CAP_LOW 0xF77E
- +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
- +#define REG_BAT_FULLCHG_CAP_LOW 0xF781
- +#define REG_BAT_DESIGN_VOL_HIGH 0xF782
- +#define REG_BAT_DESIGN_VOL_LOW 0xF783
- +#define REG_BAT_CURRENT_HIGH 0xF784
- +#define REG_BAT_CURRENT_LOW 0xF785
- +#define REG_BAT_VOLTAGE_HIGH 0xF786
- +#define REG_BAT_VOLTAGE_LOW 0xF787
- +#define REG_BAT_TEMPERATURE_HIGH 0xF788
- +#define REG_BAT_TEMPERATURE_LOW 0xF789
- +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
- +#define REG_BAT_RELATIVE_CAP_LOW 0xF493
- +#define REG_BAT_VENDOR 0xF4C4
- +#define FLAG_BAT_VENDOR_SANYO 0x01
- +#define FLAG_BAT_VENDOR_SIMPLO 0x02
- +#define REG_BAT_CELL_COUNT 0xF4C6
- +#define FLAG_BAT_CELL_3S1P 0x03
- +#define FLAG_BAT_CELL_3S2P 0x06
- +#define REG_BAT_CHARGE 0xF4A2
- +#define FLAG_BAT_CHARGE_DISCHARGE 0x01
- +#define FLAG_BAT_CHARGE_CHARGE 0x02
- +#define FLAG_BAT_CHARGE_ACPOWER 0x00
- +#define REG_BAT_STATUS 0xF4B0
- +#define BIT_BAT_STATUS_LOW (1 << 5)
- +#define BIT_BAT_STATUS_DESTROY (1 << 2)
- +#define BIT_BAT_STATUS_FULL (1 << 1)
- +#define BIT_BAT_STATUS_IN (1 << 0)
- +#define REG_BAT_CHARGE_STATUS 0xF4B1
- +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
- +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
- +#define REG_BAT_STATE 0xF482
- +#define BIT_BAT_STATE_CHARGING (1 << 1)
- +#define BIT_BAT_STATE_DISCHARGING (1 << 0)
- +#define REG_BAT_POWER 0xF440
- +#define BIT_BAT_POWER_S3 (1 << 2)
- +#define BIT_BAT_POWER_ON (1 << 1)
- +#define BIT_BAT_POWER_ACIN (1 << 0)
- +
- +/* Audio: rd/wr */
- +#define REG_AUDIO_VOLUME 0xF46C
- +#define REG_AUDIO_MUTE 0xF4E7
- +#define REG_AUDIO_BEEP 0xF4D0
- +/* USB port power or not: rd/wr */
- +#define REG_USB0_FLAG 0xF461
- +#define REG_USB1_FLAG 0xF462
- +#define REG_USB2_FLAG 0xF463
- +#define BIT_USB_FLAG_ON 1
- +#define BIT_USB_FLAG_OFF 0
- +/* LID */
- +#define REG_LID_DETECT 0xF4BD
- +#define BIT_LID_DETECT_ON 1
- +#define BIT_LID_DETECT_OFF 0
- +/* CRT */
- +#define REG_CRT_DETECT 0xF4AD
- +#define BIT_CRT_DETECT_PLUG 1
- +#define BIT_CRT_DETECT_UNPLUG 0
- +/* LCD backlight brightness adjust: 9 levels */
- +#define REG_DISPLAY_BRIGHTNESS 0xF4F5
- +/* Black screen Status */
- +#define BIT_DISPLAY_LCD_ON 1
- +#define BIT_DISPLAY_LCD_OFF 0
- +/* LCD backlight control: off/restore */
- +#define REG_BACKLIGHT_CTRL 0xF7BD
- +#define BIT_BACKLIGHT_ON 1
- +#define BIT_BACKLIGHT_OFF 0
- +/* Reset the machine auto-clear: rd/wr */
- +#define REG_RESET 0xF4EC
- +#define BIT_RESET_ON 1
- +/* Light the led: rd/wr */
- +#define REG_LED 0xF4C8
- +#define BIT_LED_RED_POWER (1 << 0)
- +#define BIT_LED_ORANGE_POWER (1 << 1)
- +#define BIT_LED_GREEN_CHARGE (1 << 2)
- +#define BIT_LED_RED_CHARGE (1 << 3)
- +#define BIT_LED_NUMLOCK (1 << 4)
- +/* Test led mode, all led on/off */
- +#define REG_LED_TEST 0xF4C2
- +#define BIT_LED_TEST_IN 1
- +#define BIT_LED_TEST_OUT 0
- +/* Camera on/off */
- +#define REG_CAMERA_STATUS 0xF46A
- +#define BIT_CAMERA_STATUS_ON 1
- +#define BIT_CAMERA_STATUS_OFF 0
- +#define REG_CAMERA_CONTROL 0xF7B7
- +#define BIT_CAMERA_CONTROL_OFF 0
- +#define BIT_CAMERA_CONTROL_ON 1
- +/* Wlan Status */
- +#define REG_WLAN 0xF4FA
- +#define BIT_WLAN_ON 1
- +#define BIT_WLAN_OFF 0
- +#define REG_DISPLAY_LCD 0xF79F
- +
- +/* SCI Event Number from EC */
- +enum {
- + EVENT_LID = 0x23, /* Turn on/off LID */
- + EVENT_SWITCHVIDEOMODE, /* Fn+F3 for display switch */
- + EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
- + EVENT_OVERTEMP, /* Over-temperature happened */
- + EVENT_CRT_DETECT, /* CRT is connected */
- + EVENT_CAMERA, /* Camera on/off */
- + EVENT_USB_OC2, /* USB2 Over Current occurred */
- + EVENT_USB_OC0, /* USB0 Over Current occurred */
- + EVENT_DISPLAYTOGGLE, /* Fn+F2, Turn on/off backlight */
- + EVENT_AUDIO_MUTE, /* Fn+F4, Mute on/off */
- + EVENT_DISPLAY_BRIGHTNESS,/* Fn+^/V, LCD backlight brightness adjust */
- + EVENT_AC_BAT, /* AC & Battery relative issue */
- + EVENT_AUDIO_VOLUME, /* Fn+<|>, Volume adjust */
- + EVENT_WLAN, /* Wlan on/off */
- +};
- +
- +#define EVENT_START EVENT_LID
- +#define EVENT_END EVENT_WLAN
- +
- +#endif /* !_EC_KB3310B_H */
- diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/loongson.h linux-2.6.37/arch/mips/include/asm/mach-loongson/loongson.h
- --- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/loongson.h 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/include/asm/mach-loongson/loongson.h 2011-01-11 20:44:43.000000000 +0100
- @@ -43,6 +43,12 @@
- #endif
- }
-
- +/*
- + * Copy kernel command line from arcs_cmdline
- + */
- +#include <asm/setup.h>
- +extern char loongson_cmdline[COMMAND_LINE_SIZE];
- +
- /* irq operation functions */
- extern void bonito_irqdispatch(void);
- extern void __init bonito_irq_init(void);
- diff -Nur linux-2.6.37.orig/arch/mips/kernel/csrc-r4k.c linux-2.6.37/arch/mips/kernel/csrc-r4k.c
- --- linux-2.6.37.orig/arch/mips/kernel/csrc-r4k.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/kernel/csrc-r4k.c 2011-01-11 20:44:43.000000000 +0100
- @@ -6,10 +6,66 @@
- * Copyright (C) 2007 by Ralf Baechle
- */
- #include <linux/clocksource.h>
- +#include <linux/cnt32_to_63.h>
- #include <linux/init.h>
- +#include <linux/timer.h>
-
- #include <asm/time.h>
-
- +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
- +/*
- + * MIPS sched_clock implementation.
- + *
- + * Because the hardware timer period is quite short and because cnt32_to_63()
- + * needs to be called at least once per half period to work properly, a kernel
- + * timer is set up to ensure this requirement is always met.
- + *
- + * Please refer to include/linux/cnt32_to_63.h and arch/arm/plat-orion/time.c
- + */
- +#define CLOCK2NS_SCALE_FACTOR 8
- +
- +static unsigned long clock2ns_scale __read_mostly;
- +
- +unsigned long long notrace sched_clock(void)
- +{
- + unsigned long long v = cnt32_to_63(read_c0_count());
- + return (v * clock2ns_scale) >> CLOCK2NS_SCALE_FACTOR;
- +}
- +
- +static struct timer_list cnt32_to_63_keepwarm_timer;
- +
- +static void cnt32_to_63_keepwarm(unsigned long data)
- +{
- + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
- + sched_clock();
- +}
- +#endif
- +
- +static inline void setup_hres_sched_clock(unsigned long clock)
- +{
- +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
- + unsigned long long v;
- + unsigned long data;
- +
- + v = NSEC_PER_SEC;
- + v <<= CLOCK2NS_SCALE_FACTOR;
- + v += clock/2;
- + do_div(v, clock);
- + /*
- + * We want an even value to automatically clear the top bit
- + * returned by cnt32_to_63() without an additional run time
- + * instruction. So if the LSB is 1 then round it up.
- + */
- + if (v & 1)
- + v++;
- + clock2ns_scale = v;
- +
- + data = 0x80000000UL / clock * HZ;
- + setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
- + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
- +#endif
- +}
- +
- static cycle_t c0_hpt_read(struct clocksource *cs)
- {
- return read_c0_count();
- @@ -27,6 +83,8 @@
- if (!cpu_has_counter || !mips_hpt_frequency)
- return -ENXIO;
-
- + setup_hres_sched_clock(mips_hpt_frequency);
- +
- /* Calculate a somewhat reasonable rating value */
- clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
-
- diff -Nur linux-2.6.37.orig/arch/mips/kernel/time.c linux-2.6.37/arch/mips/kernel/time.c
- --- linux-2.6.37.orig/arch/mips/kernel/time.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/kernel/time.c 2011-01-11 20:44:43.000000000 +0100
- @@ -119,6 +119,11 @@
-
- void __init time_init(void)
- {
- +#ifdef CONFIG_HR_SCHED_CLOCK
- + if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
- + write_c0_count(0);
- +#endif
- +
- plat_time_init();
-
- if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cmdline.c linux-2.6.37/arch/mips/loongson/common/cmdline.c
- --- linux-2.6.37.orig/arch/mips/loongson/common/cmdline.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/common/cmdline.c 2011-01-11 20:44:43.000000000 +0100
- @@ -17,10 +17,15 @@
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
- +#include <linux/module.h>
- #include <asm/bootinfo.h>
-
- #include <loongson.h>
-
- +/* the kernel command line copied from arcs_cmdline */
- +char loongson_cmdline[COMMAND_LINE_SIZE];
- +EXPORT_SYMBOL(loongson_cmdline);
- +
- void __init prom_init_cmdline(void)
- {
- int prom_argc;
- @@ -50,4 +55,26 @@
- strcat(arcs_cmdline, " root=/dev/hda1");
-
- prom_init_machtype();
- +
- + /* append machine specific command line */
- + switch (mips_machtype) {
- + case MACH_LEMOTE_LL2F:
- + if ((strstr(arcs_cmdline, "video=")) == NULL)
- + strcat(arcs_cmdline, " video=sisfb:1360x768-16@60");
- + break;
- + case MACH_LEMOTE_FL2F:
- + if ((strstr(arcs_cmdline, "ide_core.ignore_cable=")) == NULL)
- + strcat(arcs_cmdline, " ide_core.ignore_cable=0");
- + break;
- + case MACH_LEMOTE_ML2F7:
- + /* Mengloong-2F has a 800x480 screen */
- + if ((strstr(arcs_cmdline, "vga=")) == NULL)
- + strcat(arcs_cmdline, " vga=0x313");
- + break;
- + default:
- + break;
- + }
- +
- + /* copy arcs_cmdline into loongson_cmdline */
- + strncpy(loongson_cmdline, arcs_cmdline, COMMAND_LINE_SIZE);
- }
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_acc.c
- --- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_acc.c 2011-01-11 20:44:43.000000000 +0100
- @@ -18,7 +18,7 @@
-
- void pci_acc_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -66,75 +66,73 @@
- u32 pci_acc_read_reg(int reg)
- {
- u32 hi, lo;
- - u32 conf_data = 0;
- + u32 cfg = 0;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
- if (((lo & 0xfff00000) || (hi & 0x000000ff))
- && ((hi & 0xf0000000) == 0xa0000000))
- - conf_data |= PCI_COMMAND_IO;
- + cfg |= PCI_COMMAND_IO;
- _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
- if ((lo & 0x300) == 0x300)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_ACC_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_ACC_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- - conf_data =
- - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- - PCI_NORMAL_LATENCY_TIMER);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- + PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_ACC_FLAG) {
- - conf_data = CS5536_ACC_RANGE |
- + cfg = CS5536_ACC_RANGE |
- PCI_BASE_ADDRESS_SPACE_IO;
- lo &= ~SOFT_BAR_ACC_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
- - conf_data = (hi & 0x000000ff) << 12;
- - conf_data |= (lo & 0xfff00000) >> 20;
- - conf_data |= 0x01;
- - conf_data &= ~0x02;
- + cfg = (hi & 0x000000ff) << 12;
- + cfg |= (lo & 0xfff00000) >> 20;
- + cfg |= 0x01;
- + cfg &= ~0x02;
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_USB_POINTER;
- + cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
- break;
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ehci.c
- --- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2011-01-11 20:44:43.000000000 +0100
- @@ -18,7 +18,7 @@
-
- void pci_ehci_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -78,83 +78,81 @@
-
- u32 pci_ehci_read_reg(int reg)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- if (hi & PCI_COMMAND_MASTER)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- if (hi & PCI_COMMAND_MEMORY)
- - conf_data |= PCI_COMMAND_MEMORY;
- + cfg |= PCI_COMMAND_MEMORY;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_EHCI_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- - conf_data =
- - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- - PCI_NORMAL_LATENCY_TIMER);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- + PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_EHCI_FLAG) {
- - conf_data = CS5536_EHCI_RANGE |
- + cfg = CS5536_EHCI_RANGE |
- PCI_BASE_ADDRESS_SPACE_MEMORY;
- lo &= ~SOFT_BAR_EHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = lo & 0xfffff000;
- + cfg = lo & 0xfffff000;
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_USB_POINTER;
- + cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- break;
- case PCI_EHCI_LEGSMIEN_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = (hi & 0x003f0000) >> 16;
- + cfg = (hi & 0x003f0000) >> 16;
- break;
- case PCI_EHCI_LEGSMISTS_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = (hi & 0x3f000000) >> 24;
- + cfg = (hi & 0x3f000000) >> 24;
- break;
- case PCI_EHCI_FLADJ_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = hi & 0x00003f00;
- + cfg = hi & 0x00003f00;
- break;
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ide.c
- --- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ide.c 2011-01-11 20:44:43.000000000 +0100
- @@ -18,7 +18,7 @@
-
- void pci_ide_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -72,26 +72,16 @@
- _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
- }
- break;
- - case PCI_IDE_DTC_REG:
- - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
- - lo = value;
- - _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
- - break;
- - case PCI_IDE_CAST_REG:
- - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
- - lo = value;
- - _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
- - break;
- - case PCI_IDE_ETC_REG:
- - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
- - lo = value;
- - _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
- - break;
- - case PCI_IDE_PM_REG:
- - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
- - lo = value;
- - _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
- - break;
- +#define SET_PCI_IDE_REG(r) \
- + case PCI_IDE_##r##_REG: \
- + _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &lo); \
- + lo = value; \
- + _wrmsr(IDE_MSR_REG(IDE_##r), hi, lo); \
- + break;
- + SET_PCI_IDE_REG(DTC)
- + SET_PCI_IDE_REG(CAST)
- + SET_PCI_IDE_REG(ETC)
- + SET_PCI_IDE_REG(PM)
- default:
- break;
- }
- @@ -99,94 +89,82 @@
-
- u32 pci_ide_read_reg(int reg)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
- if (lo & 0xfffffff0)
- - conf_data |= PCI_COMMAND_IO;
- + cfg |= PCI_COMMAND_IO;
- _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
- if ((lo & 0x30) == 0x30)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_IDE_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_IDE_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
- hi &= 0x000000f8;
- - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
- break;
- case PCI_BAR4_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_IDE_FLAG) {
- - conf_data = CS5536_IDE_RANGE |
- + cfg = CS5536_IDE_RANGE |
- PCI_BASE_ADDRESS_SPACE_IO;
- lo &= ~SOFT_BAR_IDE_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
- - conf_data = lo & 0xfffffff0;
- - conf_data |= 0x01;
- - conf_data &= ~0x02;
- + cfg = lo & 0xfffffff0;
- + cfg |= 0x01;
- + cfg &= ~0x02;
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_POINTER;
- + cfg = PCI_CAPLIST_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
- - break;
- - case PCI_IDE_CFG_REG:
- - _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
- - conf_data = lo;
- - break;
- - case PCI_IDE_DTC_REG:
- - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
- - conf_data = lo;
- - break;
- - case PCI_IDE_CAST_REG:
- - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
- - conf_data = lo;
- - break;
- - case PCI_IDE_ETC_REG:
- - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
- - conf_data = lo;
- - break;
- - case PCI_IDE_PM_REG:
- - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
- - conf_data = lo;
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
- break;
- +#define GET_PCI_IDE_REG(r) \
- + case PCI_IDE_##r##_REG: \
- + _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &cfg); \
- + break;
- + GET_PCI_IDE_REG(CFG)
- + GET_PCI_IDE_REG(DTC)
- + GET_PCI_IDE_REG(CAST)
- + GET_PCI_IDE_REG(ETC)
- + GET_PCI_IDE_REG(PM)
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ohci.c
- --- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2011-01-11 20:44:43.000000000 +0100
- @@ -18,7 +18,7 @@
-
- void pci_ohci_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -73,77 +73,75 @@
-
- u32 pci_ohci_read_reg(int reg)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
- if (hi & PCI_COMMAND_MASTER)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- if (hi & PCI_COMMAND_MEMORY)
- - conf_data |= PCI_COMMAND_MEMORY;
- + cfg |= PCI_COMMAND_MEMORY;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_OHCI_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- - conf_data =
- - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- - PCI_NORMAL_LATENCY_TIMER);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- + PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_OHCI_FLAG) {
- - conf_data = CS5536_OHCI_RANGE |
- + cfg = CS5536_OHCI_RANGE |
- PCI_BASE_ADDRESS_SPACE_MEMORY;
- lo &= ~SOFT_BAR_OHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
- - conf_data = lo & 0xffffff00;
- - conf_data &= ~0x0000000f; /* 32bit mem */
- + cfg = lo & 0xffffff00;
- + cfg &= ~0x0000000f; /* 32bit mem */
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_USB_POINTER;
- + cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- break;
- case PCI_OHCI_INT_REG:
- _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
- if ((lo & 0x00000f00) == CS5536_USB_INTR)
- - conf_data = 1;
- + cfg = 1;
- break;
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/mtd.c linux-2.6.37/arch/mips/loongson/common/mtd.c
- --- linux-2.6.37.orig/arch/mips/loongson/common/mtd.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/common/mtd.c 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,91 @@
- +/*
- + * Driver for flushing/dumping ROM of PMON on loongson family machines
- + *
- + * Copyright (C) 2008-2009 Lemote Inc.
- + * Author: Yan Hua <yanh@lemote.com>
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + */
- +
- +#include <linux/module.h>
- +#include <linux/types.h>
- +#include <linux/kernel.h>
- +#include <linux/init.h>
- +#include <linux/mtd/mtd.h>
- +#include <linux/mtd/map.h>
- +#include <linux/mtd/partitions.h>
- +
- +#include <asm/io.h>
- +
- +#include <loongson.h>
- +
- +#define FLASH_PHYS_ADDR LOONGSON_BOOT_BASE
- +#define FLASH_SIZE 0x080000
- +
- +#define FLASH_PARTITION0_ADDR 0x00000000
- +#define FLASH_PARTITION0_SIZE 0x00080000
- +
- +struct map_info flash_map = {
- + .name = "flash device",
- + .size = FLASH_SIZE,
- + .bankwidth = 1,
- +};
- +
- +struct mtd_partition flash_parts[] = {
- + {
- + .name = "Bootloader",
- + .offset = FLASH_PARTITION0_ADDR,
- + .size = FLASH_PARTITION0_SIZE},
- +};
- +
- +#define PARTITION_COUNT ARRAY_SIZE(flash_parts)
- +
- +static struct mtd_info *mymtd;
- +
- +int __init init_flash(void)
- +{
- + printk(KERN_NOTICE "flash device: %x at %x\n",
- + FLASH_SIZE, FLASH_PHYS_ADDR);
- +
- + flash_map.phys = FLASH_PHYS_ADDR;
- + flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE);
- +
- + if (!flash_map.virt) {
- + printk(KERN_NOTICE "Failed to ioremap\n");
- + return -EIO;
- + }
- +
- + simple_map_init(&flash_map);
- +
- + mymtd = do_map_probe("cfi_probe", &flash_map);
- + if (mymtd) {
- + add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT);
- + printk(KERN_NOTICE "pmon flash device initialized\n");
- + return 0;
- + }
- +
- + iounmap((void *)flash_map.virt);
- + return -ENXIO;
- +}
- +
- +static void __exit cleanup_flash(void)
- +{
- + if (mymtd) {
- + del_mtd_partitions(mymtd);
- + map_destroy(mymtd);
- + }
- + if (flash_map.virt) {
- + iounmap((void *)flash_map.virt);
- + flash_map.virt = 0;
- + }
- +}
- +
- +module_init(init_flash);
- +module_exit(cleanup_flash);
- +
- +MODULE_LICENSE("GPL");
- +MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
- +MODULE_DESCRIPTION("MTD driver for pmon flushing/dumping");
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/Makefile linux-2.6.37/arch/mips/loongson/lemote-2f/Makefile
- --- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/Makefile 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/lemote-2f/Makefile 2011-01-11 20:44:43.000000000 +0100
- @@ -2,7 +2,7 @@
- # Makefile for lemote loongson2f family machines
- #
-
- -obj-y += machtype.o irq.o reset.o ec_kb3310b.o
- +obj-y += machtype.o irq.o reset.o ec_kb3310b.o platform.o
-
- #
- # Suspend Support
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.c
- --- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2011-01-11 20:44:43.000000000 +0100
- @@ -14,7 +14,7 @@
- #include <linux/spinlock.h>
- #include <linux/delay.h>
-
- -#include "ec_kb3310b.h"
- +#include <ec_kb3310b.h>
-
- static DEFINE_SPINLOCK(index_access_lock);
- static DEFINE_SPINLOCK(port_access_lock);
- @@ -78,12 +78,9 @@
- spin_unlock_irqrestore(&port_access_lock, flags);
-
- if (timeout <= 0) {
- - printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
- + pr_err("%s: deadable error : timeout...\n", __func__);
- ret = -EINVAL;
- - } else
- - printk(KERN_INFO
- - "(%x/%d)ec issued command %d status : 0x%x\n",
- - timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
- + }
-
- return ret;
- }
- @@ -118,8 +115,7 @@
- udelay(EC_REG_DELAY);
- }
- if (timeout <= 0) {
- - pr_info("%s: get event number timeout.\n", __func__);
- -
- + pr_err("%s: get event number timeout.\n", __func__);
- return -EINVAL;
- }
- value = inb(EC_DAT_PORT);
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.h
- --- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
- @@ -1,188 +0,0 @@
- -/*
- - * KB3310B Embedded Controller
- - *
- - * Copyright (C) 2008 Lemote Inc.
- - * Author: liujl <liujl@lemote.com>, 2008-03-14
- - *
- - * This program is free software; you can redistribute it and/or modify
- - * it under the terms of the GNU General Public License as published by
- - * the Free Software Foundation; either version 2 of the License, or
- - * (at your option) any later version.
- - */
- -
- -#ifndef _EC_KB3310B_H
- -#define _EC_KB3310B_H
- -
- -extern unsigned char ec_read(unsigned short addr);
- -extern void ec_write(unsigned short addr, unsigned char val);
- -extern int ec_query_seq(unsigned char cmd);
- -extern int ec_query_event_num(void);
- -extern int ec_get_event_num(void);
- -
- -typedef int (*sci_handler) (int status);
- -extern sci_handler yeeloong_report_lid_status;
- -
- -#define SCI_IRQ_NUM 0x0A
- -
- -/*
- - * The following registers are determined by the EC index configuration.
- - * 1, fill the PORT_HIGH as EC register high part.
- - * 2, fill the PORT_LOW as EC register low part.
- - * 3, fill the PORT_DATA as EC register write data or get the data from it.
- - */
- -#define EC_IO_PORT_HIGH 0x0381
- -#define EC_IO_PORT_LOW 0x0382
- -#define EC_IO_PORT_DATA 0x0383
- -
- -/*
- - * EC delay time is 500us for register and status access
- - */
- -#define EC_REG_DELAY 500 /* unit : us */
- -#define EC_CMD_TIMEOUT 0x1000
- -
- -/*
- - * EC access port for SCI communication
- - */
- -#define EC_CMD_PORT 0x66
- -#define EC_STS_PORT 0x66
- -#define EC_DAT_PORT 0x62
- -#define CMD_INIT_IDLE_MODE 0xdd
- -#define CMD_EXIT_IDLE_MODE 0xdf
- -#define CMD_INIT_RESET_MODE 0xd8
- -#define CMD_REBOOT_SYSTEM 0x8c
- -#define CMD_GET_EVENT_NUM 0x84
- -#define CMD_PROGRAM_PIECE 0xda
- -
- -/* temperature & fan registers */
- -#define REG_TEMPERATURE_VALUE 0xF458
- -#define REG_FAN_AUTO_MAN_SWITCH 0xF459
- -#define BIT_FAN_AUTO 0
- -#define BIT_FAN_MANUAL 1
- -#define REG_FAN_CONTROL 0xF4D2
- -#define BIT_FAN_CONTROL_ON (1 << 0)
- -#define BIT_FAN_CONTROL_OFF (0 << 0)
- -#define REG_FAN_STATUS 0xF4DA
- -#define BIT_FAN_STATUS_ON (1 << 0)
- -#define BIT_FAN_STATUS_OFF (0 << 0)
- -#define REG_FAN_SPEED_HIGH 0xFE22
- -#define REG_FAN_SPEED_LOW 0xFE23
- -#define REG_FAN_SPEED_LEVEL 0xF4CC
- -/* fan speed divider */
- -#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
- -
- -/* battery registers */
- -#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
- -#define REG_BAT_DESIGN_CAP_LOW 0xF77E
- -#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
- -#define REG_BAT_FULLCHG_CAP_LOW 0xF781
- -#define REG_BAT_DESIGN_VOL_HIGH 0xF782
- -#define REG_BAT_DESIGN_VOL_LOW 0xF783
- -#define REG_BAT_CURRENT_HIGH 0xF784
- -#define REG_BAT_CURRENT_LOW 0xF785
- -#define REG_BAT_VOLTAGE_HIGH 0xF786
- -#define REG_BAT_VOLTAGE_LOW 0xF787
- -#define REG_BAT_TEMPERATURE_HIGH 0xF788
- -#define REG_BAT_TEMPERATURE_LOW 0xF789
- -#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
- -#define REG_BAT_RELATIVE_CAP_LOW 0xF493
- -#define REG_BAT_VENDOR 0xF4C4
- -#define FLAG_BAT_VENDOR_SANYO 0x01
- -#define FLAG_BAT_VENDOR_SIMPLO 0x02
- -#define REG_BAT_CELL_COUNT 0xF4C6
- -#define FLAG_BAT_CELL_3S1P 0x03
- -#define FLAG_BAT_CELL_3S2P 0x06
- -#define REG_BAT_CHARGE 0xF4A2
- -#define FLAG_BAT_CHARGE_DISCHARGE 0x01
- -#define FLAG_BAT_CHARGE_CHARGE 0x02
- -#define FLAG_BAT_CHARGE_ACPOWER 0x00
- -#define REG_BAT_STATUS 0xF4B0
- -#define BIT_BAT_STATUS_LOW (1 << 5)
- -#define BIT_BAT_STATUS_DESTROY (1 << 2)
- -#define BIT_BAT_STATUS_FULL (1 << 1)
- -#define BIT_BAT_STATUS_IN (1 << 0)
- -#define REG_BAT_CHARGE_STATUS 0xF4B1
- -#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
- -#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
- -#define REG_BAT_STATE 0xF482
- -#define BIT_BAT_STATE_CHARGING (1 << 1)
- -#define BIT_BAT_STATE_DISCHARGING (1 << 0)
- -#define REG_BAT_POWER 0xF440
- -#define BIT_BAT_POWER_S3 (1 << 2)
- -#define BIT_BAT_POWER_ON (1 << 1)
- -#define BIT_BAT_POWER_ACIN (1 << 0)
- -
- -/* other registers */
- -/* Audio: rd/wr */
- -#define REG_AUDIO_VOLUME 0xF46C
- -#define REG_AUDIO_MUTE 0xF4E7
- -#define REG_AUDIO_BEEP 0xF4D0
- -/* USB port power or not: rd/wr */
- -#define REG_USB0_FLAG 0xF461
- -#define REG_USB1_FLAG 0xF462
- -#define REG_USB2_FLAG 0xF463
- -#define BIT_USB_FLAG_ON 1
- -#define BIT_USB_FLAG_OFF 0
- -/* LID */
- -#define REG_LID_DETECT 0xF4BD
- -#define BIT_LID_DETECT_ON 1
- -#define BIT_LID_DETECT_OFF 0
- -/* CRT */
- -#define REG_CRT_DETECT 0xF4AD
- -#define BIT_CRT_DETECT_PLUG 1
- -#define BIT_CRT_DETECT_UNPLUG 0
- -/* LCD backlight brightness adjust: 9 levels */
- -#define REG_DISPLAY_BRIGHTNESS 0xF4F5
- -/* Black screen Status */
- -#define BIT_DISPLAY_LCD_ON 1
- -#define BIT_DISPLAY_LCD_OFF 0
- -/* LCD backlight control: off/restore */
- -#define REG_BACKLIGHT_CTRL 0xF7BD
- -#define BIT_BACKLIGHT_ON 1
- -#define BIT_BACKLIGHT_OFF 0
- -/* Reset the machine auto-clear: rd/wr */
- -#define REG_RESET 0xF4EC
- -#define BIT_RESET_ON 1
- -/* Light the led: rd/wr */
- -#define REG_LED 0xF4C8
- -#define BIT_LED_RED_POWER (1 << 0)
- -#define BIT_LED_ORANGE_POWER (1 << 1)
- -#define BIT_LED_GREEN_CHARGE (1 << 2)
- -#define BIT_LED_RED_CHARGE (1 << 3)
- -#define BIT_LED_NUMLOCK (1 << 4)
- -/* Test led mode, all led on/off */
- -#define REG_LED_TEST 0xF4C2
- -#define BIT_LED_TEST_IN 1
- -#define BIT_LED_TEST_OUT 0
- -/* Camera on/off */
- -#define REG_CAMERA_STATUS 0xF46A
- -#define BIT_CAMERA_STATUS_ON 1
- -#define BIT_CAMERA_STATUS_OFF 0
- -#define REG_CAMERA_CONTROL 0xF7B7
- -#define BIT_CAMERA_CONTROL_OFF 0
- -#define BIT_CAMERA_CONTROL_ON 1
- -/* Wlan Status */
- -#define REG_WLAN 0xF4FA
- -#define BIT_WLAN_ON 1
- -#define BIT_WLAN_OFF 0
- -#define REG_DISPLAY_LCD 0xF79F
- -
- -/* SCI Event Number from EC */
- -enum {
- - EVENT_LID = 0x23, /* LID open/close */
- - EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
- - EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
- - EVENT_OVERTEMP, /* Over-temperature happened */
- - EVENT_CRT_DETECT, /* CRT is connected */
- - EVENT_CAMERA, /* Camera on/off */
- - EVENT_USB_OC2, /* USB2 Over Current occurred */
- - EVENT_USB_OC0, /* USB0 Over Current occurred */
- - EVENT_BLACK_SCREEN, /* Turn on/off backlight */
- - EVENT_AUDIO_MUTE, /* Mute on/off */
- - EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
- - EVENT_AC_BAT, /* AC & Battery relative issue */
- - EVENT_AUDIO_VOLUME, /* Volume adjust */
- - EVENT_WLAN, /* Wlan on/off */
- - EVENT_END
- -};
- -
- -#endif /* !_EC_KB3310B_H */
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/platform.c linux-2.6.37/arch/mips/loongson/lemote-2f/platform.c
- --- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/platform.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/lemote-2f/platform.c 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,48 @@
- +/*
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + */
- +
- +#include <linux/err.h>
- +#include <linux/platform_device.h>
- +
- +#include <asm/bootinfo.h>
- +
- +static struct platform_device yeeloong_pdev = {
- + .name = "yeeloong_laptop",
- + .id = -1,
- +};
- +
- +static struct platform_device lynloong_pdev = {
- + .name = "lynloong_pc",
- + .id = -1,
- +};
- +
- +static int __init lemote2f_platform_init(void)
- +{
- + struct platform_device *pdev = NULL;
- +
- + switch (mips_machtype) {
- + case MACH_LEMOTE_YL2F89:
- + pdev = &yeeloong_pdev;
- + break;
- + case MACH_LEMOTE_LL2F:
- + pdev = &lynloong_pdev;
- + break;
- + default:
- + break;
- +
- + }
- +
- + if (pdev != NULL)
- + return platform_device_register(pdev);
- +
- + return -ENODEV;
- +}
- +
- +arch_initcall(lemote2f_platform_init);
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/pm.c linux-2.6.37/arch/mips/loongson/lemote-2f/pm.c
- --- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/pm.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/lemote-2f/pm.c 2011-01-11 20:44:43.000000000 +0100
- @@ -23,7 +23,7 @@
- #include <loongson.h>
-
- #include <cs5536/cs5536_mfgpt.h>
- -#include "ec_kb3310b.h"
- +#include <ec_kb3310b.h>
-
- #define I8042_KBD_IRQ 1
- #define I8042_CTR_KBDINT 0x01
- @@ -100,7 +100,7 @@
- if (irq < 0)
- return 0;
-
- - printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
- + pr_info("%s: irq = %d\n", __func__, irq);
-
- if (irq == I8042_KBD_IRQ)
- return 1;
- diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/reset.c linux-2.6.37/arch/mips/loongson/lemote-2f/reset.c
- --- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/reset.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/loongson/lemote-2f/reset.c 2011-01-11 20:44:43.000000000 +0100
- @@ -20,7 +20,7 @@
- #include <loongson.h>
-
- #include <cs5536/cs5536.h>
- -#include "ec_kb3310b.h"
- +#include <ec_kb3310b.h>
-
- static void reset_cpu(void)
- {
- diff -Nur linux-2.6.37.orig/arch/mips/mm/dma-default.c linux-2.6.37/arch/mips/mm/dma-default.c
- --- linux-2.6.37.orig/arch/mips/mm/dma-default.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/arch/mips/mm/dma-default.c 2011-01-11 20:46:19.000000000 +0100
- @@ -300,6 +300,20 @@
-
- EXPORT_SYMBOL(dma_cache_sync);
-
- +int __weak dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- + void *cpu_addr, dma_addr_t handle, size_t size)
- +{
- + struct page *pg;
- + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- + cpu_addr = (void *)dma_addr_to_virt(dev, handle);
- + pg = virt_to_page(cpu_addr);
- + return remap_pfn_range(vma, vma->vm_start,
- + page_to_pfn(pg) + vma->vm_pgoff,
- + size, vma->vm_page_prot);
- +}
- +EXPORT_SYMBOL(dma_mmap_coherent);
- +
- +
- static struct dma_map_ops mips_default_dma_map_ops = {
- .alloc_coherent = mips_dma_alloc_coherent,
- .free_coherent = mips_dma_free_coherent,
- diff -Nur linux-2.6.37.orig/drivers/ide/ide-iops.c linux-2.6.37/drivers/ide/ide-iops.c
- --- linux-2.6.37.orig/drivers/ide/ide-iops.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/drivers/ide/ide-iops.c 2011-01-11 20:44:43.000000000 +0100
- @@ -27,6 +27,8 @@
- #include <asm/uaccess.h>
- #include <asm/io.h>
-
- +#include <asm/bootinfo.h>
- +
- void SELECT_MASK(ide_drive_t *drive, int mask)
- {
- const struct ide_port_ops *port_ops = drive->hwif->port_ops;
- @@ -300,6 +302,9 @@
- {
- const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
-
- + if (mips_machtype != MACH_LEMOTE_YL2F89)
- + return;
- +
- for (list = nien_quirk_list; *list != NULL; list++)
- if (strstr(m, *list) != NULL) {
- drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
- diff -Nur linux-2.6.37.orig/drivers/platform/Kconfig linux-2.6.37/drivers/platform/Kconfig
- --- linux-2.6.37.orig/drivers/platform/Kconfig 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/drivers/platform/Kconfig 2011-01-11 20:44:43.000000000 +0100
- @@ -1,3 +1,7 @@
- if X86
- source "drivers/platform/x86/Kconfig"
- endif
- +
- +if MIPS
- +source "drivers/platform/mips/Kconfig"
- +endif
- diff -Nur linux-2.6.37.orig/drivers/platform/Makefile linux-2.6.37/drivers/platform/Makefile
- --- linux-2.6.37.orig/drivers/platform/Makefile 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/drivers/platform/Makefile 2011-01-11 20:44:43.000000000 +0100
- @@ -3,3 +3,4 @@
- #
-
- obj-$(CONFIG_X86) += x86/
- +obj-$(CONFIG_MIPS) += mips/
- diff -Nur linux-2.6.37.orig/drivers/platform/mips/Kconfig linux-2.6.37/drivers/platform/mips/Kconfig
- --- linux-2.6.37.orig/drivers/platform/mips/Kconfig 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/drivers/platform/mips/Kconfig 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,43 @@
- +#
- +# MIPS Platform Specific Drivers
- +#
- +
- +menuconfig MIPS_PLATFORM_DEVICES
- + bool "MIPS Platform Specific Device Drivers"
- + default y
- + help
- + Say Y here to get to see options for device drivers of various
- + MIPS platforms, including vendor-specific netbook/laptop/pc extension
- + drivers. This option alone does not add any kernel code.
- +
- + If you say N, all options in this submenu will be skipped and disabled.
- +
- +if MIPS_PLATFORM_DEVICES
- +
- +config LEMOTE_YEELOONG2F
- + tristate "Lemote YeeLoong Laptop"
- + depends on LEMOTE_MACH2F
- + select BACKLIGHT_CLASS_DEVICE
- + select POWER_SUPPLY
- + select HWMON
- + select VIDEO_OUTPUT_CONTROL
- + select INPUT_SPARSEKMAP
- + depends on INPUT
- + help
- + YeeLoong netbook is a mini laptop made by Lemote, which is basically
- + compatible to FuLoong2F mini PC, but it has an extra Embedded
- + Controller(kb3310b) for battery, hotkey, backlight, temperature and
- + fan management.
- +
- +config LEMOTE_LYNLOONG2F
- + tristate "Lemote LynLoong PC"
- + depends on LEMOTE_MACH2F
- + select BACKLIGHT_CLASS_DEVICE
- + select VIDEO_OUTPUT_CONTROL
- + help
- + LynLoong PC is an AllINONE machine made by Lemote, which is basically
- + compatible to FuLoong2F Mini PC, the only difference is that it has a
- + size-fixed screen: 1360x768 with sisfb video driver. and also, it has
- + its own specific suspend support.
- +
- +endif # MIPS_PLATFORM_DEVICES
- diff -Nur linux-2.6.37.orig/drivers/platform/mips/Makefile linux-2.6.37/drivers/platform/mips/Makefile
- --- linux-2.6.37.orig/drivers/platform/mips/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/drivers/platform/mips/Makefile 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,7 @@
- +#
- +# Makefile for MIPS Platform-Specific Drivers
- +#
- +
- +obj-$(CONFIG_LEMOTE_YEELOONG2F) += yeeloong_laptop.o
- +
- +obj-$(CONFIG_LEMOTE_LYNLOONG2F) += lynloong_pc.o
- diff -Nur linux-2.6.37.orig/drivers/platform/mips/lynloong_pc.c linux-2.6.37/drivers/platform/mips/lynloong_pc.c
- --- linux-2.6.37.orig/drivers/platform/mips/lynloong_pc.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/drivers/platform/mips/lynloong_pc.c 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,513 @@
- +/*
- + * Driver for LynLoong PC extras
- + *
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Xiang Yu <xiangy@lemote.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/err.h>
- +#include <linux/platform_device.h>
- +#include <linux/backlight.h> /* for backlight subdriver */
- +#include <linux/fb.h>
- +#include <linux/video_output.h> /* for video output subdriver */
- +#include <linux/delay.h> /* for suspend support */
- +
- +#include <cs5536/cs5536.h>
- +#include <cs5536/cs5536_mfgpt.h>
- +
- +#include <loongson.h>
- +
- +static u32 gpio_base, mfgpt_base;
- +
- +static void set_gpio_reg_high(int gpio, int reg)
- +{
- + u32 val;
- +
- + val = inl(gpio_base + reg);
- + val |= (1 << gpio);
- + val &= ~(1 << (16 + gpio));
- + outl(val, gpio_base + reg);
- + mmiowb();
- +}
- +
- +static void set_gpio_reg_low(int gpio, int reg)
- +{
- + u32 val;
- +
- + val = inl(gpio_base + reg);
- + val |= (1 << (16 + gpio));
- + val &= ~(1 << gpio);
- + outl(val, gpio_base + reg);
- + mmiowb();
- +}
- +
- +static void set_gpio_output_low(int gpio)
- +{
- + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
- + set_gpio_reg_low(gpio, GPIOL_OUT_VAL);
- +}
- +
- +static void set_gpio_output_high(int gpio)
- +{
- + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
- + set_gpio_reg_high(gpio, GPIOL_OUT_VAL);
- +}
- +
- +/* backlight subdriver */
- +
- +#define MAX_BRIGHTNESS 100
- +#define DEFAULT_BRIGHTNESS 50
- +#define MIN_BRIGHTNESS 0
- +static unsigned int level;
- +
- +DEFINE_SPINLOCK(backlight_lock);
- +/* Tune the brightness */
- +static void setup_mfgpt2(void)
- +{
- + unsigned long flags;
- +
- + spin_lock_irqsave(&backlight_lock, flags);
- +
- + /* Set MFGPT2 comparator 1,2 */
- + outw(MAX_BRIGHTNESS-level, MFGPT2_CMP1);
- + outw(MAX_BRIGHTNESS, MFGPT2_CMP2);
- + /* Clear MFGPT2 UP COUNTER */
- + outw(0, MFGPT2_CNT);
- + /* Enable counter, compare mode, 32k */
- + outw(0x8280, MFGPT2_SETUP);
- +
- + spin_unlock_irqrestore(&backlight_lock, flags);
- +}
- +
- +static int lynloong_set_brightness(struct backlight_device *bd)
- +{
- + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
- + bd->props.power == FB_BLANK_UNBLANK) ?
- + bd->props.brightness : 0;
- +
- + if (level > MAX_BRIGHTNESS)
- + level = MAX_BRIGHTNESS;
- + else if (level < MIN_BRIGHTNESS)
- + level = MIN_BRIGHTNESS;
- +
- + setup_mfgpt2();
- +
- + return 0;
- +}
- +
- +static int lynloong_get_brightness(struct backlight_device *bd)
- +{
- + return level;
- +}
- +
- +static struct backlight_ops backlight_ops = {
- + .get_brightness = lynloong_get_brightness,
- + .update_status = lynloong_set_brightness,
- +};
- +
- +static struct backlight_device *lynloong_backlight_dev;
- +
- +static int lynloong_backlight_init(void)
- +{
- + int ret;
- + u32 hi;
- + struct backlight_properties props;
- +
- + /* Get gpio_base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
- + /* Get mfgpt_base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base);
- + /* Get gpio_base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
- +
- + /* Select for mfgpt */
- + set_gpio_reg_high(7, GPIOL_OUT_AUX1_SEL);
- + /* Enable brightness controlling */
- + set_gpio_output_high(7);
- +
- + memset(&props, 0, sizeof(struct backlight_properties));
- + props.max_brightness = MAX_BRIGHTNESS;
- + lynloong_backlight_dev = backlight_device_register("backlight0", NULL,
- + NULL, &backlight_ops, &props);
- +
- + if (IS_ERR(lynloong_backlight_dev)) {
- + ret = PTR_ERR(lynloong_backlight_dev);
- + return ret;
- + }
- +
- + lynloong_backlight_dev->props.brightness = DEFAULT_BRIGHTNESS;
- + backlight_update_status(lynloong_backlight_dev);
- +
- + return 0;
- +}
- +
- +static void lynloong_backlight_exit(void)
- +{
- + if (lynloong_backlight_dev) {
- + backlight_device_unregister(lynloong_backlight_dev);
- + lynloong_backlight_dev = NULL;
- + }
- + /* Disable brightness controlling */
- + set_gpio_output_low(7);
- +}
- +
- +/* video output driver */
- +static int vo_status = 1;
- +
- +static int lcd_video_output_get(struct output_device *od)
- +{
- + return vo_status;
- +}
- +
- +static int lcd_video_output_set(struct output_device *od)
- +{
- + int i;
- + unsigned long status;
- +
- + status = !!od->request_state;
- +
- + if (status == 0) {
- + /* Set the current status as off */
- + vo_status = 0;
- + /* Turn off the backlight */
- + set_gpio_output_low(11);
- + for (i = 0; i < 0x500; i++)
- + delay();
- + /* Turn off the LCD */
- + set_gpio_output_high(8);
- + } else {
- + /* Turn on the LCD */
- + set_gpio_output_low(8);
- + for (i = 0; i < 0x500; i++)
- + delay();
- + /* Turn on the backlight */
- + set_gpio_output_high(11);
- + /* Set the current status as on */
- + vo_status = 1;
- + }
- +
- + return 0;
- +}
- +
- +static struct output_properties lcd_output_properties = {
- + .set_state = lcd_video_output_set,
- + .get_status = lcd_video_output_get,
- +};
- +
- +static struct output_device *lcd_output_dev;
- +
- +static void lynloong_lcd_vo_set(int status)
- +{
- + lcd_output_dev->request_state = status;
- + lcd_video_output_set(lcd_output_dev);
- +}
- +
- +static int lynloong_vo_init(void)
- +{
- + int ret;
- +
- + /* Register video output device: lcd */
- + lcd_output_dev = video_output_register("LCD", NULL, NULL,
- + &lcd_output_properties);
- +
- + if (IS_ERR(lcd_output_dev)) {
- + ret = PTR_ERR(lcd_output_dev);
- + lcd_output_dev = NULL;
- + return ret;
- + }
- + /* Ensure LCD is on by default */
- + lynloong_lcd_vo_set(1);
- +
- + return 0;
- +}
- +
- +static void lynloong_vo_exit(void)
- +{
- + if (lcd_output_dev) {
- + video_output_unregister(lcd_output_dev);
- + lcd_output_dev = NULL;
- + }
- +}
- +
- +/* suspend support */
- +
- +#ifdef CONFIG_PM
- +
- +static u32 smb_base;
- +
- +/* I2C operations */
- +
- +static int i2c_wait(void)
- +{
- + char c;
- + int i;
- +
- + udelay(1000);
- + for (i = 0; i < 20; i++) {
- + c = inb(smb_base | SMB_STS);
- + if (c & (SMB_STS_BER | SMB_STS_NEGACK))
- + return -1;
- + if (c & SMB_STS_SDAST)
- + return 0;
- + udelay(100);
- + }
- + return -2;
- +}
- +
- +static void i2c_read_single(int addr, int regNo, char *value)
- +{
- + unsigned char c;
- +
- + /* Start condition */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
- + i2c_wait();
- +
- + /* Send slave address */
- + outb(addr & 0xfe, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Acknowledge smbus */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
- +
- + /* Send register index */
- + outb(regNo, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Acknowledge smbus */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
- +
- + /* Start condition again */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
- + i2c_wait();
- +
- + /* Send salve address again */
- + outb(1 | addr, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Acknowledge smbus */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
- +
- + /* Read data */
- + *value = inb(smb_base | SMB_SDA);
- +
- + /* Stop condition */
- + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
- + i2c_wait();
- +}
- +
- +static void i2c_write_single(int addr, int regNo, char value)
- +{
- + unsigned char c;
- +
- + /* Start condition */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
- + i2c_wait();
- + /* Send slave address */
- + outb(addr & 0xfe, smb_base | SMB_SDA);
- + i2c_wait();;
- +
- + /* Send register index */
- + outb(regNo, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Write data */
- + outb(value, smb_base | SMB_SDA);
- + i2c_wait();
- + /* Stop condition */
- + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
- + i2c_wait();
- +}
- +
- +static void stop_clock(int clk_reg, int clk_sel)
- +{
- + u8 value;
- +
- + i2c_read_single(0xd3, clk_reg, &value);
- + value &= ~(1 << clk_sel);
- + i2c_write_single(0xd2, clk_reg, value);
- +}
- +
- +static void enable_clock(int clk_reg, int clk_sel)
- +{
- + u8 value;
- +
- + i2c_read_single(0xd3, clk_reg, &value);
- + value |= (1 << clk_sel);
- + i2c_write_single(0xd2, clk_reg, value);
- +}
- +
- +static char cached_clk_freq;
- +static char cached_pci_fixed_freq;
- +
- +static void decrease_clk_freq(void)
- +{
- + char value;
- +
- + i2c_read_single(0xd3, 1, &value);
- + cached_clk_freq = value;
- +
- + /* Select frequency by software */
- + value |= (1 << 1);
- + /* CPU, 3V66, PCI : 100, 66, 33(1) */
- + value |= (1 << 2);
- + i2c_write_single(0xd2, 1, value);
- +
- + /* Cache the pci frequency */
- + i2c_read_single(0xd3, 14, &value);
- + cached_pci_fixed_freq = value;
- +
- + /* Enable PCI fix mode */
- + value |= (1 << 5);
- + /* 3V66, PCI : 64MHz, 32MHz */
- + value |= (1 << 3);
- + i2c_write_single(0xd2, 14, value);
- +
- +}
- +
- +static void resume_clk_freq(void)
- +{
- + i2c_write_single(0xd2, 1, cached_clk_freq);
- + i2c_write_single(0xd2, 14, cached_pci_fixed_freq);
- +}
- +
- +static void stop_clocks(void)
- +{
- + /* CPU Clock Register */
- + stop_clock(2, 5); /* not used */
- + stop_clock(2, 6); /* not used */
- + stop_clock(2, 7); /* not used */
- +
- + /* PCI Clock Register */
- + stop_clock(3, 1); /* 8100 */
- + stop_clock(3, 5); /* SIS */
- + stop_clock(3, 0); /* not used */
- + stop_clock(3, 6); /* not used */
- +
- + /* PCI 48M Clock Register */
- + stop_clock(4, 6); /* USB grounding */
- + stop_clock(4, 5); /* REF(5536_14M) */
- +
- + /* 3V66 Control Register */
- + stop_clock(5, 0); /* VCH_CLK..., grounding */
- +}
- +
- +static void enable_clocks(void)
- +{
- + enable_clock(3, 1); /* 8100 */
- + enable_clock(3, 5); /* SIS */
- +
- + enable_clock(4, 6);
- + enable_clock(4, 5); /* REF(5536_14M) */
- +
- + enable_clock(5, 0); /* VCH_CLOCK, grounding */
- +}
- +
- +static int lynloong_suspend(struct device *dev)
- +{
- + /* Disable AMP */
- + set_gpio_output_high(6);
- + /* Turn off LCD */
- + lynloong_lcd_vo_set(0);
- +
- + /* Stop the clocks of some devices */
- + stop_clocks();
- +
- + /* Decrease the external clock frequency */
- + decrease_clk_freq();
- +
- + return 0;
- +}
- +
- +static int lynloong_resume(struct device *dev)
- +{
- + /* Turn on the LCD */
- + lynloong_lcd_vo_set(1);
- +
- + /* Resume clock frequency, enable the relative clocks */
- + resume_clk_freq();
- + enable_clocks();
- +
- + /* Enable AMP */
- + set_gpio_output_low(6);
- +
- + return 0;
- +}
- +
- +static const SIMPLE_DEV_PM_OPS(lynloong_pm_ops, lynloong_suspend,
- + lynloong_resume);
- +#endif /* !CONFIG_PM */
- +
- +static struct platform_device_id platform_device_ids[] = {
- + {
- + .name = "lynloong_pc",
- + },
- + {}
- +};
- +
- +MODULE_DEVICE_TABLE(platform, platform_device_ids);
- +
- +static struct platform_driver platform_driver = {
- + .driver = {
- + .name = "lynloong_pc",
- + .owner = THIS_MODULE,
- +#ifdef CONFIG_PM
- + .pm = &lynloong_pm_ops,
- +#endif
- + },
- + .id_table = platform_device_ids,
- +};
- +
- +static int __init lynloong_init(void)
- +{
- + int ret;
- +
- + pr_info("Load LynLoong Platform Specific Driver.\n");
- +
- + /* Register platform stuff */
- + ret = platform_driver_register(&platform_driver);
- + if (ret) {
- + pr_err("Fail to register lynloong platform driver.\n");
- + return ret;
- + }
- +
- + ret = lynloong_backlight_init();
- + if (ret) {
- + pr_err("Fail to register lynloong backlight driver.\n");
- + return ret;
- + }
- +
- + ret = lynloong_vo_init();
- + if (ret) {
- + pr_err("Fail to register lynloong backlight driver.\n");
- + lynloong_vo_exit();
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +static void __exit lynloong_exit(void)
- +{
- + lynloong_vo_exit();
- + lynloong_backlight_exit();
- + platform_driver_unregister(&platform_driver);
- +
- + pr_info("Unload LynLoong Platform Specific Driver.\n");
- +}
- +
- +module_init(lynloong_init);
- +module_exit(lynloong_exit);
- +
- +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Xiang Yu <xiangy@lemote.com>");
- +MODULE_DESCRIPTION("LynLoong PC driver");
- +MODULE_LICENSE("GPL");
- diff -Nur linux-2.6.37.orig/drivers/platform/mips/yeeloong_ecrom.c linux-2.6.37/drivers/platform/mips/yeeloong_ecrom.c
- --- linux-2.6.37.orig/drivers/platform/mips/yeeloong_ecrom.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/drivers/platform/mips/yeeloong_ecrom.c 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,943 @@
- +/*
- + * Driver for flushing/dumping ROM of EC on YeeLoong laptop
- + *
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: liujl <liujl@lemote.com>
- + *
- + * NOTE :
- + * The EC resources accessing and programming are supported.
- + */
- +
- +#include <linux/proc_fs.h>
- +#include <linux/miscdevice.h>
- +#include <linux/init.h>
- +#include <linux/delay.h>
- +
- +#include <ec_kb3310b.h>
- +
- +#define EC_MISC_DEV "ec_misc"
- +#define EC_IOC_MAGIC 'E'
- +
- +/* ec registers range */
- +#define EC_MAX_REGADDR 0xFFFF
- +#define EC_MIN_REGADDR 0xF000
- +#define EC_RAM_ADDR 0xF800
- +
- +/* version burned address */
- +#define VER_ADDR 0xf7a1
- +#define VER_MAX_SIZE 7
- +#define EC_ROM_MAX_SIZE 0x10000
- +
- +/* ec internal register */
- +#define REG_POWER_MODE 0xF710
- +#define FLAG_NORMAL_MODE 0x00
- +#define FLAG_IDLE_MODE 0x01
- +#define FLAG_RESET_MODE 0x02
- +
- +/* ec update program flag */
- +#define PROGRAM_FLAG_NONE 0x00
- +#define PROGRAM_FLAG_IE 0x01
- +#define PROGRAM_FLAG_ROM 0x02
- +
- +/* XBI relative registers */
- +#define REG_XBISEG0 0xFEA0
- +#define REG_XBISEG1 0xFEA1
- +#define REG_XBIRSV2 0xFEA2
- +#define REG_XBIRSV3 0xFEA3
- +#define REG_XBIRSV4 0xFEA4
- +#define REG_XBICFG 0xFEA5
- +#define REG_XBICS 0xFEA6
- +#define REG_XBIWE 0xFEA7
- +#define REG_XBISPIA0 0xFEA8
- +#define REG_XBISPIA1 0xFEA9
- +#define REG_XBISPIA2 0xFEAA
- +#define REG_XBISPIDAT 0xFEAB
- +#define REG_XBISPICMD 0xFEAC
- +#define REG_XBISPICFG 0xFEAD
- +#define REG_XBISPIDATR 0xFEAE
- +#define REG_XBISPICFG2 0xFEAF
- +
- +/* commands definition for REG_XBISPICMD */
- +#define SPICMD_WRITE_STATUS 0x01
- +#define SPICMD_BYTE_PROGRAM 0x02
- +#define SPICMD_READ_BYTE 0x03
- +#define SPICMD_WRITE_DISABLE 0x04
- +#define SPICMD_READ_STATUS 0x05
- +#define SPICMD_WRITE_ENABLE 0x06
- +#define SPICMD_HIGH_SPEED_READ 0x0B
- +#define SPICMD_POWER_DOWN 0xB9
- +#define SPICMD_SST_EWSR 0x50
- +#define SPICMD_SST_SEC_ERASE 0x20
- +#define SPICMD_SST_BLK_ERASE 0x52
- +#define SPICMD_SST_CHIP_ERASE 0x60
- +#define SPICMD_FRDO 0x3B
- +#define SPICMD_SEC_ERASE 0xD7
- +#define SPICMD_BLK_ERASE 0xD8
- +#define SPICMD_CHIP_ERASE 0xC7
- +
- +/* bits definition for REG_XBISPICFG */
- +#define SPICFG_AUTO_CHECK 0x01
- +#define SPICFG_SPI_BUSY 0x02
- +#define SPICFG_DUMMY_READ 0x04
- +#define SPICFG_EN_SPICMD 0x08
- +#define SPICFG_LOW_SPICS 0x10
- +#define SPICFG_EN_SHORT_READ 0x20
- +#define SPICFG_EN_OFFSET_READ 0x40
- +#define SPICFG_EN_FAST_READ 0x80
- +
- +/* watchdog timer registers */
- +#define REG_WDTCFG 0xfe80
- +#define REG_WDTPF 0xfe81
- +#define REG_WDT 0xfe82
- +
- +/* lpc configure register */
- +#define REG_LPCCFG 0xfe95
- +
- +/* 8051 reg */
- +#define REG_PXCFG 0xff14
- +
- +/* Fan register in KB3310 */
- +#define REG_ECFAN_SPEED_LEVEL 0xf4e4
- +#define REG_ECFAN_SWITCH 0xf4d2
- +
- +/* the ec flash rom id number */
- +#define EC_ROM_PRODUCT_ID_SPANSION 0x01
- +#define EC_ROM_PRODUCT_ID_MXIC 0xC2
- +#define EC_ROM_PRODUCT_ID_AMIC 0x37
- +#define EC_ROM_PRODUCT_ID_EONIC 0x1C
- +
- +/* misc ioctl operations */
- +#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int)
- +#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int)
- +#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int)
- +#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int)
- +#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int)
- +
- +/* start address for programming of EC content or IE */
- +/* ec running code start address */
- +#define EC_START_ADDR 0x00000000
- +/* ec information element storing address */
- +#define IE_START_ADDR 0x00020000
- +
- +/* EC state */
- +#define EC_STATE_IDLE 0x00 /* ec in idle state */
- +#define EC_STATE_BUSY 0x01 /* ec in busy state */
- +
- +/* timeout value for programming */
- +#define EC_FLASH_TIMEOUT 0x1000 /* ec program timeout */
- +/* command checkout timeout including cmd to port or state flag check */
- +#define EC_CMD_TIMEOUT 0x1000
- +#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) /* unit : us */
- +#define EC_MAX_DELAY_UNIT (10) /* every time for polling */
- +#define SPI_FINISH_WAIT_TIME 10
- +/* EC content max size */
- +#define EC_CONTENT_MAX_SIZE (64 * 1024)
- +#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR)
- +
- +/* the register operation access struct */
- +struct ec_reg {
- + u32 addr; /* the address of kb3310 registers */
- + u8 val; /* the register value */
- +};
- +
- +struct ec_info {
- + u32 start_addr;
- + u32 size;
- + u8 *buf;
- +};
- +
- +/* open for using rom protection action */
- +#define EC_ROM_PROTECTION
- +
- +/* enable the chip reset mode */
- +static int ec_init_reset_mode(void)
- +{
- + int timeout;
- + unsigned char status = 0;
- + int ret = 0;
- +
- + /* make chip goto reset mode */
- + ret = ec_query_seq(CMD_INIT_RESET_MODE);
- + if (ret < 0) {
- + printk(KERN_ERR "ec init reset mode failed.\n");
- + goto out;
- + }
- +
- + /* make the action take active */
- + timeout = EC_CMD_TIMEOUT;
- + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
- + while (timeout--) {
- + if (status) {
- + udelay(EC_REG_DELAY);
- + break;
- + }
- + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
- + udelay(EC_REG_DELAY);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR "ec rom fixup : can't check reset status.\n");
- + ret = -EINVAL;
- + } else
- + printk(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout,
- + EC_CMD_TIMEOUT - timeout, status);
- +
- + /* set MCU to reset mode */
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_PXCFG);
- + status |= (1 << 0);
- + ec_write(REG_PXCFG, status);
- + udelay(EC_REG_DELAY);
- +
- + /* disable FWH/LPC */
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_LPCCFG);
- + status &= ~(1 << 7);
- + ec_write(REG_LPCCFG, status);
- + udelay(EC_REG_DELAY);
- +
- + printk(KERN_INFO "entering reset mode ok..............\n");
- +
- + out:
- + return ret;
- +}
- +
- +/* make ec exit from reset mode */
- +static void ec_exit_reset_mode(void)
- +{
- + unsigned char regval;
- +
- + udelay(EC_REG_DELAY);
- + regval = ec_read(REG_LPCCFG);
- + regval |= (1 << 7);
- + ec_write(REG_LPCCFG, regval);
- + regval = ec_read(REG_PXCFG);
- + regval &= ~(1 << 0);
- + ec_write(REG_PXCFG, regval);
- + printk(KERN_INFO "exit reset mode ok..................\n");
- +
- + return;
- +}
- +
- +/* make ec disable WDD */
- +static void ec_disable_WDD(void)
- +{
- + unsigned char status;
- +
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_WDTCFG);
- + ec_write(REG_WDTPF, 0x03);
- + ec_write(REG_WDTCFG, (status & 0x80) | 0x48);
- + printk(KERN_INFO "Disable WDD ok..................\n");
- +
- + return;
- +}
- +
- +/* make ec enable WDD */
- +static void ec_enable_WDD(void)
- +{
- + unsigned char status;
- +
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_WDTCFG);
- + ec_write(REG_WDT, 0x28); /* set WDT 5sec(0x28) */
- + ec_write(REG_WDTCFG, (status & 0x80) | 0x03);
- + printk(KERN_INFO "Enable WDD ok..................\n");
- +
- + return;
- +}
- +
- +/* make ec goto idle mode */
- +static int ec_init_idle_mode(void)
- +{
- + int timeout;
- + unsigned char status = 0;
- + int ret = 0;
- +
- + ec_query_seq(CMD_INIT_IDLE_MODE);
- +
- + /* make the action take active */
- + timeout = EC_CMD_TIMEOUT;
- + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
- + while (timeout--) {
- + if (status) {
- + udelay(EC_REG_DELAY);
- + break;
- + }
- + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
- + udelay(EC_REG_DELAY);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR "ec rom fixup : can't check out the status.\n");
- + ret = -EINVAL;
- + } else
- + printk(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout,
- + EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE));
- +
- + printk(KERN_INFO "entering idle mode ok...................\n");
- +
- + return ret;
- +}
- +
- +/* make ec exit from idle mode */
- +static int ec_exit_idle_mode(void)
- +{
- +
- + ec_query_seq(CMD_EXIT_IDLE_MODE);
- +
- + printk(KERN_INFO "exit idle mode ok...................\n");
- +
- + return 0;
- +}
- +
- +static int ec_instruction_cycle(void)
- +{
- + unsigned long timeout;
- + int ret = 0;
- +
- + timeout = EC_FLASH_TIMEOUT;
- + while (timeout-- >= 0) {
- + if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY))
- + break;
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR
- + "EC_INSTRUCTION_CYCLE : timeout for check flag.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + out:
- + return ret;
- +}
- +
- +/* To see if the ec is in busy state or not. */
- +static inline int ec_flash_busy(unsigned long timeout)
- +{
- + /* assurance the first command be going to rom */
- + if (ec_instruction_cycle() < 0)
- + return EC_STATE_BUSY;
- +#if 1
- + timeout = timeout / EC_MAX_DELAY_UNIT;
- + while (timeout-- > 0) {
- + /* check the rom's status of busy flag */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (ec_instruction_cycle() < 0)
- + return EC_STATE_BUSY;
- + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
- + return EC_STATE_IDLE;
- + udelay(EC_MAX_DELAY_UNIT);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR
- + "EC_FLASH_BUSY : timeout for check rom flag.\n");
- + return EC_STATE_BUSY;
- + }
- +#else
- + /* check the rom's status of busy flag */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (ec_instruction_cycle() < 0)
- + return EC_STATE_BUSY;
- +
- + timeout = timeout / EC_MAX_DELAY_UNIT;
- + while (timeout-- > 0) {
- + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
- + return EC_STATE_IDLE;
- + udelay(EC_MAX_DELAY_UNIT);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR
- + "EC_FLASH_BUSY : timeout for check rom flag.\n");
- + return EC_STATE_BUSY;
- + }
- +#endif
- +
- + return EC_STATE_IDLE;
- +}
- +
- +static int rom_instruction_cycle(unsigned char cmd)
- +{
- + unsigned long timeout = 0;
- +
- + switch (cmd) {
- + case SPICMD_READ_STATUS:
- + case SPICMD_WRITE_ENABLE:
- + case SPICMD_WRITE_DISABLE:
- + case SPICMD_READ_BYTE:
- + case SPICMD_HIGH_SPEED_READ:
- + timeout = 0;
- + break;
- + case SPICMD_WRITE_STATUS:
- + timeout = 300 * 1000;
- + break;
- + case SPICMD_BYTE_PROGRAM:
- + timeout = 5 * 1000;
- + break;
- + case SPICMD_SST_SEC_ERASE:
- + case SPICMD_SEC_ERASE:
- + timeout = 1000 * 1000;
- + break;
- + case SPICMD_SST_BLK_ERASE:
- + case SPICMD_BLK_ERASE:
- + timeout = 3 * 1000 * 1000;
- + break;
- + case SPICMD_SST_CHIP_ERASE:
- + case SPICMD_CHIP_ERASE:
- + timeout = 20 * 1000 * 1000;
- + break;
- + default:
- + timeout = EC_SPICMD_STANDARD_TIMEOUT;
- + }
- + if (timeout == 0)
- + return ec_instruction_cycle();
- + if (timeout < EC_SPICMD_STANDARD_TIMEOUT)
- + timeout = EC_SPICMD_STANDARD_TIMEOUT;
- +
- + return ec_flash_busy(timeout);
- +}
- +
- +/* delay for start/stop action */
- +static void delay_spi(int n)
- +{
- + while (n--)
- + inb(EC_IO_PORT_HIGH);
- +}
- +
- +/* start the action to spi rom function */
- +static void ec_start_spi(void)
- +{
- + unsigned char val;
- +
- + delay_spi(SPI_FINISH_WAIT_TIME);
- + val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK;
- + ec_write(REG_XBISPICFG, val);
- + delay_spi(SPI_FINISH_WAIT_TIME);
- +}
- +
- +/* stop the action to spi rom function */
- +static void ec_stop_spi(void)
- +{
- + unsigned char val;
- +
- + delay_spi(SPI_FINISH_WAIT_TIME);
- + val =
- + ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK));
- + ec_write(REG_XBISPICFG, val);
- + delay_spi(SPI_FINISH_WAIT_TIME);
- +}
- +
- +/* read one byte from xbi interface */
- +static int ec_read_byte(unsigned int addr, unsigned char *byte)
- +{
- + int ret = 0;
- +
- + /* enable spicmd writing. */
- + ec_start_spi();
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + /* write the address */
- + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
- + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
- + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
- + /* start action */
- + ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ);
- + if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + *byte = ec_read(REG_XBISPIDAT);
- +
- + out:
- + /* disable spicmd writing. */
- + ec_stop_spi();
- +
- + return ret;
- +}
- +
- +/* write one byte to ec rom */
- +static int ec_write_byte(unsigned int addr, unsigned char byte)
- +{
- + int ret = 0;
- +
- + /* enable spicmd writing. */
- + ec_start_spi();
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + /* write the address */
- + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
- + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
- + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
- + ec_write(REG_XBISPIDAT, byte);
- + /* start action */
- + ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM);
- + if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + out:
- + /* disable spicmd writing. */
- + ec_stop_spi();
- +
- + return ret;
- +}
- +
- +/* unprotect SPI ROM */
- +/* EC_ROM_unprotect function code */
- +static int EC_ROM_unprotect(void)
- +{
- + unsigned char status;
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
- + return 1;
- + }
- +
- + /* unprotect the status register of rom */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n");
- + return 1;
- + }
- + status = ec_read(REG_XBISPIDAT);
- + ec_write(REG_XBISPIDAT, status & 0x02);
- + if (ec_instruction_cycle() < 0) {
- + printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n");
- + return 1;
- + }
- +
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
- + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n");
- + return 1;
- + }
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
- + return 1;
- + }
- +
- + return 0;
- +}
- +
- +/* erase one block or chip or sector as needed */
- +static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr)
- +{
- + unsigned char status;
- + int ret = 0, i = 0;
- + int unprotect_count = 3;
- + int check_flag = 0;
- +
- + /* enable spicmd writing. */
- + ec_start_spi();
- +
- +#ifdef EC_ROM_PROTECTION
- + /* added for re-check SPICMD_READ_STATUS */
- + while (unprotect_count-- > 0) {
- + if (EC_ROM_unprotect()) {
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + /* first time:500ms --> 5.5sec -->10.5sec */
- + for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++)
- + udelay(50000);
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (rom_instruction_cycle(SPICMD_READ_STATUS)
- + == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
- + } else {
- + status = ec_read(REG_XBISPIDAT);
- + printk(KERN_INFO "Read unprotect status : 0x%x\n",
- + status);
- + if ((status & 0x1C) == 0x00) {
- + printk(KERN_INFO
- + "Read unprotect status OK1 : 0x%x\n",
- + status & 0x1C);
- + check_flag = 1;
- + break;
- + }
- + }
- + }
- +
- + if (!check_flag) {
- + printk(KERN_INFO "SPI ROM unprotect fail.\n");
- + return 1;
- + }
- +#endif
- +
- + /* block address fill */
- + if (erase_cmd == SPICMD_BLK_ERASE) {
- + ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16);
- + ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8);
- + ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0);
- + }
- +
- + /* erase the whole chip first */
- + ec_write(REG_XBISPICMD, erase_cmd);
- + if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) {
- + printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + out:
- + /* disable spicmd writing. */
- + ec_stop_spi();
- +
- + return ret;
- +}
- +
- +/* update the whole rom content with H/W mode
- + * PLEASE USING ec_unit_erase() FIRSTLY
- + */
- +static int ec_program_rom(struct ec_info *info, int flag)
- +{
- + unsigned int addr = 0;
- + unsigned long size = 0;
- + unsigned char *ptr = NULL;
- + unsigned char data;
- + unsigned char val = 0;
- + int ret = 0;
- + int i, j;
- + unsigned char status;
- +
- + /* modify for program serial No.
- + * set IE_START_ADDR & use idle mode,
- + * disable WDD
- + */
- + if (flag == PROGRAM_FLAG_ROM) {
- + ret = ec_init_reset_mode();
- + addr = info->start_addr + EC_START_ADDR;
- + printk(KERN_INFO "PROGRAM_FLAG_ROM..............\n");
- + } else if (flag == PROGRAM_FLAG_IE) {
- + ret = ec_init_idle_mode();
- + ec_disable_WDD();
- + addr = info->start_addr + IE_START_ADDR;
- + printk(KERN_INFO "PROGRAM_FLAG_IE..............\n");
- + } else {
- + return 0;
- + }
- +
- + if (ret < 0) {
- + if (flag == PROGRAM_FLAG_IE)
- + ec_enable_WDD();
- + return ret;
- + }
- +
- + size = info->size;
- + ptr = info->buf;
- + printk(KERN_INFO "starting update ec ROM..............\n");
- +
- + ret = ec_unit_erase(SPICMD_BLK_ERASE, addr);
- + if (ret) {
- + printk(KERN_ERR "program ec : erase block failed.\n");
- + goto out;
- + }
- + printk(KERN_ERR "program ec : erase block OK.\n");
- +
- + i = 0;
- + while (i < size) {
- + data = *(ptr + i);
- + ec_write_byte(addr, data);
- + ec_read_byte(addr, &val);
- + if (val != data) {
- + ec_write_byte(addr, data);
- + ec_read_byte(addr, &val);
- + if (val != data) {
- + printk(KERN_INFO
- + "EC : Second flash program failed at:\t");
- + printk(KERN_INFO
- + "addr : 0x%x, source : 0x%x, dest: 0x%x\n",
- + addr, data, val);
- + printk(KERN_INFO "This should not happen... STOP\n");
- + break;
- + }
- + }
- + i++;
- + addr++;
- + }
- +
- +#ifdef EC_ROM_PROTECTION
- + /* we should start spi access firstly */
- + ec_start_spi();
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n");
- + goto out1;
- + }
- +
- + /* protect the status register of rom */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
- + goto out1;
- + }
- + status = ec_read(REG_XBISPIDAT);
- +
- + ec_write(REG_XBISPIDAT, status | 0x1C);
- + if (ec_instruction_cycle() < 0) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : write status value failed.\n");
- + goto out1;
- + }
- +
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
- + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n");
- + goto out1;
- + }
- +#endif
- +
- + /* disable the write action to spi rom */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n");
- + goto out1;
- + }
- +
- + out1:
- + /* we should stop spi access firstly */
- + ec_stop_spi();
- + out:
- + /* for security */
- + for (j = 0; j < 2000; j++)
- + udelay(1000);
- +
- + /* modify for program serial No.
- + * after program No exit idle mode
- + * and enable WDD
- + */
- + if (flag == PROGRAM_FLAG_ROM) {
- + /* exit from the reset mode */
- + ec_exit_reset_mode();
- + } else {
- + /* ec exit from idle mode */
- + ret = ec_exit_idle_mode();
- + ec_enable_WDD();
- + if (ret < 0)
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +/* ioctl */
- +static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd,
- + u_long arg)
- +{
- + struct ec_info ecinfo;
- + void __user *ptr = (void __user *)arg;
- + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
- + int ret = 0;
- +
- + switch (cmd) {
- + case IOCTL_RDREG:
- + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "reg read : copy from user error.\n");
- + return -EFAULT;
- + }
- + if ((ecreg->addr > EC_MAX_REGADDR)
- + || (ecreg->addr < EC_MIN_REGADDR)) {
- + printk(KERN_ERR
- + "reg read : out of register address range.\n");
- + return -EINVAL;
- + }
- + ecreg->val = ec_read(ecreg->addr);
- + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "reg read : copy to user error.\n");
- + return -EFAULT;
- + }
- + break;
- + case IOCTL_WRREG:
- + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "reg write : copy from user error.\n");
- + return -EFAULT;
- + }
- + if ((ecreg->addr > EC_MAX_REGADDR)
- + || (ecreg->addr < EC_MIN_REGADDR)) {
- + printk(KERN_ERR
- + "reg write : out of register address range.\n");
- + return -EINVAL;
- + }
- + ec_write(ecreg->addr, ecreg->val);
- + break;
- + case IOCTL_READ_EC:
- + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "spi read : copy from user error.\n");
- + return -EFAULT;
- + }
- + if ((ecreg->addr > EC_RAM_ADDR)
- + && (ecreg->addr < EC_MAX_REGADDR)) {
- + printk(KERN_ERR
- + "spi read : out of register address range.\n");
- + return -EINVAL;
- + }
- + ec_read_byte(ecreg->addr, &(ecreg->val));
- + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "spi read : copy to user error.\n");
- + return -EFAULT;
- + }
- + break;
- + case IOCTL_PROGRAM_IE:
- + ecinfo.start_addr = EC_START_ADDR;
- + ecinfo.size = EC_CONTENT_MAX_SIZE;
- + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
- + if (ecinfo.buf == NULL) {
- + printk(KERN_ERR "program ie : kmalloc failed.\n");
- + return -ENOMEM;
- + }
- + ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size);
- + if (ret) {
- + printk(KERN_ERR "program ie : copy from user error.\n");
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + return -EFAULT;
- + }
- +
- + /* use ec_program_rom to write serial No */
- + ec_program_rom(&ecinfo, PROGRAM_FLAG_IE);
- +
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + break;
- + case IOCTL_PROGRAM_EC:
- + ecinfo.start_addr = EC_START_ADDR;
- + if (get_user((ecinfo.size), (u32 *) ptr)) {
- + printk(KERN_ERR "program ec : get user error.\n");
- + return -EFAULT;
- + }
- + if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) {
- + printk(KERN_ERR "program ec : size out of limited.\n");
- + return -EINVAL;
- + }
- + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
- + if (ecinfo.buf == NULL) {
- + printk(KERN_ERR "program ec : kmalloc failed.\n");
- + return -ENOMEM;
- + }
- + ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size);
- + if (ret) {
- + printk(KERN_ERR "program ec : copy from user error.\n");
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + return -EFAULT;
- + }
- +
- + ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM);
- +
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + break;
- +
- + default:
- + break;
- + }
- +
- + return 0;
- +}
- +
- +static long misc_compat_ioctl(struct file *file, unsigned int cmd,
- + unsigned long arg)
- +{
- + return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
- +}
- +
- +static int misc_open(struct inode *inode, struct file *filp)
- +{
- + struct ec_reg *ecreg = NULL;
- + ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL);
- + if (ecreg)
- + filp->private_data = ecreg;
- +
- + return ecreg ? 0 : -ENOMEM;
- +}
- +
- +static int misc_release(struct inode *inode, struct file *filp)
- +{
- + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
- +
- + filp->private_data = NULL;
- + kfree(ecreg);
- +
- + return 0;
- +}
- +
- +static const struct file_operations ecmisc_fops = {
- + .open = misc_open,
- + .release = misc_release,
- + .read = NULL,
- + .write = NULL,
- +#ifdef CONFIG_64BIT
- + .compat_ioctl = misc_compat_ioctl,
- +#else
- + .ioctl = misc_ioctl,
- +#endif
- +};
- +
- +static struct miscdevice ecmisc_device = {
- + .minor = MISC_DYNAMIC_MINOR,
- + .name = EC_MISC_DEV,
- + .fops = &ecmisc_fops
- +};
- +
- +static int __init ecmisc_init(void)
- +{
- + int ret;
- +
- + printk(KERN_INFO "EC misc device init.\n");
- + ret = misc_register(&ecmisc_device);
- +
- + return ret;
- +}
- +
- +static void __exit ecmisc_exit(void)
- +{
- + printk(KERN_INFO "EC misc device exit.\n");
- + misc_deregister(&ecmisc_device);
- +}
- +
- +module_init(ecmisc_init);
- +module_exit(ecmisc_exit);
- +
- +MODULE_AUTHOR("liujl <liujl@lemote.com>");
- +MODULE_DESCRIPTION("Driver for flushing/dumping ROM of EC on YeeLoong laptop");
- +MODULE_LICENSE("GPL");
- diff -Nur linux-2.6.37.orig/drivers/platform/mips/yeeloong_laptop.c linux-2.6.37/drivers/platform/mips/yeeloong_laptop.c
- --- linux-2.6.37.orig/drivers/platform/mips/yeeloong_laptop.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.37/drivers/platform/mips/yeeloong_laptop.c 2011-01-11 20:44:43.000000000 +0100
- @@ -0,0 +1,1200 @@
- +/*
- + * Driver for YeeLoong laptop extras
- + *
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Liu Junliang <liujl@lemote.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/err.h>
- +#include <linux/platform_device.h>
- +#include <linux/backlight.h> /* for backlight subdriver */
- +#include <linux/fb.h>
- +#include <linux/hwmon.h> /* for hwmon subdriver */
- +#include <linux/hwmon-sysfs.h>
- +#include <linux/video_output.h> /* for video output subdriver */
- +#include <linux/input.h> /* for hotkey subdriver */
- +#include <linux/input/sparse-keymap.h>
- +#include <linux/interrupt.h>
- +#include <linux/delay.h>
- +#include <linux/power_supply.h> /* for AC & Battery subdriver */
- +
- +#include <cs5536/cs5536.h>
- +
- +#include <loongson.h> /* for loongson_cmdline */
- +#include <ec_kb3310b.h>
- +
- +/* common function */
- +#define EC_VER_LEN 64
- +
- +static int ec_version_before(char *version)
- +{
- + char *p, ec_ver[EC_VER_LEN];
- +
- + p = strstr(loongson_cmdline, "EC_VER=");
- + if (!p)
- + memset(ec_ver, 0, EC_VER_LEN);
- + else {
- + strncpy(ec_ver, p, EC_VER_LEN);
- + p = strstr(ec_ver, " ");
- + if (p)
- + *p = '\0';
- + }
- +
- + return (strncasecmp(ec_ver, version, 64) < 0);
- +}
- +
- +/* backlight subdriver */
- +#define MAX_BRIGHTNESS 8
- +
- +static int yeeloong_set_brightness(struct backlight_device *bd)
- +{
- + unsigned int level, current_level;
- + static unsigned int old_level;
- +
- + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
- + bd->props.power == FB_BLANK_UNBLANK) ?
- + bd->props.brightness : 0;
- +
- + level = SENSORS_LIMIT(level, 0, MAX_BRIGHTNESS);
- +
- + /* Avoid to modify the brightness when EC is tuning it */
- + if (old_level != level) {
- + current_level = ec_read(REG_DISPLAY_BRIGHTNESS);
- + if (old_level == current_level)
- + ec_write(REG_DISPLAY_BRIGHTNESS, level);
- + old_level = level;
- + }
- +
- + return 0;
- +}
- +
- +static int yeeloong_get_brightness(struct backlight_device *bd)
- +{
- + return ec_read(REG_DISPLAY_BRIGHTNESS);
- +}
- +
- +static struct backlight_ops backlight_ops = {
- + .get_brightness = yeeloong_get_brightness,
- + .update_status = yeeloong_set_brightness,
- +};
- +
- +static struct backlight_device *yeeloong_backlight_dev;
- +
- +static int yeeloong_backlight_init(void)
- +{
- + int ret;
- + struct backlight_properties props;
- +
- + memset(&props, 0, sizeof(struct backlight_properties));
- + props.max_brightness = MAX_BRIGHTNESS;
- + yeeloong_backlight_dev = backlight_device_register("backlight0", NULL,
- + NULL, &backlight_ops, &props);
- +
- + if (IS_ERR(yeeloong_backlight_dev)) {
- + ret = PTR_ERR(yeeloong_backlight_dev);
- + yeeloong_backlight_dev = NULL;
- + return ret;
- + }
- +
- + yeeloong_backlight_dev->props.brightness =
- + yeeloong_get_brightness(yeeloong_backlight_dev);
- + backlight_update_status(yeeloong_backlight_dev);
- +
- + return 0;
- +}
- +
- +static void yeeloong_backlight_exit(void)
- +{
- + if (yeeloong_backlight_dev) {
- + backlight_device_unregister(yeeloong_backlight_dev);
- + yeeloong_backlight_dev = NULL;
- + }
- +}
- +
- +/* AC & Battery subdriver */
- +
- +static struct power_supply yeeloong_ac, yeeloong_bat;
- +
- +#define AC_OFFLINE 0
- +#define AC_ONLINE 1
- +
- +static int yeeloong_get_ac_props(struct power_supply *psy,
- + enum power_supply_property psp,
- + union power_supply_propval *val)
- +{
- + switch (psp) {
- + case POWER_SUPPLY_PROP_ONLINE:
- + val->intval = ((ec_read(REG_BAT_POWER)) & BIT_BAT_POWER_ACIN) ?
- + AC_ONLINE : AC_OFFLINE;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +static enum power_supply_property yeeloong_ac_props[] = {
- + POWER_SUPPLY_PROP_ONLINE,
- +};
- +
- +static struct power_supply yeeloong_ac = {
- + .name = "yeeloong-ac",
- + .type = POWER_SUPPLY_TYPE_MAINS,
- + .properties = yeeloong_ac_props,
- + .num_properties = ARRAY_SIZE(yeeloong_ac_props),
- + .get_property = yeeloong_get_ac_props,
- +};
- +
- +#define BAT_CAP_CRITICAL 5
- +#define BAT_CAP_HIGH 99
- +
- +#define get_bat_info(type) \
- + ((ec_read(REG_BAT_##type##_HIGH) << 8) | \
- + (ec_read(REG_BAT_##type##_LOW)))
- +
- +static int yeeloong_bat_get_ex_property(enum power_supply_property psp,
- + union power_supply_propval *val)
- +{
- + int bat_in, curr_cap, cap_level, status, charge, health;
- +
- + status = ec_read(REG_BAT_STATUS);
- + bat_in = status & BIT_BAT_STATUS_IN;
- + curr_cap = get_bat_info(RELATIVE_CAP);
- + if (status & BIT_BAT_STATUS_FULL)
- + curr_cap = 100;
- +
- + switch (psp) {
- + case POWER_SUPPLY_PROP_PRESENT:
- + val->intval = bat_in;
- + break;
- + case POWER_SUPPLY_PROP_CAPACITY:
- + val->intval = curr_cap;
- + break;
- + case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
- + if (status & BIT_BAT_STATUS_LOW) {
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
- + if (curr_cap <= BAT_CAP_CRITICAL)
- + cap_level =
- + POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
- + } else if (status & BIT_BAT_STATUS_FULL) {
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
- + if (curr_cap >= BAT_CAP_HIGH)
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
- + } else if (status & BIT_BAT_STATUS_DESTROY)
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
- + val->intval = cap_level;
- + break;
- + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
- + /* seconds */
- + val->intval = bat_in ? (curr_cap - 3) * 54 + 142 : 0;
- + break;
- + case POWER_SUPPLY_PROP_STATUS:
- + if (!bat_in)
- + charge = POWER_SUPPLY_STATUS_UNKNOWN;
- + else {
- + if (status & BIT_BAT_STATUS_FULL) {
- + val->intval = POWER_SUPPLY_STATUS_FULL;
- + break;
- + }
- +
- + charge = ec_read(REG_BAT_CHARGE);
- + if (charge & FLAG_BAT_CHARGE_DISCHARGE)
- + charge = POWER_SUPPLY_STATUS_DISCHARGING;
- + else if (charge & FLAG_BAT_CHARGE_CHARGE)
- + charge = POWER_SUPPLY_STATUS_CHARGING;
- + else
- + charge = POWER_SUPPLY_STATUS_NOT_CHARGING;
- + }
- + val->intval = charge;
- + break;
- + case POWER_SUPPLY_PROP_HEALTH:
- + if (!bat_in) /* no battery present */
- + health = POWER_SUPPLY_HEALTH_UNKNOWN;
- + else { /* Assume it is good */
- + health = POWER_SUPPLY_HEALTH_GOOD;
- + if (status &
- + (BIT_BAT_STATUS_DESTROY | BIT_BAT_STATUS_LOW))
- + health = POWER_SUPPLY_HEALTH_DEAD;
- + if (ec_read(REG_BAT_CHARGE_STATUS) &
- + BIT_BAT_CHARGE_STATUS_OVERTEMP)
- + health = POWER_SUPPLY_HEALTH_OVERHEAT;
- + }
- + val->intval = health;
- + break;
- + case POWER_SUPPLY_PROP_CHARGE_NOW: /* 1/100(%)*1000 µAh */
- + val->intval = curr_cap * get_bat_info(FULLCHG_CAP) * 10;
- + break;
- + default:
- + return -EINVAL;
- + }
- + return 0;
- +}
- +
- +static int get_battery_temp(void)
- +{
- + int value;
- +
- + value = get_bat_info(TEMPERATURE);
- +
- + return value * 1000;
- +}
- +
- +static int get_battery_current(void)
- +{
- + s16 value;
- +
- + value = get_bat_info(CURRENT);
- +
- + return -value;
- +}
- +
- +static int get_battery_voltage(void)
- +{
- + int value;
- +
- + value = get_bat_info(VOLTAGE);
- +
- + return value;
- +}
- +
- +static int yeeloong_get_bat_props(struct power_supply *psy,
- + enum power_supply_property psp,
- + union power_supply_propval *val)
- +{
- + switch (psp) {
- + /* Fixed information */
- + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- + val->intval = get_bat_info(DESIGN_VOL) * 1000; /* mV -> µV */
- + break;
- + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- + val->intval = get_bat_info(DESIGN_CAP) * 1000; /* mAh->µAh */
- + break;
- + case POWER_SUPPLY_PROP_CHARGE_FULL:
- + val->intval = get_bat_info(FULLCHG_CAP) * 1000; /* µAh */
- + break;
- + case POWER_SUPPLY_PROP_MANUFACTURER:
- + val->strval = (ec_read(REG_BAT_VENDOR) ==
- + FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO";
- + break;
- + /* Dynamic information */
- + case POWER_SUPPLY_PROP_CURRENT_NOW:
- + val->intval = get_battery_current() * 1000; /* mA -> µA */
- + break;
- + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- + val->intval = get_battery_voltage() * 1000; /* mV -> µV */
- + break;
- + case POWER_SUPPLY_PROP_TEMP:
- + val->intval = get_battery_temp(); /* Celcius */
- + break;
- + /* Dynamic but related information */
- + default:
- + return yeeloong_bat_get_ex_property(psp, val);
- + }
- +
- + return 0;
- +}
- +
- +static enum power_supply_property yeeloong_bat_props[] = {
- + POWER_SUPPLY_PROP_STATUS,
- + POWER_SUPPLY_PROP_PRESENT,
- + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
- + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
- + POWER_SUPPLY_PROP_CHARGE_FULL,
- + POWER_SUPPLY_PROP_CHARGE_NOW,
- + POWER_SUPPLY_PROP_CURRENT_NOW,
- + POWER_SUPPLY_PROP_VOLTAGE_NOW,
- + POWER_SUPPLY_PROP_HEALTH,
- + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
- + POWER_SUPPLY_PROP_CAPACITY,
- + POWER_SUPPLY_PROP_CAPACITY_LEVEL,
- + POWER_SUPPLY_PROP_TEMP,
- + POWER_SUPPLY_PROP_MANUFACTURER,
- +};
- +
- +static struct power_supply yeeloong_bat = {
- + .name = "yeeloong-bat",
- + .type = POWER_SUPPLY_TYPE_BATTERY,
- + .properties = yeeloong_bat_props,
- + .num_properties = ARRAY_SIZE(yeeloong_bat_props),
- + .get_property = yeeloong_get_bat_props,
- +};
- +
- +static int ac_bat_initialized;
- +
- +static int yeeloong_bat_init(void)
- +{
- + int ret;
- +
- + ret = power_supply_register(NULL, &yeeloong_ac);
- + if (ret)
- + return ret;
- + ret = power_supply_register(NULL, &yeeloong_bat);
- + if (ret) {
- + power_supply_unregister(&yeeloong_ac);
- + return ret;
- + }
- + ac_bat_initialized = 1;
- +
- + return 0;
- +}
- +
- +static void yeeloong_bat_exit(void)
- +{
- + ac_bat_initialized = 0;
- +
- + power_supply_unregister(&yeeloong_ac);
- + power_supply_unregister(&yeeloong_bat);
- +}
- +/* hwmon subdriver */
- +
- +#define MIN_FAN_SPEED 0
- +#define MAX_FAN_SPEED 3
- +
- +static int get_fan_pwm_enable(void)
- +{
- + int level, mode;
- +
- + level = ec_read(REG_FAN_SPEED_LEVEL);
- + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
- +
- + if (level == MAX_FAN_SPEED && mode == BIT_FAN_MANUAL)
- + mode = 0;
- + else if (mode == BIT_FAN_MANUAL)
- + mode = 1;
- + else
- + mode = 2;
- +
- + return mode;
- +}
- +
- +static void set_fan_pwm_enable(int mode)
- +{
- + switch (mode) {
- + case 0:
- + /* fullspeed */
- + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
- + ec_write(REG_FAN_SPEED_LEVEL, MAX_FAN_SPEED);
- + break;
- + case 1:
- + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
- + break;
- + case 2:
- + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_AUTO);
- + break;
- + default:
- + break;
- + }
- +}
- +
- +static int get_fan_pwm(void)
- +{
- + return ec_read(REG_FAN_SPEED_LEVEL);
- +}
- +
- +static void set_fan_pwm(int value)
- +{
- + int mode;
- +
- + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
- + if (mode != BIT_FAN_MANUAL)
- + return;
- +
- + value = SENSORS_LIMIT(value, 0, 3);
- +
- + /* We must ensure the fan is on */
- + if (value > 0)
- + ec_write(REG_FAN_CONTROL, BIT_FAN_CONTROL_ON);
- +
- + ec_write(REG_FAN_SPEED_LEVEL, value);
- +}
- +
- +static int get_fan_rpm(void)
- +{
- + int value;
- +
- + value = FAN_SPEED_DIVIDER /
- + (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) |
- + ec_read(REG_FAN_SPEED_LOW));
- +
- + return value;
- +}
- +
- +static int get_cpu_temp(void)
- +{
- + s8 value;
- +
- + value = ec_read(REG_TEMPERATURE_VALUE);
- +
- + return value * 1000;
- +}
- +
- +static int get_cpu_temp_max(void)
- +{
- + return 60 * 1000;
- +}
- +
- +static int get_battery_temp_alarm(void)
- +{
- + int status;
- +
- + status = (ec_read(REG_BAT_CHARGE_STATUS) &
- + BIT_BAT_CHARGE_STATUS_OVERTEMP);
- +
- + return !!status;
- +}
- +
- +static ssize_t store_sys_hwmon(void (*set) (int), const char *buf, size_t count)
- +{
- + int ret;
- + unsigned long value;
- +
- + if (!count)
- + return 0;
- +
- + ret = strict_strtoul(buf, 10, &value);
- + if (ret)
- + return ret;
- +
- + set(value);
- +
- + return count;
- +}
- +
- +static ssize_t show_sys_hwmon(int (*get) (void), char *buf)
- +{
- + return sprintf(buf, "%d\n", get());
- +}
- +
- +#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
- + static ssize_t show_##_name(struct device *dev, \
- + struct device_attribute *attr, \
- + char *buf) \
- + { \
- + return show_sys_hwmon(_set, buf); \
- + } \
- + static ssize_t store_##_name(struct device *dev, \
- + struct device_attribute *attr, \
- + const char *buf, size_t count) \
- + { \
- + return store_sys_hwmon(_get, buf, count); \
- + } \
- + static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
- +
- +CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
- +CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, get_fan_pwm, set_fan_pwm);
- +CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, get_fan_pwm_enable,
- + set_fan_pwm_enable);
- +CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL);
- +CREATE_SENSOR_ATTR(temp1_max, S_IRUGO, get_cpu_temp_max, NULL);
- +CREATE_SENSOR_ATTR(temp2_input, S_IRUGO, get_battery_temp, NULL);
- +CREATE_SENSOR_ATTR(temp2_max_alarm, S_IRUGO, get_battery_temp_alarm, NULL);
- +CREATE_SENSOR_ATTR(curr1_input, S_IRUGO, get_battery_current, NULL);
- +CREATE_SENSOR_ATTR(in1_input, S_IRUGO, get_battery_voltage, NULL);
- +
- +static ssize_t
- +show_name(struct device *dev, struct device_attribute *attr, char *buf)
- +{
- + return sprintf(buf, "yeeloong\n");
- +}
- +
- +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
- +
- +static struct attribute *hwmon_attributes[] = {
- + &sensor_dev_attr_pwm1.dev_attr.attr,
- + &sensor_dev_attr_pwm1_enable.dev_attr.attr,
- + &sensor_dev_attr_fan1_input.dev_attr.attr,
- + &sensor_dev_attr_temp1_input.dev_attr.attr,
- + &sensor_dev_attr_temp1_max.dev_attr.attr,
- + &sensor_dev_attr_temp2_input.dev_attr.attr,
- + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
- + &sensor_dev_attr_curr1_input.dev_attr.attr,
- + &sensor_dev_attr_in1_input.dev_attr.attr,
- + &sensor_dev_attr_name.dev_attr.attr,
- + NULL
- +};
- +
- +static struct attribute_group hwmon_attribute_group = {
- + .attrs = hwmon_attributes
- +};
- +
- +static struct device *yeeloong_hwmon_dev;
- +
- +static int yeeloong_hwmon_init(void)
- +{
- + int ret;
- +
- + yeeloong_hwmon_dev = hwmon_device_register(NULL);
- + if (IS_ERR(yeeloong_hwmon_dev)) {
- + pr_err("Fail to register yeeloong hwmon device\n");
- + yeeloong_hwmon_dev = NULL;
- + return PTR_ERR(yeeloong_hwmon_dev);
- + }
- + ret = sysfs_create_group(&yeeloong_hwmon_dev->kobj,
- + &hwmon_attribute_group);
- + if (ret) {
- + hwmon_device_unregister(yeeloong_hwmon_dev);
- + yeeloong_hwmon_dev = NULL;
- + return ret;
- + }
- + /* ensure fan is set to auto mode */
- + set_fan_pwm_enable(2);
- +
- + return 0;
- +}
- +
- +static void yeeloong_hwmon_exit(void)
- +{
- + if (yeeloong_hwmon_dev) {
- + sysfs_remove_group(&yeeloong_hwmon_dev->kobj,
- + &hwmon_attribute_group);
- + hwmon_device_unregister(yeeloong_hwmon_dev);
- + yeeloong_hwmon_dev = NULL;
- + }
- +}
- +
- +/* video output subdriver */
- +
- +static int lcd_video_output_get(struct output_device *od)
- +{
- + return ec_read(REG_DISPLAY_LCD);
- +}
- +
- +#define LCD 0
- +#define CRT 1
- +
- +static void display_vo_set(int display, int on)
- +{
- + int addr;
- + unsigned long value;
- +
- + addr = (display == LCD) ? 0x31 : 0x21;
- +
- + outb(addr, 0x3c4);
- + value = inb(0x3c5);
- +
- + if (display == LCD)
- + value |= (on ? 0x03 : 0x02);
- + else {
- + if (on)
- + clear_bit(7, &value);
- + else
- + set_bit(7, &value);
- + }
- +
- + outb(addr, 0x3c4);
- + outb(value, 0x3c5);
- +}
- +
- +static int lcd_video_output_set(struct output_device *od)
- +{
- + unsigned long status;
- +
- + status = !!od->request_state;
- +
- + display_vo_set(LCD, status);
- + ec_write(REG_BACKLIGHT_CTRL, status);
- +
- + return 0;
- +}
- +
- +static struct output_properties lcd_output_properties = {
- + .set_state = lcd_video_output_set,
- + .get_status = lcd_video_output_get,
- +};
- +
- +static int crt_video_output_get(struct output_device *od)
- +{
- + return ec_read(REG_CRT_DETECT);
- +}
- +
- +static int crt_video_output_set(struct output_device *od)
- +{
- + unsigned long status;
- +
- + status = !!od->request_state;
- +
- + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_PLUG)
- + display_vo_set(CRT, status);
- +
- + return 0;
- +}
- +
- +static struct output_properties crt_output_properties = {
- + .set_state = crt_video_output_set,
- + .get_status = crt_video_output_get,
- +};
- +
- +static struct output_device *lcd_output_dev, *crt_output_dev;
- +
- +static void yeeloong_lcd_vo_set(int status)
- +{
- + lcd_output_dev->request_state = status;
- + lcd_video_output_set(lcd_output_dev);
- +}
- +
- +static void yeeloong_crt_vo_set(int status)
- +{
- + crt_output_dev->request_state = status;
- + crt_video_output_set(crt_output_dev);
- +}
- +
- +static int yeeloong_vo_init(void)
- +{
- + int ret;
- +
- + /* Register video output device: lcd, crt */
- + lcd_output_dev = video_output_register("LCD", NULL, NULL,
- + &lcd_output_properties);
- +
- + if (IS_ERR(lcd_output_dev)) {
- + ret = PTR_ERR(lcd_output_dev);
- + lcd_output_dev = NULL;
- + return ret;
- + }
- + /* Ensure LCD is on by default */
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- +
- + crt_output_dev = video_output_register("CRT", NULL, NULL,
- + &crt_output_properties);
- +
- + if (IS_ERR(crt_output_dev)) {
- + ret = PTR_ERR(crt_output_dev);
- + crt_output_dev = NULL;
- + return ret;
- + }
- +
- + /* Turn off CRT by default, and will be enabled when the CRT
- + * connectting event reported by SCI */
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- +
- + return 0;
- +}
- +
- +static void yeeloong_vo_exit(void)
- +{
- + if (lcd_output_dev) {
- + video_output_unregister(lcd_output_dev);
- + lcd_output_dev = NULL;
- + }
- + if (crt_output_dev) {
- + video_output_unregister(crt_output_dev);
- + crt_output_dev = NULL;
- + }
- +}
- +
- +/* hotkey subdriver */
- +
- +static struct input_dev *yeeloong_hotkey_dev;
- +
- +static const struct key_entry yeeloong_keymap[] = {
- + {KE_SW, EVENT_LID, { SW_LID } },
- + {KE_KEY, EVENT_CAMERA, { KEY_CAMERA } }, /* Fn + ESC */
- + {KE_KEY, EVENT_SLEEP, { KEY_SLEEP } }, /* Fn + F1 */
- + {KE_KEY, EVENT_DISPLAYTOGGLE, { KEY_DISPLAYTOGGLE } }, /* Fn + F2 */
- + {KE_KEY, EVENT_SWITCHVIDEOMODE, { KEY_SWITCHVIDEOMODE } }, /* Fn + F3 */
- + {KE_KEY, EVENT_AUDIO_MUTE, { KEY_MUTE } }, /* Fn + F4 */
- + {KE_KEY, EVENT_WLAN, { KEY_WLAN } }, /* Fn + F5 */
- + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSUP } }, /* Fn + up */
- + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSDOWN } }, /* Fn + down */
- + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEUP } }, /* Fn + right */
- + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEDOWN } }, /* Fn + left */
- + {KE_END, 0}
- +};
- +
- +static struct key_entry *get_event_key_entry(int event, int status)
- +{
- + struct key_entry *ke;
- + static int old_brightness_status = -1;
- + static int old_volume_status = -1;
- +
- + ke = sparse_keymap_entry_from_scancode(yeeloong_hotkey_dev, event);
- + if (!ke)
- + return NULL;
- +
- + switch (event) {
- + case EVENT_DISPLAY_BRIGHTNESS:
- + /* current status > old one, means up */
- + if ((status < old_brightness_status) || (0 == status))
- + ke++;
- + old_brightness_status = status;
- + break;
- + case EVENT_AUDIO_VOLUME:
- + if ((status < old_volume_status) || (0 == status))
- + ke++;
- + old_volume_status = status;
- + break;
- + default:
- + break;
- + }
- +
- + return ke;
- +}
- +
- +static int report_lid_switch(int status)
- +{
- + input_report_switch(yeeloong_hotkey_dev, SW_LID, !status);
- + input_sync(yeeloong_hotkey_dev);
- +
- + return status;
- +}
- +
- +static int crt_detect_handler(int status)
- +{
- + if (status) {
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + } else {
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + }
- + return status;
- +}
- +
- +static int displaytoggle_handler(int status)
- +{
- + /* EC(>=PQ1D26) does this job for us, we can not do it again,
- + * otherwise, the brightness will not resume to the normal level! */
- + if (ec_version_before("EC_VER=PQ1D26"))
- + yeeloong_lcd_vo_set(status);
- +
- + return status;
- +}
- +
- +static int switchvideomode_handler(int status)
- +{
- + static int video_output_status;
- +
- + /* Only enable switch video output button
- + * when CRT is connected */
- + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_UNPLUG)
- + return 0;
- + /* 0. no CRT connected: LCD on, CRT off
- + * 1. BOTH on
- + * 2. LCD off, CRT on
- + * 3. BOTH off
- + * 4. LCD on, CRT off
- + */
- + video_output_status++;
- + if (video_output_status > 4)
- + video_output_status = 1;
- +
- + switch (video_output_status) {
- + case 1:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + break;
- + case 2:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + break;
- + case 3:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + break;
- + case 4:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + break;
- + default:
- + /* Ensure LCD is on */
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + break;
- + }
- + return video_output_status;
- +}
- +
- +static int camera_handler(int status)
- +{
- + int value;
- +
- + value = ec_read(REG_CAMERA_CONTROL);
- + ec_write(REG_CAMERA_CONTROL, value | (1 << 1));
- +
- + return status;
- +}
- +
- +static int usb2_handler(int status)
- +{
- + pr_emerg("USB2 Over Current occurred\n");
- +
- + return status;
- +}
- +
- +static int usb0_handler(int status)
- +{
- + pr_emerg("USB0 Over Current occurred\n");
- +
- + return status;
- +}
- +
- +static int ac_bat_handler(int status)
- +{
- + if (ac_bat_initialized) {
- + power_supply_changed(&yeeloong_ac);
- + power_supply_changed(&yeeloong_bat);
- + }
- + return status;
- +}
- +
- +static void do_event_action(int event)
- +{
- + sci_handler handler;
- + int reg, status;
- + struct key_entry *ke;
- +
- + reg = 0;
- + handler = NULL;
- +
- + switch (event) {
- + case EVENT_LID:
- + reg = REG_LID_DETECT;
- + break;
- + case EVENT_SWITCHVIDEOMODE:
- + handler = switchvideomode_handler;
- + break;
- + case EVENT_CRT_DETECT:
- + reg = REG_CRT_DETECT;
- + handler = crt_detect_handler;
- + break;
- + case EVENT_CAMERA:
- + reg = REG_CAMERA_STATUS;
- + handler = camera_handler;
- + break;
- + case EVENT_USB_OC2:
- + reg = REG_USB2_FLAG;
- + handler = usb2_handler;
- + break;
- + case EVENT_USB_OC0:
- + reg = REG_USB0_FLAG;
- + handler = usb0_handler;
- + break;
- + case EVENT_DISPLAYTOGGLE:
- + reg = REG_DISPLAY_LCD;
- + handler = displaytoggle_handler;
- + break;
- + case EVENT_AUDIO_MUTE:
- + reg = REG_AUDIO_MUTE;
- + break;
- + case EVENT_DISPLAY_BRIGHTNESS:
- + reg = REG_DISPLAY_BRIGHTNESS;
- + break;
- + case EVENT_AUDIO_VOLUME:
- + reg = REG_AUDIO_VOLUME;
- + break;
- + case EVENT_AC_BAT:
- + handler = ac_bat_handler;
- + break;
- + default:
- + break;
- + }
- +
- + if (reg != 0)
- + status = ec_read(reg);
- +
- + if (handler != NULL)
- + status = handler(status);
- +
- + pr_info("%s: event: %d status: %d\n", __func__, event, status);
- +
- + /* Report current key to user-space */
- + ke = get_event_key_entry(event, status);
- + if (ke) {
- + if (ke->keycode == SW_LID)
- + report_lid_switch(status);
- + else
- + sparse_keymap_report_entry(yeeloong_hotkey_dev, ke, 1,
- + true);
- + }
- +}
- +
- +/*
- + * SCI(system control interrupt) main interrupt routine
- + *
- + * We will do the query and get event number together so the interrupt routine
- + * should be longer than 120us now at least 3ms elpase for it.
- + */
- +static irqreturn_t sci_irq_handler(int irq, void *dev_id)
- +{
- + int ret, event;
- +
- + if (SCI_IRQ_NUM != irq)
- + return IRQ_NONE;
- +
- + /* Query the event number */
- + ret = ec_query_event_num();
- + if (ret < 0)
- + return IRQ_NONE;
- +
- + event = ec_get_event_num();
- + if (event < EVENT_START || event > EVENT_END)
- + return IRQ_NONE;
- +
- + /* Execute corresponding actions */
- + do_event_action(event);
- +
- + return IRQ_HANDLED;
- +}
- +
- +/*
- + * Config and init some msr and gpio register properly.
- + */
- +static int sci_irq_init(void)
- +{
- + u32 hi, lo;
- + u32 gpio_base;
- + unsigned long flags;
- + int ret;
- +
- + /* Get gpio base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
- + gpio_base = lo & 0xff00;
- +
- + /* Filter the former kb3310 interrupt for security */
- + ret = ec_query_event_num();
- + if (ret)
- + return ret;
- +
- + /* For filtering next number interrupt */
- + udelay(10000);
- +
- + /* Set gpio native registers and msrs for GPIO27 SCI EVENT PIN
- + * gpio :
- + * input, pull-up, no-invert, event-count and value 0,
- + * no-filter, no edge mode
- + * gpio27 map to Virtual gpio0
- + * msr :
- + * no primary and lpc
- + * Unrestricted Z input to IG10 from Virtual gpio 0.
- + */
- + local_irq_save(flags);
- + _rdmsr(0x80000024, &hi, &lo);
- + lo &= ~(1 << 10);
- + _wrmsr(0x80000024, hi, lo);
- + _rdmsr(0x80000025, &hi, &lo);
- + lo &= ~(1 << 10);
- + _wrmsr(0x80000025, hi, lo);
- + _rdmsr(0x80000023, &hi, &lo);
- + lo |= (0x0a << 0);
- + _wrmsr(0x80000023, hi, lo);
- + local_irq_restore(flags);
- +
- + /* Set gpio27 as sci interrupt
- + *
- + * input, pull-up, no-fliter, no-negedge, invert
- + * the sci event is just about 120us
- + */
- + asm(".set noreorder\n");
- + /* input enable */
- + outl(0x00000800, (gpio_base | 0xA0));
- + /* revert the input */
- + outl(0x00000800, (gpio_base | 0xA4));
- + /* event-int enable */
- + outl(0x00000800, (gpio_base | 0xB8));
- + asm(".set reorder\n");
- +
- + return 0;
- +}
- +
- +static struct irqaction sci_irqaction = {
- + .handler = sci_irq_handler,
- + .name = "sci",
- + .flags = IRQF_SHARED,
- +};
- +
- +static int yeeloong_hotkey_init(void)
- +{
- + int ret;
- +
- + ret = sci_irq_init();
- + if (ret)
- + return -EFAULT;
- +
- + ret = setup_irq(SCI_IRQ_NUM, &sci_irqaction);
- + if (ret)
- + return -EFAULT;
- +
- + yeeloong_hotkey_dev = input_allocate_device();
- +
- + if (!yeeloong_hotkey_dev) {
- + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
- + return -ENOMEM;
- + }
- +
- + yeeloong_hotkey_dev->name = "HotKeys";
- + yeeloong_hotkey_dev->phys = "button/input0";
- + yeeloong_hotkey_dev->id.bustype = BUS_HOST;
- + yeeloong_hotkey_dev->dev.parent = NULL;
- +
- + ret = sparse_keymap_setup(yeeloong_hotkey_dev, yeeloong_keymap, NULL);
- + if (ret) {
- + pr_err("Fail to setup input device keymap\n");
- + input_free_device(yeeloong_hotkey_dev);
- + return ret;
- + }
- +
- + ret = input_register_device(yeeloong_hotkey_dev);
- + if (ret) {
- + sparse_keymap_free(yeeloong_hotkey_dev);
- + input_free_device(yeeloong_hotkey_dev);
- + return ret;
- + }
- +
- + /* Update the current status of LID */
- + report_lid_switch(BIT_LID_DETECT_ON);
- +
- +#ifdef CONFIG_LOONGSON_SUSPEND
- + /* Install the real yeeloong_report_lid_status for pm.c */
- + yeeloong_report_lid_status = report_lid_switch;
- +#endif
- +
- + return 0;
- +}
- +
- +static void yeeloong_hotkey_exit(void)
- +{
- + /* Free irq */
- + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
- +
- +#ifdef CONFIG_LOONGSON_SUSPEND
- + /* Uninstall yeeloong_report_lid_status for pm.c */
- + if (yeeloong_report_lid_status == report_lid_switch)
- + yeeloong_report_lid_status = NULL;
- +#endif
- +
- + if (yeeloong_hotkey_dev) {
- + sparse_keymap_free(yeeloong_hotkey_dev);
- + input_unregister_device(yeeloong_hotkey_dev);
- + yeeloong_hotkey_dev = NULL;
- + }
- +}
- +
- +#ifdef CONFIG_PM
- +static void usb_ports_set(int status)
- +{
- + status = !!status;
- +
- + ec_write(REG_USB0_FLAG, status);
- + ec_write(REG_USB1_FLAG, status);
- + ec_write(REG_USB2_FLAG, status);
- +}
- +
- +static int yeeloong_suspend(struct device *dev)
- +
- +{
- + if (ec_version_before("EC_VER=PQ1D27"))
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + usb_ports_set(BIT_USB_FLAG_OFF);
- +
- + return 0;
- +}
- +
- +static int yeeloong_resume(struct device *dev)
- +{
- + if (ec_version_before("EC_VER=PQ1D27"))
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + usb_ports_set(BIT_USB_FLAG_ON);
- +
- + return 0;
- +}
- +
- +static const SIMPLE_DEV_PM_OPS(yeeloong_pm_ops, yeeloong_suspend,
- + yeeloong_resume);
- +#endif
- +
- +static struct platform_device_id platform_device_ids[] = {
- + {
- + .name = "yeeloong_laptop",
- + },
- + {}
- +};
- +
- +MODULE_DEVICE_TABLE(platform, platform_device_ids);
- +
- +static struct platform_driver platform_driver = {
- + .driver = {
- + .name = "yeeloong_laptop",
- + .owner = THIS_MODULE,
- +#ifdef CONFIG_PM
- + .pm = &yeeloong_pm_ops,
- +#endif
- + },
- + .id_table = platform_device_ids,
- +};
- +
- +static int __init yeeloong_init(void)
- +{
- + int ret;
- +
- + pr_info("Load YeeLoong Laptop Platform Specific Driver.\n");
- +
- + /* Register platform stuff */
- + ret = platform_driver_register(&platform_driver);
- + if (ret) {
- + pr_err("Fail to register yeeloong platform driver.\n");
- + return ret;
- + }
- +
- + ret = yeeloong_backlight_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong backlight driver.\n");
- + yeeloong_backlight_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_bat_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong battery driver.\n");
- + yeeloong_bat_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_hwmon_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong hwmon driver.\n");
- + yeeloong_hwmon_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_vo_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong video output driver.\n");
- + yeeloong_vo_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_hotkey_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong hotkey driver.\n");
- + yeeloong_hotkey_exit();
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +static void __exit yeeloong_exit(void)
- +{
- + yeeloong_hotkey_exit();
- + yeeloong_vo_exit();
- + yeeloong_hwmon_exit();
- + yeeloong_bat_exit();
- + yeeloong_backlight_exit();
- + platform_driver_unregister(&platform_driver);
- +
- + pr_info("Unload YeeLoong Platform Specific Driver.\n");
- +}
- +
- +module_init(yeeloong_init);
- +module_exit(yeeloong_exit);
- +
- +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Liu Junliang <liujl@lemote.com>");
- +MODULE_DESCRIPTION("YeeLoong laptop driver");
- +MODULE_LICENSE("GPL");
- diff -Nur linux-2.6.37.orig/drivers/staging/sm7xx/smtcfb.c linux-2.6.37/drivers/staging/sm7xx/smtcfb.c
- --- linux-2.6.37.orig/drivers/staging/sm7xx/smtcfb.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/drivers/staging/sm7xx/smtcfb.c 2011-01-11 20:44:43.000000000 +0100
- @@ -12,6 +12,8 @@
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- + * - Remove the buggy 2D support for Lynx, 2010/01/06, Wu Zhangjin
- + *
- * Version 0.10.26192.21.01
- * - Add PowerPC/Big endian support
- * - Add 2D support for Lynx
- @@ -107,6 +109,7 @@
- {"0x307", 1280, 1024, 8},
-
- {"0x311", 640, 480, 16},
- + {"0x313", 800, 480, 16},
- {"0x314", 800, 600, 16},
- {"0x317", 1024, 768, 16},
- {"0x31A", 1280, 1024, 16},
- diff -Nur linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c linux-2.6.37/drivers/usb/host/ohci-hcd.c
- --- linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/drivers/usb/host/ohci-hcd.c 2011-01-11 20:44:43.000000000 +0100
- @@ -838,9 +838,13 @@
- }
-
- if (ints & OHCI_INTR_WDH) {
- - spin_lock (&ohci->lock);
- - dl_done_list (ohci);
- - spin_unlock (&ohci->lock);
- + if (ohci->hcca->done_head == 0) {
- + ints &= ~OHCI_INTR_WDH;
- + } else {
- + spin_lock (&ohci->lock);
- + dl_done_list (ohci);
- + spin_unlock (&ohci->lock);
- + }
- }
-
- if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
- diff -Nur linux-2.6.37.orig/net/rfkill/core.c linux-2.6.37/net/rfkill/core.c
- --- linux-2.6.37.orig/net/rfkill/core.c 2011-01-05 01:50:19.000000000 +0100
- +++ linux-2.6.37/net/rfkill/core.c 2011-01-11 20:44:43.000000000 +0100
- @@ -112,7 +112,7 @@
- static DEFINE_MUTEX(rfkill_global_mutex);
- static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */
-
- -static unsigned int rfkill_default_state = 1;
- +static unsigned int rfkill_default_state; /* default: 0 = radio off */
- module_param_named(default_state, rfkill_default_state, uint, 0444);
- MODULE_PARM_DESC(default_state,
- "Default initial state for all radio types, 0 = radio off");
|