1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267 |
- diff -Nur linux-2.6.36.orig/arch/mips/Kconfig linux-2.6.36/arch/mips/Kconfig
- --- linux-2.6.36.orig/arch/mips/Kconfig 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/Kconfig 2010-12-17 23:12:59.000000000 +0100
- @@ -205,7 +205,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.
-
- @@ -1093,6 +1093,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.
- @@ -2012,6 +2014,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.36.orig/arch/mips/include/asm/dma-mapping.h linux-2.6.36/arch/mips/include/asm/dma-mapping.h
- --- linux-2.6.36.orig/arch/mips/include/asm/dma-mapping.h 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/include/asm/dma-mapping.h 2010-12-17 23:12:59.000000000 +0100
- @@ -65,4 +65,8 @@
- extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction direction);
-
- +#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.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
- --- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-12-17 23:12:59.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.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
- --- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-12-17 23:12:59.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.36.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h linux-2.6.36/arch/mips/include/asm/mach-loongson/ec_kb3310b.h
- --- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 2010-12-17 23:12:59.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.36.orig/arch/mips/include/asm/mach-loongson/loongson.h linux-2.6.36/arch/mips/include/asm/mach-loongson/loongson.h
- --- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/loongson.h 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/include/asm/mach-loongson/loongson.h 2010-12-17 23:12:59.000000000 +0100
- @@ -42,6 +42,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.36.orig/arch/mips/kernel/csrc-r4k.c linux-2.6.36/arch/mips/kernel/csrc-r4k.c
- --- linux-2.6.36.orig/arch/mips/kernel/csrc-r4k.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/kernel/csrc-r4k.c 2010-12-17 23:12:59.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.36.orig/arch/mips/kernel/time.c linux-2.6.36/arch/mips/kernel/time.c
- --- linux-2.6.36.orig/arch/mips/kernel/time.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/kernel/time.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cmdline.c linux-2.6.36/arch/mips/loongson/common/cmdline.c
- --- linux-2.6.36.orig/arch/mips/loongson/common/cmdline.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/common/cmdline.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_acc.c
- --- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ehci.c
- --- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ide.c
- --- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ohci.c
- --- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/mtd.c linux-2.6.36/arch/mips/loongson/common/mtd.c
- --- linux-2.6.36.orig/arch/mips/loongson/common/mtd.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/arch/mips/loongson/common/mtd.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/Makefile linux-2.6.36/arch/mips/loongson/lemote-2f/Makefile
- --- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/Makefile 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/lemote-2f/Makefile 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-2.6.36/arch/mips/loongson/lemote-2f/ec_kb3310b.c
- --- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-2.6.36/arch/mips/loongson/lemote-2f/ec_kb3310b.h
- --- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/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.36.orig/arch/mips/loongson/lemote-2f/platform.c linux-2.6.36/arch/mips/loongson/lemote-2f/platform.c
- --- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/platform.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/arch/mips/loongson/lemote-2f/platform.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/pm.c linux-2.6.36/arch/mips/loongson/lemote-2f/pm.c
- --- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/pm.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/lemote-2f/pm.c 2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/reset.c linux-2.6.36/arch/mips/loongson/lemote-2f/reset.c
- --- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/reset.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/loongson/lemote-2f/reset.c 2010-12-17 23:12:59.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.36.orig/arch/mips/mm/dma-default.c linux-2.6.36/arch/mips/mm/dma-default.c
- --- linux-2.6.36.orig/arch/mips/mm/dma-default.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/arch/mips/mm/dma-default.c 2010-12-17 23:12:59.000000000 +0100
- @@ -380,3 +380,16 @@
- }
-
- 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);
- diff -Nur linux-2.6.36.orig/drivers/ide/ide-iops.c linux-2.6.36/drivers/ide/ide-iops.c
- --- linux-2.6.36.orig/drivers/ide/ide-iops.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/drivers/ide/ide-iops.c 2010-12-17 23:12:59.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.36.orig/drivers/platform/Kconfig linux-2.6.36/drivers/platform/Kconfig
- --- linux-2.6.36.orig/drivers/platform/Kconfig 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/drivers/platform/Kconfig 2010-12-17 23:12:59.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.36.orig/drivers/platform/Makefile linux-2.6.36/drivers/platform/Makefile
- --- linux-2.6.36.orig/drivers/platform/Makefile 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/drivers/platform/Makefile 2010-12-17 23:12:59.000000000 +0100
- @@ -3,3 +3,4 @@
- #
-
- obj-$(CONFIG_X86) += x86/
- +obj-$(CONFIG_MIPS) += mips/
- diff -Nur linux-2.6.36.orig/drivers/platform/mips/Kconfig linux-2.6.36/drivers/platform/mips/Kconfig
- --- linux-2.6.36.orig/drivers/platform/mips/Kconfig 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/drivers/platform/mips/Kconfig 2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/Makefile linux-2.6.36/drivers/platform/mips/Makefile
- --- linux-2.6.36.orig/drivers/platform/mips/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/drivers/platform/mips/Makefile 2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/lynloong_pc.c linux-2.6.36/drivers/platform/mips/lynloong_pc.c
- --- linux-2.6.36.orig/drivers/platform/mips/lynloong_pc.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/drivers/platform/mips/lynloong_pc.c 2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/yeeloong_ecrom.c linux-2.6.36/drivers/platform/mips/yeeloong_ecrom.c
- --- linux-2.6.36.orig/drivers/platform/mips/yeeloong_ecrom.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/drivers/platform/mips/yeeloong_ecrom.c 2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/yeeloong_laptop.c linux-2.6.36/drivers/platform/mips/yeeloong_laptop.c
- --- linux-2.6.36.orig/drivers/platform/mips/yeeloong_laptop.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-2.6.36/drivers/platform/mips/yeeloong_laptop.c 2010-12-17 23:12:59.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.36.orig/drivers/staging/sm7xx/smtcfb.c linux-2.6.36/drivers/staging/sm7xx/smtcfb.c
- --- linux-2.6.36.orig/drivers/staging/sm7xx/smtcfb.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/drivers/staging/sm7xx/smtcfb.c 2010-12-17 23:12:59.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.36.orig/drivers/usb/host/ohci-hcd.c linux-2.6.36/drivers/usb/host/ohci-hcd.c
- --- linux-2.6.36.orig/drivers/usb/host/ohci-hcd.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/drivers/usb/host/ohci-hcd.c 2010-12-17 23:12:59.000000000 +0100
- @@ -832,9 +832,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.36.orig/net/rfkill/core.c linux-2.6.36/net/rfkill/core.c
- --- linux-2.6.36.orig/net/rfkill/core.c 2010-10-20 22:30:22.000000000 +0200
- +++ linux-2.6.36/net/rfkill/core.c 2010-12-17 23:12:59.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");
|