12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007 |
- From 16e07c5e69b4cec6bea87fd616d05e9af33b565b Mon Sep 17 00:00:00 2001
- From: Chukun Pan <[email protected]>
- Date: Fri, 5 Jan 2024 23:16:16 +0800
- Subject: [PATCH 1/4] uboot-sunxi: bump to 2024.01
- This version supports LPDDR4 DRAM of H618 SoC.
- Tested on Orange Pi Zero 3.
- Signed-off-by: Chukun Pan <[email protected]>
- ---
- package/boot/uboot-sunxi/Makefile | 4 ++--
- .../uboot-sunxi/patches/062-A20-improve-gmac-upload.patch | 2 +-
- ...00-mkimage-check-environment-for-dtc-binary-location.patch | 2 +-
- 3 files changed, 4 insertions(+), 4 deletions(-)
- diff --git a/package/boot/uboot-sunxi/Makefile b/package/boot/uboot-sunxi/Makefile
- index 7f50992e6955c..de07dbdec2e97 100644
- --- a/package/boot/uboot-sunxi/Makefile
- +++ b/package/boot/uboot-sunxi/Makefile
- @@ -9,9 +9,9 @@
- include $(TOPDIR)/rules.mk
- include $(INCLUDE_DIR)/kernel.mk
-
- -PKG_VERSION:=2023.04
- +PKG_VERSION:=2024.01
-
- -PKG_HASH:=e31cac91545ff41b71cec5d8c22afd695645cd6e2a442ccdacacd60534069341
- +PKG_HASH:=b99611f1ed237bf3541bdc8434b68c96a6e05967061f992443cb30aabebef5b3
-
- PKG_MAINTAINER:=Zoltan HERPAI <[email protected]>
-
- diff --git a/package/boot/uboot-sunxi/patches/062-A20-improve-gmac-upload.patch b/package/boot/uboot-sunxi/patches/062-A20-improve-gmac-upload.patch
- index 13a703f307d21..a1caf18a184a5 100644
- --- a/package/boot/uboot-sunxi/patches/062-A20-improve-gmac-upload.patch
- +++ b/package/boot/uboot-sunxi/patches/062-A20-improve-gmac-upload.patch
- @@ -2,7 +2,7 @@
-
- --- a/configs/A20-OLinuXino-Lime2_defconfig
- +++ b/configs/A20-OLinuXino-Lime2_defconfig
- -@@ -26,6 +26,7 @@ CONFIG_ETH_DESIGNWARE=y
- +@@ -25,6 +25,7 @@ CONFIG_ETH_DESIGNWARE=y
- CONFIG_RGMII=y
- CONFIG_MII=y
- CONFIG_SUN7I_GMAC=y
- diff --git a/package/boot/uboot-sunxi/patches/200-mkimage-check-environment-for-dtc-binary-location.patch b/package/boot/uboot-sunxi/patches/200-mkimage-check-environment-for-dtc-binary-location.patch
- index fcc30ce35cd1d..0307d6b99b2e2 100644
- --- a/package/boot/uboot-sunxi/patches/200-mkimage-check-environment-for-dtc-binary-location.patch
- +++ b/package/boot/uboot-sunxi/patches/200-mkimage-check-environment-for-dtc-binary-location.patch
- @@ -17,7 +17,7 @@ Cc: Simon Glass <[email protected]>
-
- --- a/tools/fit_image.c
- +++ b/tools/fit_image.c
- -@@ -754,9 +754,14 @@ static int fit_handle_file(struct image_
- +@@ -774,9 +774,14 @@ static int fit_handle_file(struct image_
- }
- *cmd = '\0';
- } else if (params->datafile) {
- From b59981e7f7e83468ce3604877307d620a9e48f18 Mon Sep 17 00:00:00 2001
- From: Chukun Pan <[email protected]>
- Date: Thu, 16 Nov 2023 23:10:21 +0800
- Subject: [PATCH 2/4] generic: 6.1: backport AXP PMIC support
- Backport AXP15060, AXP313a and AXP192 support.
- The AXP15060 PMIC is used for starfive boards,
- and the AXP313a PMIC is used for sunxi boards.
- Remove conflicting patches from starfive target.
- Signed-off-by: Chukun Pan <[email protected]>
- ---
- ...0x-Switch-to-the-sys-off-handler-API.patch | 82 ++
- ...axp20x-Add-support-for-AXP15060-PMIC.patch | 343 ++++++
- ...-axp20x-Add-support-for-AXP313a-PMIC.patch | 256 +++++
- ...p20x-Add-support-for-AXP313a-variant.patch | 129 +++
- ...gulator-axp20x-Add-AXP15060-support.patch} | 159 +--
- ....5-mfd-axp20x-Add-support-for-AXP192.patch | 383 +++++++
- ...-mfd-axp20x-Add-support-for-AXP15060.patch | 1014 -----------------
- 7 files changed, 1239 insertions(+), 1127 deletions(-)
- create mode 100644 target/linux/generic/backport-6.1/850-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch
- create mode 100644 target/linux/generic/backport-6.1/851-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch
- create mode 100644 target/linux/generic/backport-6.1/852-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch
- create mode 100644 target/linux/generic/backport-6.1/853-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch
- rename target/linux/{starfive/patches-6.1/0118-driver-regulator-axp20x-Support-AXP15060-variant.patch => generic/backport-6.1/854-v6.5-regulator-axp20x-Add-AXP15060-support.patch} (74%)
- create mode 100644 target/linux/generic/backport-6.1/855-v6.5-mfd-axp20x-Add-support-for-AXP192.patch
- delete mode 100644 target/linux/starfive/patches-6.1/0117-driver-mfd-axp20x-Add-support-for-AXP15060.patch
- diff --git a/target/linux/generic/backport-6.1/850-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch b/target/linux/generic/backport-6.1/850-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch
- new file mode 100644
- index 0000000000000..b742276c8ad43
- --- /dev/null
- +++ b/target/linux/generic/backport-6.1/850-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch
- @@ -0,0 +1,82 @@
- +From 1b1305e95e85624f538ec56db9acf88e2d3d7397 Mon Sep 17 00:00:00 2001
- +From: Samuel Holland <[email protected]>
- +Date: Wed, 28 Dec 2022 10:27:52 -0600
- +Subject: [PATCH] mfd: axp20x: Switch to the sys-off handler API
- +
- +This removes a layer of indirection through pm_power_off() and allows
- +the PMIC handler to be used as a fallback when firmware power off fails.
- +This happens on boards like the Clockwork DevTerm R-01 where OpenSBI
- +does not know how to use the PMIC to power off the board.
- +
- +Move the check for AXP288 to avoid registering a dummy handler.
- +
- +Signed-off-by: Samuel Holland <[email protected]>
- +[Lee: Removed superfluous new line]
- +Signed-off-by: Lee Jones <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/mfd/axp20x.c | 27 +++++++++++----------------
- + 1 file changed, 11 insertions(+), 16 deletions(-)
- +
- +--- a/drivers/mfd/axp20x.c
- ++++ b/drivers/mfd/axp20x.c
- +@@ -23,7 +23,7 @@
- + #include <linux/mfd/core.h>
- + #include <linux/module.h>
- + #include <linux/of_device.h>
- +-#include <linux/pm_runtime.h>
- ++#include <linux/reboot.h>
- + #include <linux/regmap.h>
- + #include <linux/regulator/consumer.h>
- +
- +@@ -832,17 +832,16 @@ static const struct mfd_cell axp813_cell
- + },
- + };
- +
- +-static struct axp20x_dev *axp20x_pm_power_off;
- +-static void axp20x_power_off(void)
- ++static int axp20x_power_off(struct sys_off_data *data)
- + {
- +- if (axp20x_pm_power_off->variant == AXP288_ID)
- +- return;
- ++ struct axp20x_dev *axp20x = data->cb_data;
- +
- +- regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
- +- AXP20X_OFF);
- ++ regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
- +
- + /* Give capacitors etc. time to drain to avoid kernel panic msg. */
- + mdelay(500);
- ++
- ++ return NOTIFY_DONE;
- + }
- +
- + int axp20x_match_device(struct axp20x_dev *axp20x)
- +@@ -1009,10 +1008,11 @@ int axp20x_device_probe(struct axp20x_de
- + return ret;
- + }
- +
- +- if (!pm_power_off) {
- +- axp20x_pm_power_off = axp20x;
- +- pm_power_off = axp20x_power_off;
- +- }
- ++ if (axp20x->variant != AXP288_ID)
- ++ devm_register_sys_off_handler(axp20x->dev,
- ++ SYS_OFF_MODE_POWER_OFF,
- ++ SYS_OFF_PRIO_DEFAULT,
- ++ axp20x_power_off, axp20x);
- +
- + dev_info(axp20x->dev, "AXP20X driver loaded\n");
- +
- +@@ -1022,11 +1022,6 @@ EXPORT_SYMBOL(axp20x_device_probe);
- +
- + void axp20x_device_remove(struct axp20x_dev *axp20x)
- + {
- +- if (axp20x == axp20x_pm_power_off) {
- +- axp20x_pm_power_off = NULL;
- +- pm_power_off = NULL;
- +- }
- +-
- + mfd_remove_devices(axp20x->dev);
- + regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
- + }
- diff --git a/target/linux/generic/backport-6.1/851-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch b/target/linux/generic/backport-6.1/851-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch
- new file mode 100644
- index 0000000000000..ec8d38a183a72
- --- /dev/null
- +++ b/target/linux/generic/backport-6.1/851-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch
- @@ -0,0 +1,343 @@
- +From e0f8ad2a705367518b5c56bf9d6da89681467c02 Mon Sep 17 00:00:00 2001
- +From: Shengyu Qu <[email protected]>
- +Date: Fri, 21 Apr 2023 23:08:15 +0800
- +Subject: [PATCH] mfd: axp20x: Add support for AXP15060 PMIC
- +
- +The AXP15060 is a PMIC chip produced by X-Powers, and could be connected
- +via an I2C bus.
- +
- +Describe the regmap and the MFD bits, along with the registers exposed
- +via I2C. Eventually advertise the device using a new compatible string
- +and add support for power off the system.
- +
- +The driver would disable PEK function if IRQ is not configured in device
- +tree, since some boards (For example, Starfive Visionfive 2) didn't
- +connect IRQ line of PMIC to SOC.
- +
- +GPIO function isn't enabled in this commit, since its configuration
- +operation is different from any existing AXP PMICs and needs
- +logic modification on existing driver. GPIO support might come in later
- +patches.
- +
- +Signed-off-by: Shengyu Qu <[email protected]>
- +Reviewed-by: Krzysztof Kozlowski <[email protected]>
- +Signed-off-by: Lee Jones <[email protected]>
- +Link: https://lore.kernel.org/r/TY3P286MB261162D57695AC8164ED50E298609@TY3P286MB2611.JPNP286.PROD.OUTLOOK.COM
- +---
- + drivers/mfd/axp20x-i2c.c | 2 +
- + drivers/mfd/axp20x.c | 107 +++++++++++++++++++++++++++++++++++++
- + include/linux/mfd/axp20x.h | 85 +++++++++++++++++++++++++++++
- + 3 files changed, 194 insertions(+)
- +
- +--- a/drivers/mfd/axp20x-i2c.c
- ++++ b/drivers/mfd/axp20x-i2c.c
- +@@ -66,6 +66,7 @@ static const struct of_device_id axp20x_
- + { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
- + { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
- + { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
- ++ { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
- + { },
- + };
- + MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
- +@@ -79,6 +80,7 @@ static const struct i2c_device_id axp20x
- + { "axp223", 0 },
- + { "axp803", 0 },
- + { "axp806", 0 },
- ++ { "axp15060", 0 },
- + { },
- + };
- + MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
- +--- a/drivers/mfd/axp20x.c
- ++++ b/drivers/mfd/axp20x.c
- +@@ -43,6 +43,7 @@ static const char * const axp20x_model_n
- + "AXP806",
- + "AXP809",
- + "AXP813",
- ++ "AXP15060",
- + };
- +
- + static const struct regmap_range axp152_writeable_ranges[] = {
- +@@ -168,6 +169,31 @@ static const struct regmap_access_table
- + .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges),
- + };
- +
- ++static const struct regmap_range axp15060_writeable_ranges[] = {
- ++ regmap_reg_range(AXP15060_PWR_OUT_CTRL1, AXP15060_DCDC_MODE_CTRL2),
- ++ regmap_reg_range(AXP15060_OUTPUT_MONITOR_DISCHARGE, AXP15060_CPUSLDO_V_CTRL),
- ++ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
- ++ regmap_reg_range(AXP15060_PEK_KEY, AXP15060_PEK_KEY),
- ++ regmap_reg_range(AXP15060_IRQ1_EN, AXP15060_IRQ2_EN),
- ++ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
- ++};
- ++
- ++static const struct regmap_range axp15060_volatile_ranges[] = {
- ++ regmap_reg_range(AXP15060_STARTUP_SRC, AXP15060_STARTUP_SRC),
- ++ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
- ++ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
- ++};
- ++
- ++static const struct regmap_access_table axp15060_writeable_table = {
- ++ .yes_ranges = axp15060_writeable_ranges,
- ++ .n_yes_ranges = ARRAY_SIZE(axp15060_writeable_ranges),
- ++};
- ++
- ++static const struct regmap_access_table axp15060_volatile_table = {
- ++ .yes_ranges = axp15060_volatile_ranges,
- ++ .n_yes_ranges = ARRAY_SIZE(axp15060_volatile_ranges),
- ++};
- ++
- + static const struct resource axp152_pek_resources[] = {
- + DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- + DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- +@@ -236,6 +262,11 @@ static const struct resource axp809_pek_
- + DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- + };
- +
- ++static const struct resource axp15060_pek_resources[] = {
- ++ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- ++ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- ++};
- ++
- + static const struct regmap_config axp152_regmap_config = {
- + .reg_bits = 8,
- + .val_bits = 8,
- +@@ -281,6 +312,15 @@ static const struct regmap_config axp806
- + .cache_type = REGCACHE_RBTREE,
- + };
- +
- ++static const struct regmap_config axp15060_regmap_config = {
- ++ .reg_bits = 8,
- ++ .val_bits = 8,
- ++ .wr_table = &axp15060_writeable_table,
- ++ .volatile_table = &axp15060_volatile_table,
- ++ .max_register = AXP15060_IRQ2_STATE,
- ++ .cache_type = REGCACHE_RBTREE,
- ++};
- ++
- + #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \
- + [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
- +
- +@@ -502,6 +542,23 @@ static const struct regmap_irq axp809_re
- + INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0),
- + };
- +
- ++static const struct regmap_irq axp15060_regmap_irqs[] = {
- ++ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV1, 0, 0),
- ++ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV2, 0, 1),
- ++ INIT_REGMAP_IRQ(AXP15060, DCDC1_V_LOW, 0, 2),
- ++ INIT_REGMAP_IRQ(AXP15060, DCDC2_V_LOW, 0, 3),
- ++ INIT_REGMAP_IRQ(AXP15060, DCDC3_V_LOW, 0, 4),
- ++ INIT_REGMAP_IRQ(AXP15060, DCDC4_V_LOW, 0, 5),
- ++ INIT_REGMAP_IRQ(AXP15060, DCDC5_V_LOW, 0, 6),
- ++ INIT_REGMAP_IRQ(AXP15060, DCDC6_V_LOW, 0, 7),
- ++ INIT_REGMAP_IRQ(AXP15060, PEK_LONG, 1, 0),
- ++ INIT_REGMAP_IRQ(AXP15060, PEK_SHORT, 1, 1),
- ++ INIT_REGMAP_IRQ(AXP15060, GPIO1_INPUT, 1, 2),
- ++ INIT_REGMAP_IRQ(AXP15060, PEK_FAL_EDGE, 1, 3),
- ++ INIT_REGMAP_IRQ(AXP15060, PEK_RIS_EDGE, 1, 4),
- ++ INIT_REGMAP_IRQ(AXP15060, GPIO2_INPUT, 1, 5),
- ++};
- ++
- + static const struct regmap_irq_chip axp152_regmap_irq_chip = {
- + .name = "axp152_irq_chip",
- + .status_base = AXP152_IRQ1_STATE,
- +@@ -588,6 +645,17 @@ static const struct regmap_irq_chip axp8
- + .num_regs = 5,
- + };
- +
- ++static const struct regmap_irq_chip axp15060_regmap_irq_chip = {
- ++ .name = "axp15060",
- ++ .status_base = AXP15060_IRQ1_STATE,
- ++ .ack_base = AXP15060_IRQ1_STATE,
- ++ .unmask_base = AXP15060_IRQ1_EN,
- ++ .init_ack_masked = true,
- ++ .irqs = axp15060_regmap_irqs,
- ++ .num_irqs = ARRAY_SIZE(axp15060_regmap_irqs),
- ++ .num_regs = 2,
- ++};
- ++
- + static const struct mfd_cell axp20x_cells[] = {
- + {
- + .name = "axp20x-gpio",
- +@@ -832,6 +900,23 @@ static const struct mfd_cell axp813_cell
- + },
- + };
- +
- ++static const struct mfd_cell axp15060_cells[] = {
- ++ {
- ++ .name = "axp221-pek",
- ++ .num_resources = ARRAY_SIZE(axp15060_pek_resources),
- ++ .resources = axp15060_pek_resources,
- ++ }, {
- ++ .name = "axp20x-regulator",
- ++ },
- ++};
- ++
- ++/* For boards that don't have IRQ line connected to SOC. */
- ++static const struct mfd_cell axp_regulator_only_cells[] = {
- ++ {
- ++ .name = "axp20x-regulator",
- ++ },
- ++};
- ++
- + static int axp20x_power_off(struct sys_off_data *data)
- + {
- + struct axp20x_dev *axp20x = data->cb_data;
- +@@ -941,6 +1026,28 @@ int axp20x_match_device(struct axp20x_de
- + */
- + axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
- + break;
- ++ case AXP15060_ID:
- ++ /*
- ++ * Don't register the power key part if there is no interrupt
- ++ * line.
- ++ *
- ++ * Since most use cases of AXP PMICs are Allwinner SOCs, board
- ++ * designers follow Allwinner's reference design and connects
- ++ * IRQ line to SOC, there's no need for those variants to deal
- ++ * with cases that IRQ isn't connected. However, AXP15660 is
- ++ * used by some other vendors' SOCs that didn't connect IRQ
- ++ * line, we need to deal with this case.
- ++ */
- ++ if (axp20x->irq > 0) {
- ++ axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
- ++ axp20x->cells = axp15060_cells;
- ++ } else {
- ++ axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
- ++ axp20x->cells = axp_regulator_only_cells;
- ++ }
- ++ axp20x->regmap_cfg = &axp15060_regmap_config;
- ++ axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip;
- ++ break;
- + default:
- + dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
- + return -EINVAL;
- +--- a/include/linux/mfd/axp20x.h
- ++++ b/include/linux/mfd/axp20x.h
- +@@ -21,6 +21,7 @@ enum axp20x_variants {
- + AXP806_ID,
- + AXP809_ID,
- + AXP813_ID,
- ++ AXP15060_ID,
- + NR_AXP20X_VARIANTS,
- + };
- +
- +@@ -131,6 +132,39 @@ enum axp20x_variants {
- + /* Other DCDC regulator control registers are the same as AXP803 */
- + #define AXP813_DCDC7_V_OUT 0x26
- +
- ++#define AXP15060_STARTUP_SRC 0x00
- ++#define AXP15060_PWR_OUT_CTRL1 0x10
- ++#define AXP15060_PWR_OUT_CTRL2 0x11
- ++#define AXP15060_PWR_OUT_CTRL3 0x12
- ++#define AXP15060_DCDC1_V_CTRL 0x13
- ++#define AXP15060_DCDC2_V_CTRL 0x14
- ++#define AXP15060_DCDC3_V_CTRL 0x15
- ++#define AXP15060_DCDC4_V_CTRL 0x16
- ++#define AXP15060_DCDC5_V_CTRL 0x17
- ++#define AXP15060_DCDC6_V_CTRL 0x18
- ++#define AXP15060_ALDO1_V_CTRL 0x19
- ++#define AXP15060_DCDC_MODE_CTRL1 0x1a
- ++#define AXP15060_DCDC_MODE_CTRL2 0x1b
- ++#define AXP15060_OUTPUT_MONITOR_DISCHARGE 0x1e
- ++#define AXP15060_IRQ_PWROK_VOFF 0x1f
- ++#define AXP15060_ALDO2_V_CTRL 0x20
- ++#define AXP15060_ALDO3_V_CTRL 0x21
- ++#define AXP15060_ALDO4_V_CTRL 0x22
- ++#define AXP15060_ALDO5_V_CTRL 0x23
- ++#define AXP15060_BLDO1_V_CTRL 0x24
- ++#define AXP15060_BLDO2_V_CTRL 0x25
- ++#define AXP15060_BLDO3_V_CTRL 0x26
- ++#define AXP15060_BLDO4_V_CTRL 0x27
- ++#define AXP15060_BLDO5_V_CTRL 0x28
- ++#define AXP15060_CLDO1_V_CTRL 0x29
- ++#define AXP15060_CLDO2_V_CTRL 0x2a
- ++#define AXP15060_CLDO3_V_CTRL 0x2b
- ++#define AXP15060_CLDO4_V_CTRL 0x2d
- ++#define AXP15060_CPUSLDO_V_CTRL 0x2e
- ++#define AXP15060_PWR_WAKEUP_CTRL 0x31
- ++#define AXP15060_PWR_DISABLE_DOWN_SEQ 0x32
- ++#define AXP15060_PEK_KEY 0x36
- ++
- + /* Interrupt */
- + #define AXP152_IRQ1_EN 0x40
- + #define AXP152_IRQ2_EN 0x41
- +@@ -152,6 +186,11 @@ enum axp20x_variants {
- + #define AXP20X_IRQ5_STATE 0x4c
- + #define AXP20X_IRQ6_STATE 0x4d
- +
- ++#define AXP15060_IRQ1_EN 0x40
- ++#define AXP15060_IRQ2_EN 0x41
- ++#define AXP15060_IRQ1_STATE 0x48
- ++#define AXP15060_IRQ2_STATE 0x49
- ++
- + /* ADC */
- + #define AXP20X_ACIN_V_ADC_H 0x56
- + #define AXP20X_ACIN_V_ADC_L 0x57
- +@@ -222,6 +261,8 @@ enum axp20x_variants {
- + #define AXP22X_GPIO_STATE 0x94
- + #define AXP22X_GPIO_PULL_DOWN 0x95
- +
- ++#define AXP15060_CLDO4_GPIO2_MODESET 0x2c
- ++
- + /* Battery */
- + #define AXP20X_CHRG_CC_31_24 0xb0
- + #define AXP20X_CHRG_CC_23_16 0xb1
- +@@ -419,6 +460,33 @@ enum {
- + AXP813_REG_ID_MAX,
- + };
- +
- ++enum {
- ++ AXP15060_DCDC1 = 0,
- ++ AXP15060_DCDC2,
- ++ AXP15060_DCDC3,
- ++ AXP15060_DCDC4,
- ++ AXP15060_DCDC5,
- ++ AXP15060_DCDC6,
- ++ AXP15060_ALDO1,
- ++ AXP15060_ALDO2,
- ++ AXP15060_ALDO3,
- ++ AXP15060_ALDO4,
- ++ AXP15060_ALDO5,
- ++ AXP15060_BLDO1,
- ++ AXP15060_BLDO2,
- ++ AXP15060_BLDO3,
- ++ AXP15060_BLDO4,
- ++ AXP15060_BLDO5,
- ++ AXP15060_CLDO1,
- ++ AXP15060_CLDO2,
- ++ AXP15060_CLDO3,
- ++ AXP15060_CLDO4,
- ++ AXP15060_CPUSLDO,
- ++ AXP15060_SW,
- ++ AXP15060_RTC_LDO,
- ++ AXP15060_REG_ID_MAX,
- ++};
- ++
- + /* IRQs */
- + enum {
- + AXP152_IRQ_LDO0IN_CONNECT = 1,
- +@@ -632,6 +700,23 @@ enum axp809_irqs {
- + AXP809_IRQ_GPIO0_INPUT,
- + };
- +
- ++enum axp15060_irqs {
- ++ AXP15060_IRQ_DIE_TEMP_HIGH_LV1 = 1,
- ++ AXP15060_IRQ_DIE_TEMP_HIGH_LV2,
- ++ AXP15060_IRQ_DCDC1_V_LOW,
- ++ AXP15060_IRQ_DCDC2_V_LOW,
- ++ AXP15060_IRQ_DCDC3_V_LOW,
- ++ AXP15060_IRQ_DCDC4_V_LOW,
- ++ AXP15060_IRQ_DCDC5_V_LOW,
- ++ AXP15060_IRQ_DCDC6_V_LOW,
- ++ AXP15060_IRQ_PEK_LONG,
- ++ AXP15060_IRQ_PEK_SHORT,
- ++ AXP15060_IRQ_GPIO1_INPUT,
- ++ AXP15060_IRQ_PEK_FAL_EDGE,
- ++ AXP15060_IRQ_PEK_RIS_EDGE,
- ++ AXP15060_IRQ_GPIO2_INPUT,
- ++};
- ++
- + struct axp20x_dev {
- + struct device *dev;
- + int irq;
- diff --git a/target/linux/generic/backport-6.1/852-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch b/target/linux/generic/backport-6.1/852-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch
- new file mode 100644
- index 0000000000000..9fe70c1032f6f
- --- /dev/null
- +++ b/target/linux/generic/backport-6.1/852-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch
- @@ -0,0 +1,256 @@
- +From 75c8cb2f4cb218aaf4ea68cab08d6dbc96eeae15 Mon Sep 17 00:00:00 2001
- +From: Martin Botka <[email protected]>
- +Date: Wed, 24 May 2023 01:00:10 +0100
- +Subject: [PATCH] mfd: axp20x: Add support for AXP313a PMIC
- +
- +The AXP313a is a PMIC chip produced by X-Powers, it can be connected via
- +an I2C bus.
- +The name AXP1530 seems to appear as well, and this is what is used in
- +the BSP driver. From all we know it's the same chip, just a different
- +name. However we have only seen AXP313a chips in the wild, so go with
- +this name.
- +
- +Compared to the other AXP PMICs it's a rather simple affair: just three
- +DCDC converters, three LDOs, and no battery charging support.
- +
- +Describe the regmap and the MFD bits, along with the registers exposed
- +via I2C. Aside from the various regulators, also describe the power key
- +interrupts, and adjust the shutdown handler routine to use a different
- +register than the other PMICs.
- +Eventually advertise the device using the new compatible string.
- +
- +Signed-off-by: Martin Botka <[email protected]>
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Chen-Yu Tsai <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Lee Jones <[email protected]>
- +---
- + drivers/mfd/axp20x-i2c.c | 2 +
- + drivers/mfd/axp20x.c | 78 +++++++++++++++++++++++++++++++++++++-
- + include/linux/mfd/axp20x.h | 32 ++++++++++++++++
- + 3 files changed, 111 insertions(+), 1 deletion(-)
- +
- +--- a/drivers/mfd/axp20x-i2c.c
- ++++ b/drivers/mfd/axp20x-i2c.c
- +@@ -64,6 +64,7 @@ static const struct of_device_id axp20x_
- + { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
- + { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
- + { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
- ++ { .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID },
- + { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
- + { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
- + { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
- +@@ -78,6 +79,7 @@ static const struct i2c_device_id axp20x
- + { "axp209", 0 },
- + { "axp221", 0 },
- + { "axp223", 0 },
- ++ { "axp313a", 0 },
- + { "axp803", 0 },
- + { "axp806", 0 },
- + { "axp15060", 0 },
- +--- a/drivers/mfd/axp20x.c
- ++++ b/drivers/mfd/axp20x.c
- +@@ -39,6 +39,7 @@ static const char * const axp20x_model_n
- + "AXP221",
- + "AXP223",
- + "AXP288",
- ++ "AXP313a",
- + "AXP803",
- + "AXP806",
- + "AXP809",
- +@@ -155,6 +156,25 @@ static const struct regmap_range axp806_
- + regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
- + };
- +
- ++static const struct regmap_range axp313a_writeable_ranges[] = {
- ++ regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
- ++};
- ++
- ++static const struct regmap_range axp313a_volatile_ranges[] = {
- ++ regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
- ++ regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
- ++};
- ++
- ++static const struct regmap_access_table axp313a_writeable_table = {
- ++ .yes_ranges = axp313a_writeable_ranges,
- ++ .n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
- ++};
- ++
- ++static const struct regmap_access_table axp313a_volatile_table = {
- ++ .yes_ranges = axp313a_volatile_ranges,
- ++ .n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
- ++};
- ++
- + static const struct regmap_range axp806_volatile_ranges[] = {
- + regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
- + };
- +@@ -247,6 +267,11 @@ static const struct resource axp288_fuel
- + DEFINE_RES_IRQ(AXP288_IRQ_WL1),
- + };
- +
- ++static const struct resource axp313a_pek_resources[] = {
- ++ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- ++ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- ++};
- ++
- + static const struct resource axp803_pek_resources[] = {
- + DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- + DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- +@@ -303,6 +328,15 @@ static const struct regmap_config axp288
- + .cache_type = REGCACHE_RBTREE,
- + };
- +
- ++static const struct regmap_config axp313a_regmap_config = {
- ++ .reg_bits = 8,
- ++ .val_bits = 8,
- ++ .wr_table = &axp313a_writeable_table,
- ++ .volatile_table = &axp313a_volatile_table,
- ++ .max_register = AXP313A_IRQ_STATE,
- ++ .cache_type = REGCACHE_RBTREE,
- ++};
- ++
- + static const struct regmap_config axp806_regmap_config = {
- + .reg_bits = 8,
- + .val_bits = 8,
- +@@ -455,6 +489,16 @@ static const struct regmap_irq axp288_re
- + INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
- + };
- +
- ++static const struct regmap_irq axp313a_regmap_irqs[] = {
- ++ INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE, 0, 7),
- ++ INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE, 0, 6),
- ++ INIT_REGMAP_IRQ(AXP313A, PEK_SHORT, 0, 5),
- ++ INIT_REGMAP_IRQ(AXP313A, PEK_LONG, 0, 4),
- ++ INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW, 0, 3),
- ++ INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW, 0, 2),
- ++ INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH, 0, 0),
- ++};
- ++
- + static const struct regmap_irq axp803_regmap_irqs[] = {
- + INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7),
- + INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6),
- +@@ -609,6 +653,17 @@ static const struct regmap_irq_chip axp2
- +
- + };
- +
- ++static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
- ++ .name = "axp313a_irq_chip",
- ++ .status_base = AXP313A_IRQ_STATE,
- ++ .ack_base = AXP313A_IRQ_STATE,
- ++ .unmask_base = AXP313A_IRQ_EN,
- ++ .init_ack_masked = true,
- ++ .irqs = axp313a_regmap_irqs,
- ++ .num_irqs = ARRAY_SIZE(axp313a_regmap_irqs),
- ++ .num_regs = 1,
- ++};
- ++
- + static const struct regmap_irq_chip axp803_regmap_irq_chip = {
- + .name = "axp803",
- + .status_base = AXP20X_IRQ1_STATE,
- +@@ -751,6 +806,11 @@ static const struct mfd_cell axp152_cell
- + },
- + };
- +
- ++static struct mfd_cell axp313a_cells[] = {
- ++ MFD_CELL_NAME("axp20x-regulator"),
- ++ MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
- ++};
- ++
- + static const struct resource axp288_adc_resources[] = {
- + DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
- + };
- +@@ -920,8 +980,18 @@ static const struct mfd_cell axp_regulat
- + static int axp20x_power_off(struct sys_off_data *data)
- + {
- + struct axp20x_dev *axp20x = data->cb_data;
- ++ unsigned int shutdown_reg;
- +
- +- regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
- ++ switch (axp20x->variant) {
- ++ case AXP313A_ID:
- ++ shutdown_reg = AXP313A_SHUTDOWN_CTRL;
- ++ break;
- ++ default:
- ++ shutdown_reg = AXP20X_OFF_CTRL;
- ++ break;
- ++ }
- ++
- ++ regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
- +
- + /* Give capacitors etc. time to drain to avoid kernel panic msg. */
- + mdelay(500);
- +@@ -984,6 +1054,12 @@ int axp20x_match_device(struct axp20x_de
- + axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
- + axp20x->irq_flags = IRQF_TRIGGER_LOW;
- + break;
- ++ case AXP313A_ID:
- ++ axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
- ++ axp20x->cells = axp313a_cells;
- ++ axp20x->regmap_cfg = &axp313a_regmap_config;
- ++ axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
- ++ break;
- + case AXP803_ID:
- + axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
- + axp20x->cells = axp803_cells;
- +--- a/include/linux/mfd/axp20x.h
- ++++ b/include/linux/mfd/axp20x.h
- +@@ -17,6 +17,7 @@ enum axp20x_variants {
- + AXP221_ID,
- + AXP223_ID,
- + AXP288_ID,
- ++ AXP313A_ID,
- + AXP803_ID,
- + AXP806_ID,
- + AXP809_ID,
- +@@ -92,6 +93,17 @@ enum axp20x_variants {
- + #define AXP22X_ALDO3_V_OUT 0x2a
- + #define AXP22X_CHRG_CTRL3 0x35
- +
- ++#define AXP313A_ON_INDICATE 0x00
- ++#define AXP313A_OUTPUT_CONTROL 0x10
- ++#define AXP313A_DCDC1_CONRTOL 0x13
- ++#define AXP313A_DCDC2_CONRTOL 0x14
- ++#define AXP313A_DCDC3_CONRTOL 0x15
- ++#define AXP313A_ALDO1_CONRTOL 0x16
- ++#define AXP313A_DLDO1_CONRTOL 0x17
- ++#define AXP313A_SHUTDOWN_CTRL 0x1a
- ++#define AXP313A_IRQ_EN 0x20
- ++#define AXP313A_IRQ_STATE 0x21
- ++
- + #define AXP806_STARTUP_SRC 0x00
- + #define AXP806_CHIP_ID 0x03
- + #define AXP806_PWR_OUT_CTRL1 0x10
- +@@ -364,6 +376,16 @@ enum {
- + };
- +
- + enum {
- ++ AXP313A_DCDC1 = 0,
- ++ AXP313A_DCDC2,
- ++ AXP313A_DCDC3,
- ++ AXP313A_ALDO1,
- ++ AXP313A_DLDO1,
- ++ AXP313A_RTC_LDO,
- ++ AXP313A_REG_ID_MAX,
- ++};
- ++
- ++enum {
- + AXP806_DCDCA = 0,
- + AXP806_DCDCB,
- + AXP806_DCDCC,
- +@@ -613,6 +635,16 @@ enum axp288_irqs {
- + AXP288_IRQ_BC_USB_CHNG,
- + };
- +
- ++enum axp313a_irqs {
- ++ AXP313A_IRQ_DIE_TEMP_HIGH,
- ++ AXP313A_IRQ_DCDC2_V_LOW = 2,
- ++ AXP313A_IRQ_DCDC3_V_LOW,
- ++ AXP313A_IRQ_PEK_LONG,
- ++ AXP313A_IRQ_PEK_SHORT,
- ++ AXP313A_IRQ_PEK_FAL_EDGE,
- ++ AXP313A_IRQ_PEK_RIS_EDGE,
- ++};
- ++
- + enum axp803_irqs {
- + AXP803_IRQ_ACIN_OVER_V = 1,
- + AXP803_IRQ_ACIN_PLUGIN,
- diff --git a/target/linux/generic/backport-6.1/853-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch b/target/linux/generic/backport-6.1/853-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch
- new file mode 100644
- index 0000000000000..91f1b398244a5
- --- /dev/null
- +++ b/target/linux/generic/backport-6.1/853-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch
- @@ -0,0 +1,129 @@
- +From 60fd7eb89670d2636ac3156881acbd103c6eba6a Mon Sep 17 00:00:00 2001
- +From: Martin Botka <[email protected]>
- +Date: Wed, 24 May 2023 01:00:11 +0100
- +Subject: [PATCH] regulator: axp20x: Add support for AXP313a variant
- +
- +The AXP313a is your typical I2C controlled PMIC, although in a lighter
- +fashion compared to the other X-Powers PMICs: it has only three DCDC
- +rails, three LDOs, and no battery charging support.
- +
- +The AXP313a datasheet does not describe a register to change the DCDC
- +switching frequency, and talks of it being fixed at 3 MHz. Check that
- +the property allowing to change that frequency is absent from the DT,
- +and bail out otherwise.
- +
- +The third LDO, RTCLDO, is fixed, and cannot even be turned on or off,
- +programmatically. On top of that, its voltage is customisable (either
- +1.8V or 3.3V), which we cannot describe easily using the existing
- +regulator wrapper functions. This should be fixed properly, using
- +regulator-{min,max}-microvolt in the DT, but this requires more changes
- +to the code. As some other PMICs (AXP2xx, AXP803) seem to paper over the
- +same problem as well, we follow suit here and pretend it's a fixed 1.8V
- +regulator. A proper fix can follow later. The BSP code seems to ignore
- +this regulator altogether.
- +
- +Describe the AXP313A's voltage settings and switch registers, how the
- +voltages are encoded, and connect this to the MFD device via its
- +regulator ID.
- +
- +Signed-off-by: Martin Botka <[email protected]>
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Chen-Yu Tsai <[email protected]>
- +Reviewed-by: Mark Brown <[email protected]>
- +Tested-by: Shengyu Qu <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Mark Brown <[email protected]>
- +---
- + drivers/regulator/axp20x-regulator.c | 60 ++++++++++++++++++++++++++++
- + 1 file changed, 60 insertions(+)
- +
- +--- a/drivers/regulator/axp20x-regulator.c
- ++++ b/drivers/regulator/axp20x-regulator.c
- +@@ -134,6 +134,11 @@
- + #define AXP22X_PWR_OUT_DLDO4_MASK BIT_MASK(6)
- + #define AXP22X_PWR_OUT_ALDO3_MASK BIT_MASK(7)
- +
- ++#define AXP313A_DCDC1_NUM_VOLTAGES 107
- ++#define AXP313A_DCDC23_NUM_VOLTAGES 88
- ++#define AXP313A_DCDC_V_OUT_MASK GENMASK(6, 0)
- ++#define AXP313A_LDO_V_OUT_MASK GENMASK(4, 0)
- ++
- + #define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0)
- + #define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1)
- + #define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2)
- +@@ -638,6 +643,48 @@ static const struct regulator_desc axp22
- + .ops = &axp20x_ops_sw,
- + };
- +
- ++static const struct linear_range axp313a_dcdc1_ranges[] = {
- ++ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
- ++ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
- ++ REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
- ++};
- ++
- ++static const struct linear_range axp313a_dcdc2_ranges[] = {
- ++ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
- ++ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
- ++};
- ++
- ++/*
- ++ * This is deviating from the datasheet. The values here are taken from the
- ++ * BSP driver and have been confirmed by measurements.
- ++ */
- ++static const struct linear_range axp313a_dcdc3_ranges[] = {
- ++ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
- ++ REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
- ++};
- ++
- ++static const struct regulator_desc axp313a_regulators[] = {
- ++ AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
- ++ axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
- ++ AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
- ++ AXP313A_OUTPUT_CONTROL, BIT(0)),
- ++ AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
- ++ axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
- ++ AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
- ++ AXP313A_OUTPUT_CONTROL, BIT(1)),
- ++ AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
- ++ axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
- ++ AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
- ++ AXP313A_OUTPUT_CONTROL, BIT(2)),
- ++ AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
- ++ AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
- ++ AXP313A_OUTPUT_CONTROL, BIT(3)),
- ++ AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
- ++ AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
- ++ AXP313A_OUTPUT_CONTROL, BIT(4)),
- ++ AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
- ++};
- ++
- + /* DCDC ranges shared with AXP813 */
- + static const struct linear_range axp803_dcdc234_ranges[] = {
- + REGULATOR_LINEAR_RANGE(500000,
- +@@ -1040,6 +1087,15 @@ static int axp20x_set_dcdc_freq(struct p
- + def = 3000;
- + step = 150;
- + break;
- ++ case AXP313A_ID:
- ++ /* The DCDC PWM frequency seems to be fixed to 3 MHz. */
- ++ if (dcdcfreq != 0) {
- ++ dev_err(&pdev->dev,
- ++ "DCDC frequency on AXP313a is fixed to 3 MHz.\n");
- ++ return -EINVAL;
- ++ }
- ++
- ++ return 0;
- + default:
- + dev_err(&pdev->dev,
- + "Setting DCDC frequency for unsupported AXP variant\n");
- +@@ -1232,6 +1288,10 @@ static int axp20x_regulator_probe(struct
- + drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
- + "x-powers,drive-vbus-en");
- + break;
- ++ case AXP313A_ID:
- ++ regulators = axp313a_regulators;
- ++ nregulators = AXP313A_REG_ID_MAX;
- ++ break;
- + case AXP803_ID:
- + regulators = axp803_regulators;
- + nregulators = AXP803_REG_ID_MAX;
- diff --git a/target/linux/starfive/patches-6.1/0118-driver-regulator-axp20x-Support-AXP15060-variant.patch b/target/linux/generic/backport-6.1/854-v6.5-regulator-axp20x-Add-AXP15060-support.patch
- similarity index 74%
- rename from target/linux/starfive/patches-6.1/0118-driver-regulator-axp20x-Support-AXP15060-variant.patch
- rename to target/linux/generic/backport-6.1/854-v6.5-regulator-axp20x-Add-AXP15060-support.patch
- index ccb277b3a01c7..6af09204af2e5 100644
- --- a/target/linux/starfive/patches-6.1/0118-driver-regulator-axp20x-Support-AXP15060-variant.patch
- +++ b/target/linux/generic/backport-6.1/854-v6.5-regulator-axp20x-Add-AXP15060-support.patch
- @@ -1,30 +1,35 @@
- -From 1b017f3376a5df4a2cd5a120c16723e777fc9a36 Mon Sep 17 00:00:00 2001
- -From: "ziv.xu" <[email protected]>
- -Date: Fri, 4 Aug 2023 13:55:23 +0800
- -Subject: [PATCH 118/122] driver: regulator: axp20x: Support AXP15060 variant.
- +From 9e72869d0fe12aba8cd489e485d93912b3f5c248 Mon Sep 17 00:00:00 2001
- +From: Shengyu Qu <[email protected]>
- +Date: Wed, 24 May 2023 01:00:12 +0100
- +Subject: [PATCH] regulator: axp20x: Add AXP15060 support
-
- -Add axp15060 variant support to axp20x
- +The AXP15060 is a typical I2C-controlled PMIC, seen on multiple boards
- +with different default register value. Current driver is tested on
- +Starfive Visionfive 2.
-
- -Signed-off-by: ziv.xu <[email protected]>
- +The RTCLDO is fixed, and cannot even be turned on or off. On top of
- +that, its voltage is customisable (either 1.8V or 3.3V). We pretend it's
- +a fixed 1.8V regulator since other AXP driver also do like this. Also,
- +BSP code ignores this regulator and it's not used according to VF2
- +schematic.
- +
- +Describe the AXP15060's voltage settings and switch registers, how the
- +voltages are encoded, and connect this to the MFD device via its
- +regulator ID.
- +
- +Signed-off-by: Shengyu Qu <[email protected]>
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Mark Brown <[email protected]>
- +Tested-by: Shengyu Qu <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Mark Brown <[email protected]>
- ---
- - drivers/regulator/axp20x-regulator.c | 291 ++++++++++++++++++++++++++-
- - 1 file changed, 283 insertions(+), 8 deletions(-)
- + drivers/regulator/axp20x-regulator.c | 232 +++++++++++++++++++++++++--
- + 1 file changed, 223 insertions(+), 9 deletions(-)
-
- --- a/drivers/regulator/axp20x-regulator.c
- +++ b/drivers/regulator/axp20x-regulator.c
- -@@ -134,6 +134,11 @@
- - #define AXP22X_PWR_OUT_DLDO4_MASK BIT_MASK(6)
- - #define AXP22X_PWR_OUT_ALDO3_MASK BIT_MASK(7)
- -
- -+#define AXP313A_DCDC1_NUM_VOLTAGES 107
- -+#define AXP313A_DCDC23_NUM_VOLTAGES 88
- -+#define AXP313A_DCDC_V_OUT_MASK GENMASK(6, 0)
- -+#define AXP313A_LDO_V_OUT_MASK GENMASK(4, 0)
- -+
- - #define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0)
- - #define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1)
- - #define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2)
- -@@ -270,6 +275,74 @@
- +@@ -275,6 +275,74 @@
-
- #define AXP813_PWR_OUT_DCDC7_MASK BIT_MASK(6)
-
- @@ -99,56 +104,7 @@ Signed-off-by: ziv.xu <[email protected]>
- #define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
- _vmask, _ereg, _emask, _enable_val, _disable_val) \
- [_family##_##_id] = { \
- -@@ -638,6 +711,48 @@ static const struct regulator_desc axp22
- - .ops = &axp20x_ops_sw,
- - };
- -
- -+static const struct linear_range axp313a_dcdc1_ranges[] = {
- -+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
- -+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
- -+ REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
- -+};
- -+
- -+static const struct linear_range axp313a_dcdc2_ranges[] = {
- -+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
- -+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
- -+};
- -+
- -+/*
- -+ * This is deviating from the datasheet. The values here are taken from the
- -+ * BSP driver and have been confirmed by measurements.
- -+ */
- -+static const struct linear_range axp313a_dcdc3_ranges[] = {
- -+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
- -+ REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
- -+};
- -+
- -+static const struct regulator_desc axp313a_regulators[] = {
- -+ AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
- -+ axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
- -+ AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
- -+ AXP313A_OUTPUT_CONTROL, BIT(0)),
- -+ AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
- -+ axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
- -+ AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
- -+ AXP313A_OUTPUT_CONTROL, BIT(1)),
- -+ AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
- -+ axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
- -+ AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
- -+ AXP313A_OUTPUT_CONTROL, BIT(2)),
- -+ AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
- -+ AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
- -+ AXP313A_OUTPUT_CONTROL, BIT(3)),
- -+ AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
- -+ AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
- -+ AXP313A_OUTPUT_CONTROL, BIT(4)),
- -+ AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
- -+};
- -+
- - /* DCDC ranges shared with AXP813 */
- - static const struct linear_range axp803_dcdc234_ranges[] = {
- - REGULATOR_LINEAR_RANGE(500000,
- -@@ -1001,6 +1116,104 @@ static const struct regulator_desc axp81
- +@@ -1048,6 +1116,104 @@ static const struct regulator_desc axp81
- AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
- };
-
- @@ -253,24 +209,20 @@ Signed-off-by: ziv.xu <[email protected]>
- static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
- {
- struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
- -@@ -1040,6 +1253,16 @@ static int axp20x_set_dcdc_freq(struct p
- - def = 3000;
- +@@ -1088,10 +1254,11 @@ static int axp20x_set_dcdc_freq(struct p
- step = 150;
- break;
- -+ case AXP313A_ID:
- + case AXP313A_ID:
- + case AXP15060_ID:
- -+ /* The DCDC PWM frequency seems to be fixed to 3 MHz. */
- -+ if (dcdcfreq != 0) {
- -+ dev_err(&pdev->dev,
- + /* The DCDC PWM frequency seems to be fixed to 3 MHz. */
- + if (dcdcfreq != 0) {
- + dev_err(&pdev->dev,
- +- "DCDC frequency on AXP313a is fixed to 3 MHz.\n");
- + "DCDC frequency on this PMIC is fixed to 3 MHz.\n");
- -+ return -EINVAL;
- -+ }
- -+
- -+ return 0;
- - default:
- - dev_err(&pdev->dev,
- - "Setting DCDC frequency for unsupported AXP variant\n");
- -@@ -1145,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(stru
- + return -EINVAL;
- + }
- +
- +@@ -1201,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(stru
- workmode <<= id - AXP813_DCDC1;
- break;
-
- @@ -286,7 +238,7 @@ Signed-off-by: ziv.xu <[email protected]>
- default:
- /* should not happen */
- WARN_ON(1);
- -@@ -1164,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(st
- +@@ -1220,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(st
-
- /*
- * Currently in our supported AXP variants, only AXP803, AXP806,
- @@ -295,7 +247,7 @@ Signed-off-by: ziv.xu <[email protected]>
- */
- switch (axp20x->variant) {
- case AXP803_ID:
- -@@ -1196,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(st
- +@@ -1252,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(st
- }
- break;
-
- @@ -313,7 +265,7 @@ Signed-off-by: ziv.xu <[email protected]>
- default:
- return false;
- }
- -@@ -1217,6 +1460,7 @@ static int axp20x_regulator_probe(struct
- +@@ -1273,6 +1460,7 @@ static int axp20x_regulator_probe(struct
- u32 workmode;
- const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
- const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
- @@ -321,18 +273,7 @@ Signed-off-by: ziv.xu <[email protected]>
- bool drivevbus = false;
-
- switch (axp20x->variant) {
- -@@ -1232,6 +1476,10 @@ static int axp20x_regulator_probe(struct
- - drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
- - "x-powers,drive-vbus-en");
- - break;
- -+ case AXP313A_ID:
- -+ regulators = axp313a_regulators;
- -+ nregulators = AXP313A_REG_ID_MAX;
- -+ break;
- - case AXP803_ID:
- - regulators = axp803_regulators;
- - nregulators = AXP803_REG_ID_MAX;
- -@@ -1252,6 +1500,10 @@ static int axp20x_regulator_probe(struct
- +@@ -1312,6 +1500,10 @@ static int axp20x_regulator_probe(struct
- drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
- "x-powers,drive-vbus-en");
- break;
- @@ -343,7 +284,7 @@ Signed-off-by: ziv.xu <[email protected]>
- default:
- dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
- axp20x->variant);
- -@@ -1278,8 +1530,9 @@ static int axp20x_regulator_probe(struct
- +@@ -1338,8 +1530,9 @@ static int axp20x_regulator_probe(struct
- continue;
-
- /*
- @@ -355,7 +296,7 @@ Signed-off-by: ziv.xu <[email protected]>
- *
- * We always register the regulators in proper sequence,
- * so the supply names are correctly read. See the last
- -@@ -1288,7 +1541,8 @@ static int axp20x_regulator_probe(struct
- +@@ -1348,7 +1541,8 @@ static int axp20x_regulator_probe(struct
- */
- if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
- (regulators == axp803_regulators && i == AXP803_DC1SW) ||
- @@ -365,7 +306,7 @@ Signed-off-by: ziv.xu <[email protected]>
- new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
- GFP_KERNEL);
- if (!new_desc)
- -@@ -1300,7 +1554,8 @@ static int axp20x_regulator_probe(struct
- +@@ -1360,7 +1554,8 @@ static int axp20x_regulator_probe(struct
- }
-
- if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
- @@ -375,7 +316,7 @@ Signed-off-by: ziv.xu <[email protected]>
- new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
- GFP_KERNEL);
- if (!new_desc)
- -@@ -1311,6 +1566,18 @@ static int axp20x_regulator_probe(struct
- +@@ -1371,6 +1566,18 @@ static int axp20x_regulator_probe(struct
- desc = new_desc;
- }
-
- @@ -394,7 +335,7 @@ Signed-off-by: ziv.xu <[email protected]>
- rdev = devm_regulator_register(&pdev->dev, desc, &config);
- if (IS_ERR(rdev)) {
- dev_err(&pdev->dev, "Failed to register %s\n",
- -@@ -1329,19 +1596,26 @@ static int axp20x_regulator_probe(struct
- +@@ -1389,19 +1596,26 @@ static int axp20x_regulator_probe(struct
- }
-
- /*
- @@ -424,11 +365,3 @@ Signed-off-by: ziv.xu <[email protected]>
- }
-
- if (drivevbus) {
- -@@ -1364,6 +1638,7 @@ static struct platform_driver axp20x_reg
- - .probe = axp20x_regulator_probe,
- - .driver = {
- - .name = "axp20x-regulator",
- -+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- - },
- - };
- -
- diff --git a/target/linux/generic/backport-6.1/855-v6.5-mfd-axp20x-Add-support-for-AXP192.patch b/target/linux/generic/backport-6.1/855-v6.5-mfd-axp20x-Add-support-for-AXP192.patch
- new file mode 100644
- index 0000000000000..20a26db3e621a
- --- /dev/null
- +++ b/target/linux/generic/backport-6.1/855-v6.5-mfd-axp20x-Add-support-for-AXP192.patch
- @@ -0,0 +1,383 @@
- +From 63eeabbc9dbddd7381409feccd9082e5ffabfe59 Mon Sep 17 00:00:00 2001
- +From: Aidan MacDonald <[email protected]>
- +Date: Thu, 11 May 2023 10:26:08 +0100
- +Subject: [PATCH] mfd: axp20x: Add support for AXP192
- +
- +The AXP192 PMIC is similar to the AXP202/AXP209, but with different
- +regulators, additional GPIOs, and a different IRQ register layout.
- +
- +Signed-off-by: Aidan MacDonald <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Lee Jones <[email protected]>
- +---
- + drivers/mfd/axp20x-i2c.c | 2 +
- + drivers/mfd/axp20x.c | 141 +++++++++++++++++++++++++++++++++++++
- + include/linux/mfd/axp20x.h | 84 ++++++++++++++++++++++
- + 3 files changed, 227 insertions(+)
- +
- +--- a/drivers/mfd/axp20x-i2c.c
- ++++ b/drivers/mfd/axp20x-i2c.c
- +@@ -60,6 +60,7 @@ static void axp20x_i2c_remove(struct i2c
- + #ifdef CONFIG_OF
- + static const struct of_device_id axp20x_i2c_of_match[] = {
- + { .compatible = "x-powers,axp152", .data = (void *)AXP152_ID },
- ++ { .compatible = "x-powers,axp192", .data = (void *)AXP192_ID },
- + { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID },
- + { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
- + { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
- +@@ -75,6 +76,7 @@ MODULE_DEVICE_TABLE(of, axp20x_i2c_of_ma
- +
- + static const struct i2c_device_id axp20x_i2c_id[] = {
- + { "axp152", 0 },
- ++ { "axp192", 0 },
- + { "axp202", 0 },
- + { "axp209", 0 },
- + { "axp221", 0 },
- +--- a/drivers/mfd/axp20x.c
- ++++ b/drivers/mfd/axp20x.c
- +@@ -34,6 +34,7 @@
- +
- + static const char * const axp20x_model_names[] = {
- + "AXP152",
- ++ "AXP192",
- + "AXP202",
- + "AXP209",
- + "AXP221",
- +@@ -94,6 +95,35 @@ static const struct regmap_access_table
- + .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
- + };
- +
- ++static const struct regmap_range axp192_writeable_ranges[] = {
- ++ regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)),
- ++ regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE),
- ++ regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL),
- ++ regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL),
- ++};
- ++
- ++static const struct regmap_range axp192_volatile_ranges[] = {
- ++ regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS),
- ++ regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE),
- ++ regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE),
- ++ regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
- ++ regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
- ++ regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE),
- ++ regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE),
- ++ regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL),
- ++ regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL),
- ++};
- ++
- ++static const struct regmap_access_table axp192_writeable_table = {
- ++ .yes_ranges = axp192_writeable_ranges,
- ++ .n_yes_ranges = ARRAY_SIZE(axp192_writeable_ranges),
- ++};
- ++
- ++static const struct regmap_access_table axp192_volatile_table = {
- ++ .yes_ranges = axp192_volatile_ranges,
- ++ .n_yes_ranges = ARRAY_SIZE(axp192_volatile_ranges),
- ++};
- ++
- + /* AXP22x ranges are shared with the AXP809, as they cover the same range */
- + static const struct regmap_range axp22x_writeable_ranges[] = {
- + regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
- +@@ -219,6 +249,19 @@ static const struct resource axp152_pek_
- + DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- + };
- +
- ++static const struct resource axp192_ac_power_supply_resources[] = {
- ++ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
- ++ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
- ++ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
- ++};
- ++
- ++static const struct resource axp192_usb_power_supply_resources[] = {
- ++ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
- ++ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
- ++ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"),
- ++ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
- ++};
- ++
- + static const struct resource axp20x_ac_power_supply_resources[] = {
- + DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
- + DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
- +@@ -301,6 +344,15 @@ static const struct regmap_config axp152
- + .cache_type = REGCACHE_RBTREE,
- + };
- +
- ++static const struct regmap_config axp192_regmap_config = {
- ++ .reg_bits = 8,
- ++ .val_bits = 8,
- ++ .wr_table = &axp192_writeable_table,
- ++ .volatile_table = &axp192_volatile_table,
- ++ .max_register = AXP20X_CC_CTRL,
- ++ .cache_type = REGCACHE_RBTREE,
- ++};
- ++
- + static const struct regmap_config axp20x_regmap_config = {
- + .reg_bits = 8,
- + .val_bits = 8,
- +@@ -378,6 +430,42 @@ static const struct regmap_irq axp152_re
- + INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0),
- + };
- +
- ++static const struct regmap_irq axp192_regmap_irqs[] = {
- ++ INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V, 0, 7),
- ++ INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN, 0, 6),
- ++ INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL, 0, 5),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V, 0, 4),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN, 0, 3),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL, 0, 2),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW, 0, 1),
- ++ INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN, 1, 7),
- ++ INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL, 1, 6),
- ++ INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE, 1, 5),
- ++ INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE, 1, 4),
- ++ INIT_REGMAP_IRQ(AXP192, CHARG, 1, 3),
- ++ INIT_REGMAP_IRQ(AXP192, CHARG_DONE, 1, 2),
- ++ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH, 1, 1),
- ++ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW, 1, 0),
- ++ INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH, 2, 7),
- ++ INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW, 2, 6),
- ++ INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG, 2, 5),
- ++ INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG, 2, 4),
- ++ INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG, 2, 3),
- ++ INIT_REGMAP_IRQ(AXP192, PEK_SHORT, 2, 1),
- ++ INIT_REGMAP_IRQ(AXP192, PEK_LONG, 2, 0),
- ++ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON, 3, 7),
- ++ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF, 3, 6),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_VALID, 3, 5),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID, 3, 4),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID, 3, 3),
- ++ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END, 3, 2),
- ++ INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL, 3, 0),
- ++ INIT_REGMAP_IRQ(AXP192, TIMER, 4, 7),
- ++ INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT, 4, 2),
- ++ INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT, 4, 1),
- ++ INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT, 4, 0),
- ++};
- ++
- + static const struct regmap_irq axp20x_regmap_irqs[] = {
- + INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7),
- + INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6),
- +@@ -615,6 +703,32 @@ static const struct regmap_irq_chip axp1
- + .num_regs = 3,
- + };
- +
- ++static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data,
- ++ unsigned int base, int index)
- ++{
- ++ /* linear mapping for IRQ1 to IRQ4 */
- ++ if (index < 4)
- ++ return base + index;
- ++
- ++ /* handle IRQ5 separately */
- ++ if (base == AXP192_IRQ1_EN)
- ++ return AXP192_IRQ5_EN;
- ++
- ++ return AXP192_IRQ5_STATE;
- ++}
- ++
- ++static const struct regmap_irq_chip axp192_regmap_irq_chip = {
- ++ .name = "axp192_irq_chip",
- ++ .status_base = AXP192_IRQ1_STATE,
- ++ .ack_base = AXP192_IRQ1_STATE,
- ++ .unmask_base = AXP192_IRQ1_EN,
- ++ .init_ack_masked = true,
- ++ .irqs = axp192_regmap_irqs,
- ++ .num_irqs = ARRAY_SIZE(axp192_regmap_irqs),
- ++ .num_regs = 5,
- ++ .get_irq_reg = axp192_get_irq_reg,
- ++};
- ++
- + static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
- + .name = "axp20x_irq_chip",
- + .status_base = AXP20X_IRQ1_STATE,
- +@@ -711,6 +825,27 @@ static const struct regmap_irq_chip axp1
- + .num_regs = 2,
- + };
- +
- ++static const struct mfd_cell axp192_cells[] = {
- ++ {
- ++ .name = "axp192-adc",
- ++ .of_compatible = "x-powers,axp192-adc",
- ++ }, {
- ++ .name = "axp20x-battery-power-supply",
- ++ .of_compatible = "x-powers,axp192-battery-power-supply",
- ++ }, {
- ++ .name = "axp20x-ac-power-supply",
- ++ .of_compatible = "x-powers,axp202-ac-power-supply",
- ++ .num_resources = ARRAY_SIZE(axp192_ac_power_supply_resources),
- ++ .resources = axp192_ac_power_supply_resources,
- ++ }, {
- ++ .name = "axp20x-usb-power-supply",
- ++ .of_compatible = "x-powers,axp192-usb-power-supply",
- ++ .num_resources = ARRAY_SIZE(axp192_usb_power_supply_resources),
- ++ .resources = axp192_usb_power_supply_resources,
- ++ },
- ++ { .name = "axp20x-regulator" },
- ++};
- ++
- + static const struct mfd_cell axp20x_cells[] = {
- + {
- + .name = "axp20x-gpio",
- +@@ -1028,6 +1163,12 @@ int axp20x_match_device(struct axp20x_de
- + axp20x->regmap_cfg = &axp152_regmap_config;
- + axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
- + break;
- ++ case AXP192_ID:
- ++ axp20x->nr_cells = ARRAY_SIZE(axp192_cells);
- ++ axp20x->cells = axp192_cells;
- ++ axp20x->regmap_cfg = &axp192_regmap_config;
- ++ axp20x->regmap_irq_chip = &axp192_regmap_irq_chip;
- ++ break;
- + case AXP202_ID:
- + case AXP209_ID:
- + axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
- +--- a/include/linux/mfd/axp20x.h
- ++++ b/include/linux/mfd/axp20x.h
- +@@ -12,6 +12,7 @@
- +
- + enum axp20x_variants {
- + AXP152_ID = 0,
- ++ AXP192_ID,
- + AXP202_ID,
- + AXP209_ID,
- + AXP221_ID,
- +@@ -26,6 +27,7 @@ enum axp20x_variants {
- + NR_AXP20X_VARIANTS,
- + };
- +
- ++#define AXP192_DATACACHE(m) (0x06 + (m))
- + #define AXP20X_DATACACHE(m) (0x04 + (m))
- +
- + /* Power supply */
- +@@ -47,6 +49,13 @@ enum axp20x_variants {
- + #define AXP152_DCDC_FREQ 0x37
- + #define AXP152_DCDC_MODE 0x80
- +
- ++#define AXP192_USB_OTG_STATUS 0x04
- ++#define AXP192_PWR_OUT_CTRL 0x12
- ++#define AXP192_DCDC2_V_OUT 0x23
- ++#define AXP192_DCDC1_V_OUT 0x26
- ++#define AXP192_DCDC3_V_OUT 0x27
- ++#define AXP192_LDO2_3_V_OUT 0x28
- ++
- + #define AXP20X_PWR_INPUT_STATUS 0x00
- + #define AXP20X_PWR_OP_MODE 0x01
- + #define AXP20X_USB_OTG_STATUS 0x02
- +@@ -185,6 +194,17 @@ enum axp20x_variants {
- + #define AXP152_IRQ2_STATE 0x49
- + #define AXP152_IRQ3_STATE 0x4a
- +
- ++#define AXP192_IRQ1_EN 0x40
- ++#define AXP192_IRQ2_EN 0x41
- ++#define AXP192_IRQ3_EN 0x42
- ++#define AXP192_IRQ4_EN 0x43
- ++#define AXP192_IRQ1_STATE 0x44
- ++#define AXP192_IRQ2_STATE 0x45
- ++#define AXP192_IRQ3_STATE 0x46
- ++#define AXP192_IRQ4_STATE 0x47
- ++#define AXP192_IRQ5_EN 0x4a
- ++#define AXP192_IRQ5_STATE 0x4d
- ++
- + #define AXP20X_IRQ1_EN 0x40
- + #define AXP20X_IRQ2_EN 0x41
- + #define AXP20X_IRQ3_EN 0x42
- +@@ -204,6 +224,11 @@ enum axp20x_variants {
- + #define AXP15060_IRQ2_STATE 0x49
- +
- + /* ADC */
- ++#define AXP192_GPIO2_V_ADC_H 0x68
- ++#define AXP192_GPIO2_V_ADC_L 0x69
- ++#define AXP192_GPIO3_V_ADC_H 0x6a
- ++#define AXP192_GPIO3_V_ADC_L 0x6b
- ++
- + #define AXP20X_ACIN_V_ADC_H 0x56
- + #define AXP20X_ACIN_V_ADC_L 0x57
- + #define AXP20X_ACIN_I_ADC_H 0x58
- +@@ -233,6 +258,8 @@ enum axp20x_variants {
- + #define AXP20X_IPSOUT_V_HIGH_L 0x7f
- +
- + /* Power supply */
- ++#define AXP192_GPIO30_IN_RANGE 0x85
- ++
- + #define AXP20X_DCDC_MODE 0x80
- + #define AXP20X_ADC_EN1 0x82
- + #define AXP20X_ADC_EN2 0x83
- +@@ -261,6 +288,16 @@ enum axp20x_variants {
- + #define AXP152_PWM1_FREQ_Y 0x9c
- + #define AXP152_PWM1_DUTY_CYCLE 0x9d
- +
- ++#define AXP192_GPIO0_CTRL 0x90
- ++#define AXP192_LDO_IO0_V_OUT 0x91
- ++#define AXP192_GPIO1_CTRL 0x92
- ++#define AXP192_GPIO2_CTRL 0x93
- ++#define AXP192_GPIO2_0_STATE 0x94
- ++#define AXP192_GPIO4_3_CTRL 0x95
- ++#define AXP192_GPIO4_3_STATE 0x96
- ++#define AXP192_GPIO2_0_PULL 0x97
- ++#define AXP192_N_RSTO_CTRL 0x9e
- ++
- + #define AXP20X_GPIO0_CTRL 0x90
- + #define AXP20X_LDO5_V_OUT 0x91
- + #define AXP20X_GPIO1_CTRL 0x92
- +@@ -341,6 +378,17 @@ enum axp20x_variants {
- +
- + /* Regulators IDs */
- + enum {
- ++ AXP192_DCDC1 = 0,
- ++ AXP192_DCDC2,
- ++ AXP192_DCDC3,
- ++ AXP192_LDO1,
- ++ AXP192_LDO2,
- ++ AXP192_LDO3,
- ++ AXP192_LDO_IO0,
- ++ AXP192_REG_ID_MAX
- ++};
- ++
- ++enum {
- + AXP20X_LDO1 = 0,
- + AXP20X_LDO2,
- + AXP20X_LDO3,
- +@@ -530,6 +578,42 @@ enum {
- + AXP152_IRQ_GPIO0_INPUT,
- + };
- +
- ++enum axp192_irqs {
- ++ AXP192_IRQ_ACIN_OVER_V = 1,
- ++ AXP192_IRQ_ACIN_PLUGIN,
- ++ AXP192_IRQ_ACIN_REMOVAL,
- ++ AXP192_IRQ_VBUS_OVER_V,
- ++ AXP192_IRQ_VBUS_PLUGIN,
- ++ AXP192_IRQ_VBUS_REMOVAL,
- ++ AXP192_IRQ_VBUS_V_LOW,
- ++ AXP192_IRQ_BATT_PLUGIN,
- ++ AXP192_IRQ_BATT_REMOVAL,
- ++ AXP192_IRQ_BATT_ENT_ACT_MODE,
- ++ AXP192_IRQ_BATT_EXIT_ACT_MODE,
- ++ AXP192_IRQ_CHARG,
- ++ AXP192_IRQ_CHARG_DONE,
- ++ AXP192_IRQ_BATT_TEMP_HIGH,
- ++ AXP192_IRQ_BATT_TEMP_LOW,
- ++ AXP192_IRQ_DIE_TEMP_HIGH,
- ++ AXP192_IRQ_CHARG_I_LOW,
- ++ AXP192_IRQ_DCDC1_V_LONG,
- ++ AXP192_IRQ_DCDC2_V_LONG,
- ++ AXP192_IRQ_DCDC3_V_LONG,
- ++ AXP192_IRQ_PEK_SHORT = 22,
- ++ AXP192_IRQ_PEK_LONG,
- ++ AXP192_IRQ_N_OE_PWR_ON,
- ++ AXP192_IRQ_N_OE_PWR_OFF,
- ++ AXP192_IRQ_VBUS_VALID,
- ++ AXP192_IRQ_VBUS_NOT_VALID,
- ++ AXP192_IRQ_VBUS_SESS_VALID,
- ++ AXP192_IRQ_VBUS_SESS_END,
- ++ AXP192_IRQ_LOW_PWR_LVL = 31,
- ++ AXP192_IRQ_TIMER,
- ++ AXP192_IRQ_GPIO2_INPUT = 37,
- ++ AXP192_IRQ_GPIO1_INPUT,
- ++ AXP192_IRQ_GPIO0_INPUT,
- ++};
- ++
- + enum {
- + AXP20X_IRQ_ACIN_OVER_V = 1,
- + AXP20X_IRQ_ACIN_PLUGIN,
- diff --git a/target/linux/starfive/patches-6.1/0117-driver-mfd-axp20x-Add-support-for-AXP15060.patch b/target/linux/starfive/patches-6.1/0117-driver-mfd-axp20x-Add-support-for-AXP15060.patch
- deleted file mode 100644
- index 18ad298065f2d..0000000000000
- --- a/target/linux/starfive/patches-6.1/0117-driver-mfd-axp20x-Add-support-for-AXP15060.patch
- +++ /dev/null
- @@ -1,1014 +0,0 @@
- -From e62161318f2fe3e396fc31c50d210e99bec83021 Mon Sep 17 00:00:00 2001
- -From: "ziv.xu" <[email protected]>
- -Date: Fri, 4 Aug 2023 13:53:10 +0800
- -Subject: [PATCH 117/122] driver: mfd: axp20x: Add support for AXP15060
- -
- -axp20x add support for AXP15060
- -
- -Signed-off-by: ziv.xu <[email protected]>
- ----
- - drivers/mfd/axp20x-i2c.c | 2 +
- - drivers/mfd/axp20x.c | 373 ++++++++++++++++++++++++++++++++++---
- - include/linux/mfd/axp20x.h | 218 +++++++++++++++++++++-
- - 3 files changed, 557 insertions(+), 36 deletions(-)
- -
- ---- a/drivers/mfd/axp20x-i2c.c
- -+++ b/drivers/mfd/axp20x-i2c.c
- -@@ -66,6 +66,7 @@ static const struct of_device_id axp20x_
- - { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
- - { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
- - { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
- -+ { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
- - { },
- - };
- - MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
- -@@ -79,6 +80,7 @@ static const struct i2c_device_id axp20x
- - { "axp223", 0 },
- - { "axp803", 0 },
- - { "axp806", 0 },
- -+ { "axp15060", 0 },
- - { },
- - };
- - MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
- ---- a/drivers/mfd/axp20x.c
- -+++ b/drivers/mfd/axp20x.c
- -@@ -23,7 +23,7 @@
- - #include <linux/mfd/core.h>
- - #include <linux/module.h>
- - #include <linux/of_device.h>
- --#include <linux/pm_runtime.h>
- -+#include <linux/reboot.h>
- - #include <linux/regmap.h>
- - #include <linux/regulator/consumer.h>
- -
- -@@ -34,15 +34,18 @@
- -
- - static const char * const axp20x_model_names[] = {
- - "AXP152",
- -+ "AXP192",
- - "AXP202",
- - "AXP209",
- - "AXP221",
- - "AXP223",
- - "AXP288",
- -+ "AXP313a",
- - "AXP803",
- - "AXP806",
- - "AXP809",
- - "AXP813",
- -+ "AXP15060",
- - };
- -
- - static const struct regmap_range axp152_writeable_ranges[] = {
- -@@ -92,6 +95,35 @@ static const struct regmap_access_table
- - .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
- - };
- -
- -+static const struct regmap_range axp192_writeable_ranges[] = {
- -+ regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)),
- -+ regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE),
- -+ regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL),
- -+ regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL),
- -+};
- -+
- -+static const struct regmap_range axp192_volatile_ranges[] = {
- -+ regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS),
- -+ regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE),
- -+ regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE),
- -+ regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
- -+ regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
- -+ regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE),
- -+ regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE),
- -+ regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL),
- -+ regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL),
- -+};
- -+
- -+static const struct regmap_access_table axp192_writeable_table = {
- -+ .yes_ranges = axp192_writeable_ranges,
- -+ .n_yes_ranges = ARRAY_SIZE(axp192_writeable_ranges),
- -+};
- -+
- -+static const struct regmap_access_table axp192_volatile_table = {
- -+ .yes_ranges = axp192_volatile_ranges,
- -+ .n_yes_ranges = ARRAY_SIZE(axp192_volatile_ranges),
- -+};
- -+
- - /* AXP22x ranges are shared with the AXP809, as they cover the same range */
- - static const struct regmap_range axp22x_writeable_ranges[] = {
- - regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
- -@@ -119,6 +151,7 @@ static const struct regmap_access_table
- -
- - /* AXP288 ranges are shared with the AXP803, as they cover the same range */
- - static const struct regmap_range axp288_writeable_ranges[] = {
- -+ regmap_reg_range(AXP288_POWER_REASON, AXP288_POWER_REASON),
- - regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
- - regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
- - };
- -@@ -154,6 +187,25 @@ static const struct regmap_range axp806_
- - regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
- - };
- -
- -+static const struct regmap_range axp313a_writeable_ranges[] = {
- -+ regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
- -+};
- -+
- -+static const struct regmap_range axp313a_volatile_ranges[] = {
- -+ regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
- -+ regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
- -+};
- -+
- -+static const struct regmap_access_table axp313a_writeable_table = {
- -+ .yes_ranges = axp313a_writeable_ranges,
- -+ .n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
- -+};
- -+
- -+static const struct regmap_access_table axp313a_volatile_table = {
- -+ .yes_ranges = axp313a_volatile_ranges,
- -+ .n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
- -+};
- -+
- - static const struct regmap_range axp806_volatile_ranges[] = {
- - regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
- - };
- -@@ -168,11 +220,49 @@ static const struct regmap_access_table
- - .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges),
- - };
- -
- -+static const struct regmap_range axp15060_writeable_ranges[] = {
- -+ regmap_reg_range(AXP15060_PWR_OUT_CTRL1, AXP15060_DCDC_MODE_CTRL2),
- -+ regmap_reg_range(AXP15060_OUTPUT_MONITOR_DISCHARGE, AXP15060_CPUSLDO_V_CTRL),
- -+ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
- -+ regmap_reg_range(AXP15060_PEK_KEY, AXP15060_PEK_KEY),
- -+ regmap_reg_range(AXP15060_IRQ1_EN, AXP15060_IRQ2_EN),
- -+ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
- -+};
- -+
- -+static const struct regmap_range axp15060_volatile_ranges[] = {
- -+ regmap_reg_range(AXP15060_STARTUP_SRC, AXP15060_STARTUP_SRC),
- -+ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
- -+ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
- -+};
- -+
- -+static const struct regmap_access_table axp15060_writeable_table = {
- -+ .yes_ranges = axp15060_writeable_ranges,
- -+ .n_yes_ranges = ARRAY_SIZE(axp15060_writeable_ranges),
- -+};
- -+
- -+static const struct regmap_access_table axp15060_volatile_table = {
- -+ .yes_ranges = axp15060_volatile_ranges,
- -+ .n_yes_ranges = ARRAY_SIZE(axp15060_volatile_ranges),
- -+};
- -+
- - static const struct resource axp152_pek_resources[] = {
- - DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- - DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- - };
- -
- -+static const struct resource axp192_ac_power_supply_resources[] = {
- -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
- -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
- -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
- -+};
- -+
- -+static const struct resource axp192_usb_power_supply_resources[] = {
- -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
- -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
- -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"),
- -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
- -+};
- -+
- - static const struct resource axp20x_ac_power_supply_resources[] = {
- - DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
- - DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
- -@@ -221,6 +311,11 @@ static const struct resource axp288_fuel
- - DEFINE_RES_IRQ(AXP288_IRQ_WL1),
- - };
- -
- -+static const struct resource axp313a_pek_resources[] = {
- -+ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- -+ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- -+};
- -+
- - static const struct resource axp803_pek_resources[] = {
- - DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- - DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- -@@ -236,6 +331,11 @@ static const struct resource axp809_pek_
- - DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- - };
- -
- -+static const struct resource axp15060_pek_resources[] = {
- -+ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
- -+ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
- -+};
- -+
- - static const struct regmap_config axp152_regmap_config = {
- - .reg_bits = 8,
- - .val_bits = 8,
- -@@ -245,6 +345,15 @@ static const struct regmap_config axp152
- - .cache_type = REGCACHE_RBTREE,
- - };
- -
- -+static const struct regmap_config axp192_regmap_config = {
- -+ .reg_bits = 8,
- -+ .val_bits = 8,
- -+ .wr_table = &axp192_writeable_table,
- -+ .volatile_table = &axp192_volatile_table,
- -+ .max_register = AXP20X_CC_CTRL,
- -+ .cache_type = REGCACHE_RBTREE,
- -+};
- -+
- - static const struct regmap_config axp20x_regmap_config = {
- - .reg_bits = 8,
- - .val_bits = 8,
- -@@ -272,6 +381,15 @@ static const struct regmap_config axp288
- - .cache_type = REGCACHE_RBTREE,
- - };
- -
- -+static const struct regmap_config axp313a_regmap_config = {
- -+ .reg_bits = 8,
- -+ .val_bits = 8,
- -+ .wr_table = &axp313a_writeable_table,
- -+ .volatile_table = &axp313a_volatile_table,
- -+ .max_register = AXP313A_IRQ_STATE,
- -+ .cache_type = REGCACHE_RBTREE,
- -+};
- -+
- - static const struct regmap_config axp806_regmap_config = {
- - .reg_bits = 8,
- - .val_bits = 8,
- -@@ -281,6 +399,15 @@ static const struct regmap_config axp806
- - .cache_type = REGCACHE_RBTREE,
- - };
- -
- -+static const struct regmap_config axp15060_regmap_config = {
- -+ .reg_bits = 8,
- -+ .val_bits = 8,
- -+ .wr_table = &axp15060_writeable_table,
- -+ .volatile_table = &axp15060_volatile_table,
- -+ .max_register = AXP15060_IRQ2_STATE,
- -+ .cache_type = REGCACHE_RBTREE,
- -+};
- -+
- - #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \
- - [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
- -
- -@@ -304,6 +431,42 @@ static const struct regmap_irq axp152_re
- - INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0),
- - };
- -
- -+static const struct regmap_irq axp192_regmap_irqs[] = {
- -+ INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V, 0, 7),
- -+ INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN, 0, 6),
- -+ INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL, 0, 5),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V, 0, 4),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN, 0, 3),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL, 0, 2),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW, 0, 1),
- -+ INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN, 1, 7),
- -+ INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL, 1, 6),
- -+ INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE, 1, 5),
- -+ INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE, 1, 4),
- -+ INIT_REGMAP_IRQ(AXP192, CHARG, 1, 3),
- -+ INIT_REGMAP_IRQ(AXP192, CHARG_DONE, 1, 2),
- -+ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH, 1, 1),
- -+ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW, 1, 0),
- -+ INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH, 2, 7),
- -+ INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW, 2, 6),
- -+ INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG, 2, 5),
- -+ INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG, 2, 4),
- -+ INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG, 2, 3),
- -+ INIT_REGMAP_IRQ(AXP192, PEK_SHORT, 2, 1),
- -+ INIT_REGMAP_IRQ(AXP192, PEK_LONG, 2, 0),
- -+ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON, 3, 7),
- -+ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF, 3, 6),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_VALID, 3, 5),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID, 3, 4),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID, 3, 3),
- -+ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END, 3, 2),
- -+ INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL, 3, 0),
- -+ INIT_REGMAP_IRQ(AXP192, TIMER, 4, 7),
- -+ INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT, 4, 2),
- -+ INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT, 4, 1),
- -+ INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT, 4, 0),
- -+};
- -+
- - static const struct regmap_irq axp20x_regmap_irqs[] = {
- - INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7),
- - INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6),
- -@@ -415,6 +578,16 @@ static const struct regmap_irq axp288_re
- - INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
- - };
- -
- -+static const struct regmap_irq axp313a_regmap_irqs[] = {
- -+ INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE, 0, 7),
- -+ INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE, 0, 6),
- -+ INIT_REGMAP_IRQ(AXP313A, PEK_SHORT, 0, 5),
- -+ INIT_REGMAP_IRQ(AXP313A, PEK_LONG, 0, 4),
- -+ INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW, 0, 3),
- -+ INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW, 0, 2),
- -+ INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH, 0, 0),
- -+};
- -+
- - static const struct regmap_irq axp803_regmap_irqs[] = {
- - INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7),
- - INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6),
- -@@ -502,24 +675,65 @@ static const struct regmap_irq axp809_re
- - INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0),
- - };
- -
- -+static const struct regmap_irq axp15060_regmap_irqs[] = {
- -+ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV1, 0, 0),
- -+ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV2, 0, 1),
- -+ INIT_REGMAP_IRQ(AXP15060, DCDC1_V_LOW, 0, 2),
- -+ INIT_REGMAP_IRQ(AXP15060, DCDC2_V_LOW, 0, 3),
- -+ INIT_REGMAP_IRQ(AXP15060, DCDC3_V_LOW, 0, 4),
- -+ INIT_REGMAP_IRQ(AXP15060, DCDC4_V_LOW, 0, 5),
- -+ INIT_REGMAP_IRQ(AXP15060, DCDC5_V_LOW, 0, 6),
- -+ INIT_REGMAP_IRQ(AXP15060, DCDC6_V_LOW, 0, 7),
- -+ INIT_REGMAP_IRQ(AXP15060, PEK_LONG, 1, 0),
- -+ INIT_REGMAP_IRQ(AXP15060, PEK_SHORT, 1, 1),
- -+ INIT_REGMAP_IRQ(AXP15060, GPIO1_INPUT, 1, 2),
- -+ INIT_REGMAP_IRQ(AXP15060, PEK_FAL_EDGE, 1, 3),
- -+ INIT_REGMAP_IRQ(AXP15060, PEK_RIS_EDGE, 1, 4),
- -+ INIT_REGMAP_IRQ(AXP15060, GPIO2_INPUT, 1, 5),
- -+};
- -+
- - static const struct regmap_irq_chip axp152_regmap_irq_chip = {
- - .name = "axp152_irq_chip",
- - .status_base = AXP152_IRQ1_STATE,
- - .ack_base = AXP152_IRQ1_STATE,
- -- .mask_base = AXP152_IRQ1_EN,
- -- .mask_invert = true,
- -+ .unmask_base = AXP152_IRQ1_EN,
- - .init_ack_masked = true,
- - .irqs = axp152_regmap_irqs,
- - .num_irqs = ARRAY_SIZE(axp152_regmap_irqs),
- - .num_regs = 3,
- - };
- -
- -+static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data,
- -+ unsigned int base, int index)
- -+{
- -+ /* linear mapping for IRQ1 to IRQ4 */
- -+ if (index < 4)
- -+ return base + index;
- -+
- -+ /* handle IRQ5 separately */
- -+ if (base == AXP192_IRQ1_EN)
- -+ return AXP192_IRQ5_EN;
- -+
- -+ return AXP192_IRQ5_STATE;
- -+}
- -+
- -+static const struct regmap_irq_chip axp192_regmap_irq_chip = {
- -+ .name = "axp192_irq_chip",
- -+ .status_base = AXP192_IRQ1_STATE,
- -+ .ack_base = AXP192_IRQ1_STATE,
- -+ .unmask_base = AXP192_IRQ1_EN,
- -+ .init_ack_masked = true,
- -+ .irqs = axp192_regmap_irqs,
- -+ .num_irqs = ARRAY_SIZE(axp192_regmap_irqs),
- -+ .num_regs = 5,
- -+ .get_irq_reg = axp192_get_irq_reg,
- -+};
- -+
- - static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
- - .name = "axp20x_irq_chip",
- - .status_base = AXP20X_IRQ1_STATE,
- - .ack_base = AXP20X_IRQ1_STATE,
- -- .mask_base = AXP20X_IRQ1_EN,
- -- .mask_invert = true,
- -+ .unmask_base = AXP20X_IRQ1_EN,
- - .init_ack_masked = true,
- - .irqs = axp20x_regmap_irqs,
- - .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs),
- -@@ -531,8 +745,7 @@ static const struct regmap_irq_chip axp2
- - .name = "axp22x_irq_chip",
- - .status_base = AXP20X_IRQ1_STATE,
- - .ack_base = AXP20X_IRQ1_STATE,
- -- .mask_base = AXP20X_IRQ1_EN,
- -- .mask_invert = true,
- -+ .unmask_base = AXP20X_IRQ1_EN,
- - .init_ack_masked = true,
- - .irqs = axp22x_regmap_irqs,
- - .num_irqs = ARRAY_SIZE(axp22x_regmap_irqs),
- -@@ -543,8 +756,7 @@ static const struct regmap_irq_chip axp2
- - .name = "axp288_irq_chip",
- - .status_base = AXP20X_IRQ1_STATE,
- - .ack_base = AXP20X_IRQ1_STATE,
- -- .mask_base = AXP20X_IRQ1_EN,
- -- .mask_invert = true,
- -+ .unmask_base = AXP20X_IRQ1_EN,
- - .init_ack_masked = true,
- - .irqs = axp288_regmap_irqs,
- - .num_irqs = ARRAY_SIZE(axp288_regmap_irqs),
- -@@ -552,12 +764,22 @@ static const struct regmap_irq_chip axp2
- -
- - };
- -
- -+static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
- -+ .name = "axp313a_irq_chip",
- -+ .status_base = AXP313A_IRQ_STATE,
- -+ .ack_base = AXP313A_IRQ_STATE,
- -+ .unmask_base = AXP313A_IRQ_EN,
- -+ .init_ack_masked = true,
- -+ .irqs = axp313a_regmap_irqs,
- -+ .num_irqs = ARRAY_SIZE(axp313a_regmap_irqs),
- -+ .num_regs = 1,
- -+};
- -+
- - static const struct regmap_irq_chip axp803_regmap_irq_chip = {
- - .name = "axp803",
- - .status_base = AXP20X_IRQ1_STATE,
- - .ack_base = AXP20X_IRQ1_STATE,
- -- .mask_base = AXP20X_IRQ1_EN,
- -- .mask_invert = true,
- -+ .unmask_base = AXP20X_IRQ1_EN,
- - .init_ack_masked = true,
- - .irqs = axp803_regmap_irqs,
- - .num_irqs = ARRAY_SIZE(axp803_regmap_irqs),
- -@@ -568,8 +790,7 @@ static const struct regmap_irq_chip axp8
- - .name = "axp806",
- - .status_base = AXP20X_IRQ1_STATE,
- - .ack_base = AXP20X_IRQ1_STATE,
- -- .mask_base = AXP20X_IRQ1_EN,
- -- .mask_invert = true,
- -+ .unmask_base = AXP20X_IRQ1_EN,
- - .init_ack_masked = true,
- - .irqs = axp806_regmap_irqs,
- - .num_irqs = ARRAY_SIZE(axp806_regmap_irqs),
- -@@ -580,14 +801,45 @@ static const struct regmap_irq_chip axp8
- - .name = "axp809",
- - .status_base = AXP20X_IRQ1_STATE,
- - .ack_base = AXP20X_IRQ1_STATE,
- -- .mask_base = AXP20X_IRQ1_EN,
- -- .mask_invert = true,
- -+ .unmask_base = AXP20X_IRQ1_EN,
- - .init_ack_masked = true,
- - .irqs = axp809_regmap_irqs,
- - .num_irqs = ARRAY_SIZE(axp809_regmap_irqs),
- - .num_regs = 5,
- - };
- -
- -+static const struct regmap_irq_chip axp15060_regmap_irq_chip = {
- -+ .name = "axp15060",
- -+ .status_base = AXP15060_IRQ1_STATE,
- -+ .ack_base = AXP15060_IRQ1_STATE,
- -+ .unmask_base = AXP15060_IRQ1_EN,
- -+ .init_ack_masked = true,
- -+ .irqs = axp15060_regmap_irqs,
- -+ .num_irqs = ARRAY_SIZE(axp15060_regmap_irqs),
- -+ .num_regs = 2,
- -+};
- -+
- -+static const struct mfd_cell axp192_cells[] = {
- -+ {
- -+ .name = "axp192-adc",
- -+ .of_compatible = "x-powers,axp192-adc",
- -+ }, {
- -+ .name = "axp20x-battery-power-supply",
- -+ .of_compatible = "x-powers,axp192-battery-power-supply",
- -+ }, {
- -+ .name = "axp20x-ac-power-supply",
- -+ .of_compatible = "x-powers,axp202-ac-power-supply",
- -+ .num_resources = ARRAY_SIZE(axp192_ac_power_supply_resources),
- -+ .resources = axp192_ac_power_supply_resources,
- -+ }, {
- -+ .name = "axp20x-usb-power-supply",
- -+ .of_compatible = "x-powers,axp192-usb-power-supply",
- -+ .num_resources = ARRAY_SIZE(axp192_usb_power_supply_resources),
- -+ .resources = axp192_usb_power_supply_resources,
- -+ },
- -+ { .name = "axp20x-regulator" },
- -+};
- -+
- - static const struct mfd_cell axp20x_cells[] = {
- - {
- - .name = "axp20x-gpio",
- -@@ -683,6 +935,11 @@ static const struct mfd_cell axp152_cell
- - },
- - };
- -
- -+static struct mfd_cell axp313a_cells[] = {
- -+ MFD_CELL_NAME("axp20x-regulator"),
- -+ MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
- -+};
- -+
- - static const struct resource axp288_adc_resources[] = {
- - DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
- - };
- -@@ -832,17 +1089,43 @@ static const struct mfd_cell axp813_cell
- - },
- - };
- -
- --static struct axp20x_dev *axp20x_pm_power_off;
- --static void axp20x_power_off(void)
- -+static const struct mfd_cell axp15060_cells[] = {
- -+ {
- -+ .name = "axp221-pek",
- -+ .num_resources = ARRAY_SIZE(axp15060_pek_resources),
- -+ .resources = axp15060_pek_resources,
- -+ }, {
- -+ .name = "axp20x-regulator",
- -+ },
- -+};
- -+
- -+/* For boards that don't have IRQ line connected to SOC. */
- -+static const struct mfd_cell axp_regulator_only_cells[] = {
- -+ {
- -+ .name = "axp20x-regulator",
- -+ },
- -+};
- -+
- -+static int axp20x_power_off(struct sys_off_data *data)
- - {
- -- if (axp20x_pm_power_off->variant == AXP288_ID)
- -- return;
- -+ struct axp20x_dev *axp20x = data->cb_data;
- -+ unsigned int shutdown_reg;
- -
- -- regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
- -- AXP20X_OFF);
- -+ switch (axp20x->variant) {
- -+ case AXP313A_ID:
- -+ shutdown_reg = AXP313A_SHUTDOWN_CTRL;
- -+ break;
- -+ default:
- -+ shutdown_reg = AXP20X_OFF_CTRL;
- -+ break;
- -+ }
- -+
- -+ regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
- -
- - /* Give capacitors etc. time to drain to avoid kernel panic msg. */
- - mdelay(500);
- -+
- -+ return NOTIFY_DONE;
- - }
- -
- - int axp20x_match_device(struct axp20x_dev *axp20x)
- -@@ -874,6 +1157,12 @@ int axp20x_match_device(struct axp20x_de
- - axp20x->regmap_cfg = &axp152_regmap_config;
- - axp20x->regmap_irq_chip = &axp152_regmap_irq_chip;
- - break;
- -+ case AXP192_ID:
- -+ axp20x->nr_cells = ARRAY_SIZE(axp192_cells);
- -+ axp20x->cells = axp192_cells;
- -+ axp20x->regmap_cfg = &axp192_regmap_config;
- -+ axp20x->regmap_irq_chip = &axp192_regmap_irq_chip;
- -+ break;
- - case AXP202_ID:
- - case AXP209_ID:
- - axp20x->nr_cells = ARRAY_SIZE(axp20x_cells);
- -@@ -900,6 +1189,12 @@ int axp20x_match_device(struct axp20x_de
- - axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
- - axp20x->irq_flags = IRQF_TRIGGER_LOW;
- - break;
- -+ case AXP313A_ID:
- -+ axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
- -+ axp20x->cells = axp313a_cells;
- -+ axp20x->regmap_cfg = &axp313a_regmap_config;
- -+ axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
- -+ break;
- - case AXP803_ID:
- - axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
- - axp20x->cells = axp803_cells;
- -@@ -942,6 +1237,28 @@ int axp20x_match_device(struct axp20x_de
- - */
- - axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
- - break;
- -+ case AXP15060_ID:
- -+ /*
- -+ * Don't register the power key part if there is no interrupt
- -+ * line.
- -+ *
- -+ * Since most use cases of AXP PMICs are Allwinner SOCs, board
- -+ * designers follow Allwinner's reference design and connects
- -+ * IRQ line to SOC, there's no need for those variants to deal
- -+ * with cases that IRQ isn't connected. However, AXP15660 is
- -+ * used by some other vendors' SOCs that didn't connect IRQ
- -+ * line, we need to deal with this case.
- -+ */
- -+ if (axp20x->irq > 0) {
- -+ axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
- -+ axp20x->cells = axp15060_cells;
- -+ } else {
- -+ axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
- -+ axp20x->cells = axp_regulator_only_cells;
- -+ }
- -+ axp20x->regmap_cfg = &axp15060_regmap_config;
- -+ axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip;
- -+ break;
- - default:
- - dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
- - return -EINVAL;
- -@@ -1009,10 +1326,11 @@ int axp20x_device_probe(struct axp20x_de
- - return ret;
- - }
- -
- -- if (!pm_power_off) {
- -- axp20x_pm_power_off = axp20x;
- -- pm_power_off = axp20x_power_off;
- -- }
- -+ if (axp20x->variant != AXP288_ID)
- -+ devm_register_sys_off_handler(axp20x->dev,
- -+ SYS_OFF_MODE_POWER_OFF,
- -+ SYS_OFF_PRIO_DEFAULT,
- -+ axp20x_power_off, axp20x);
- -
- - dev_info(axp20x->dev, "AXP20X driver loaded\n");
- -
- -@@ -1022,11 +1340,6 @@ EXPORT_SYMBOL(axp20x_device_probe);
- -
- - void axp20x_device_remove(struct axp20x_dev *axp20x)
- - {
- -- if (axp20x == axp20x_pm_power_off) {
- -- axp20x_pm_power_off = NULL;
- -- pm_power_off = NULL;
- -- }
- --
- - mfd_remove_devices(axp20x->dev);
- - regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
- - }
- ---- a/include/linux/mfd/axp20x.h
- -+++ b/include/linux/mfd/axp20x.h
- -@@ -12,18 +12,22 @@
- -
- - enum axp20x_variants {
- - AXP152_ID = 0,
- -+ AXP192_ID,
- - AXP202_ID,
- - AXP209_ID,
- - AXP221_ID,
- - AXP223_ID,
- - AXP288_ID,
- -+ AXP313A_ID,
- - AXP803_ID,
- - AXP806_ID,
- - AXP809_ID,
- - AXP813_ID,
- -+ AXP15060_ID,
- - NR_AXP20X_VARIANTS,
- - };
- -
- -+#define AXP192_DATACACHE(m) (0x06 + (m))
- - #define AXP20X_DATACACHE(m) (0x04 + (m))
- -
- - /* Power supply */
- -@@ -45,6 +49,13 @@ enum axp20x_variants {
- - #define AXP152_DCDC_FREQ 0x37
- - #define AXP152_DCDC_MODE 0x80
- -
- -+#define AXP192_USB_OTG_STATUS 0x04
- -+#define AXP192_PWR_OUT_CTRL 0x12
- -+#define AXP192_DCDC2_V_OUT 0x23
- -+#define AXP192_DCDC1_V_OUT 0x26
- -+#define AXP192_DCDC3_V_OUT 0x27
- -+#define AXP192_LDO2_3_V_OUT 0x28
- -+
- - #define AXP20X_PWR_INPUT_STATUS 0x00
- - #define AXP20X_PWR_OP_MODE 0x01
- - #define AXP20X_USB_OTG_STATUS 0x02
- -@@ -91,6 +102,17 @@ enum axp20x_variants {
- - #define AXP22X_ALDO3_V_OUT 0x2a
- - #define AXP22X_CHRG_CTRL3 0x35
- -
- -+#define AXP313A_ON_INDICATE 0x00
- -+#define AXP313A_OUTPUT_CONTROL 0x10
- -+#define AXP313A_DCDC1_CONRTOL 0x13
- -+#define AXP313A_DCDC2_CONRTOL 0x14
- -+#define AXP313A_DCDC3_CONRTOL 0x15
- -+#define AXP313A_ALDO1_CONRTOL 0x16
- -+#define AXP313A_DLDO1_CONRTOL 0x17
- -+#define AXP313A_SHUTDOWN_CTRL 0x1a
- -+#define AXP313A_IRQ_EN 0x20
- -+#define AXP313A_IRQ_STATE 0x21
- -+
- - #define AXP806_STARTUP_SRC 0x00
- - #define AXP806_CHIP_ID 0x03
- - #define AXP806_PWR_OUT_CTRL1 0x10
- -@@ -131,6 +153,39 @@ enum axp20x_variants {
- - /* Other DCDC regulator control registers are the same as AXP803 */
- - #define AXP813_DCDC7_V_OUT 0x26
- -
- -+#define AXP15060_STARTUP_SRC 0x00
- -+#define AXP15060_PWR_OUT_CTRL1 0x10
- -+#define AXP15060_PWR_OUT_CTRL2 0x11
- -+#define AXP15060_PWR_OUT_CTRL3 0x12
- -+#define AXP15060_DCDC1_V_CTRL 0x13
- -+#define AXP15060_DCDC2_V_CTRL 0x14
- -+#define AXP15060_DCDC3_V_CTRL 0x15
- -+#define AXP15060_DCDC4_V_CTRL 0x16
- -+#define AXP15060_DCDC5_V_CTRL 0x17
- -+#define AXP15060_DCDC6_V_CTRL 0x18
- -+#define AXP15060_ALDO1_V_CTRL 0x19
- -+#define AXP15060_DCDC_MODE_CTRL1 0x1a
- -+#define AXP15060_DCDC_MODE_CTRL2 0x1b
- -+#define AXP15060_OUTPUT_MONITOR_DISCHARGE 0x1e
- -+#define AXP15060_IRQ_PWROK_VOFF 0x1f
- -+#define AXP15060_ALDO2_V_CTRL 0x20
- -+#define AXP15060_ALDO3_V_CTRL 0x21
- -+#define AXP15060_ALDO4_V_CTRL 0x22
- -+#define AXP15060_ALDO5_V_CTRL 0x23
- -+#define AXP15060_BLDO1_V_CTRL 0x24
- -+#define AXP15060_BLDO2_V_CTRL 0x25
- -+#define AXP15060_BLDO3_V_CTRL 0x26
- -+#define AXP15060_BLDO4_V_CTRL 0x27
- -+#define AXP15060_BLDO5_V_CTRL 0x28
- -+#define AXP15060_CLDO1_V_CTRL 0x29
- -+#define AXP15060_CLDO2_V_CTRL 0x2a
- -+#define AXP15060_CLDO3_V_CTRL 0x2b
- -+#define AXP15060_CLDO4_V_CTRL 0x2d
- -+#define AXP15060_CPUSLDO_V_CTRL 0x2e
- -+#define AXP15060_PWR_WAKEUP_CTRL 0x31
- -+#define AXP15060_PWR_DISABLE_DOWN_SEQ 0x32
- -+#define AXP15060_PEK_KEY 0x36
- -+
- - /* Interrupt */
- - #define AXP152_IRQ1_EN 0x40
- - #define AXP152_IRQ2_EN 0x41
- -@@ -139,6 +194,17 @@ enum axp20x_variants {
- - #define AXP152_IRQ2_STATE 0x49
- - #define AXP152_IRQ3_STATE 0x4a
- -
- -+#define AXP192_IRQ1_EN 0x40
- -+#define AXP192_IRQ2_EN 0x41
- -+#define AXP192_IRQ3_EN 0x42
- -+#define AXP192_IRQ4_EN 0x43
- -+#define AXP192_IRQ1_STATE 0x44
- -+#define AXP192_IRQ2_STATE 0x45
- -+#define AXP192_IRQ3_STATE 0x46
- -+#define AXP192_IRQ4_STATE 0x47
- -+#define AXP192_IRQ5_EN 0x4a
- -+#define AXP192_IRQ5_STATE 0x4d
- -+
- - #define AXP20X_IRQ1_EN 0x40
- - #define AXP20X_IRQ2_EN 0x41
- - #define AXP20X_IRQ3_EN 0x42
- -@@ -152,7 +218,17 @@ enum axp20x_variants {
- - #define AXP20X_IRQ5_STATE 0x4c
- - #define AXP20X_IRQ6_STATE 0x4d
- -
- -+#define AXP15060_IRQ1_EN 0x40
- -+#define AXP15060_IRQ2_EN 0x41
- -+#define AXP15060_IRQ1_STATE 0x48
- -+#define AXP15060_IRQ2_STATE 0x49
- -+
- - /* ADC */
- -+#define AXP192_GPIO2_V_ADC_H 0x68
- -+#define AXP192_GPIO2_V_ADC_L 0x69
- -+#define AXP192_GPIO3_V_ADC_H 0x6a
- -+#define AXP192_GPIO3_V_ADC_L 0x6b
- -+
- - #define AXP20X_ACIN_V_ADC_H 0x56
- - #define AXP20X_ACIN_V_ADC_L 0x57
- - #define AXP20X_ACIN_I_ADC_H 0x58
- -@@ -182,6 +258,8 @@ enum axp20x_variants {
- - #define AXP20X_IPSOUT_V_HIGH_L 0x7f
- -
- - /* Power supply */
- -+#define AXP192_GPIO30_IN_RANGE 0x85
- -+
- - #define AXP20X_DCDC_MODE 0x80
- - #define AXP20X_ADC_EN1 0x82
- - #define AXP20X_ADC_EN2 0x83
- -@@ -210,6 +288,16 @@ enum axp20x_variants {
- - #define AXP152_PWM1_FREQ_Y 0x9c
- - #define AXP152_PWM1_DUTY_CYCLE 0x9d
- -
- -+#define AXP192_GPIO0_CTRL 0x90
- -+#define AXP192_LDO_IO0_V_OUT 0x91
- -+#define AXP192_GPIO1_CTRL 0x92
- -+#define AXP192_GPIO2_CTRL 0x93
- -+#define AXP192_GPIO2_0_STATE 0x94
- -+#define AXP192_GPIO4_3_CTRL 0x95
- -+#define AXP192_GPIO4_3_STATE 0x96
- -+#define AXP192_GPIO2_0_PULL 0x97
- -+#define AXP192_N_RSTO_CTRL 0x9e
- -+
- - #define AXP20X_GPIO0_CTRL 0x90
- - #define AXP20X_LDO5_V_OUT 0x91
- - #define AXP20X_GPIO1_CTRL 0x92
- -@@ -222,6 +310,8 @@ enum axp20x_variants {
- - #define AXP22X_GPIO_STATE 0x94
- - #define AXP22X_GPIO_PULL_DOWN 0x95
- -
- -+#define AXP15060_CLDO4_GPIO2_MODESET 0x2c
- -+
- - /* Battery */
- - #define AXP20X_CHRG_CC_31_24 0xb0
- - #define AXP20X_CHRG_CC_23_16 0xb1
- -@@ -288,6 +378,17 @@ enum axp20x_variants {
- -
- - /* Regulators IDs */
- - enum {
- -+ AXP192_DCDC1 = 0,
- -+ AXP192_DCDC2,
- -+ AXP192_DCDC3,
- -+ AXP192_LDO1,
- -+ AXP192_LDO2,
- -+ AXP192_LDO3,
- -+ AXP192_LDO_IO0,
- -+ AXP192_REG_ID_MAX
- -+};
- -+
- -+enum {
- - AXP20X_LDO1 = 0,
- - AXP20X_LDO2,
- - AXP20X_LDO3,
- -@@ -323,6 +424,16 @@ enum {
- - };
- -
- - enum {
- -+ AXP313A_DCDC1 = 0,
- -+ AXP313A_DCDC2,
- -+ AXP313A_DCDC3,
- -+ AXP313A_ALDO1,
- -+ AXP313A_DLDO1,
- -+ AXP313A_RTC_LDO,
- -+ AXP313A_REG_ID_MAX,
- -+};
- -+
- -+enum {
- - AXP806_DCDCA = 0,
- - AXP806_DCDCB,
- - AXP806_DCDCC,
- -@@ -419,6 +530,33 @@ enum {
- - AXP813_REG_ID_MAX,
- - };
- -
- -+enum {
- -+ AXP15060_DCDC1 = 0,
- -+ AXP15060_DCDC2,
- -+ AXP15060_DCDC3,
- -+ AXP15060_DCDC4,
- -+ AXP15060_DCDC5,
- -+ AXP15060_DCDC6,
- -+ AXP15060_ALDO1,
- -+ AXP15060_ALDO2,
- -+ AXP15060_ALDO3,
- -+ AXP15060_ALDO4,
- -+ AXP15060_ALDO5,
- -+ AXP15060_BLDO1,
- -+ AXP15060_BLDO2,
- -+ AXP15060_BLDO3,
- -+ AXP15060_BLDO4,
- -+ AXP15060_BLDO5,
- -+ AXP15060_CLDO1,
- -+ AXP15060_CLDO2,
- -+ AXP15060_CLDO3,
- -+ AXP15060_CLDO4,
- -+ AXP15060_CPUSLDO,
- -+ AXP15060_SW,
- -+ AXP15060_RTC_LDO,
- -+ AXP15060_REG_ID_MAX,
- -+};
- -+
- - /* IRQs */
- - enum {
- - AXP152_IRQ_LDO0IN_CONNECT = 1,
- -@@ -432,14 +570,51 @@ enum {
- - AXP152_IRQ_PEK_SHORT,
- - AXP152_IRQ_PEK_LONG,
- - AXP152_IRQ_TIMER,
- -- AXP152_IRQ_PEK_RIS_EDGE,
- -+ /* out of bit order to make sure the press event is handled first */
- - AXP152_IRQ_PEK_FAL_EDGE,
- -+ AXP152_IRQ_PEK_RIS_EDGE,
- - AXP152_IRQ_GPIO3_INPUT,
- - AXP152_IRQ_GPIO2_INPUT,
- - AXP152_IRQ_GPIO1_INPUT,
- - AXP152_IRQ_GPIO0_INPUT,
- - };
- -
- -+enum axp192_irqs {
- -+ AXP192_IRQ_ACIN_OVER_V = 1,
- -+ AXP192_IRQ_ACIN_PLUGIN,
- -+ AXP192_IRQ_ACIN_REMOVAL,
- -+ AXP192_IRQ_VBUS_OVER_V,
- -+ AXP192_IRQ_VBUS_PLUGIN,
- -+ AXP192_IRQ_VBUS_REMOVAL,
- -+ AXP192_IRQ_VBUS_V_LOW,
- -+ AXP192_IRQ_BATT_PLUGIN,
- -+ AXP192_IRQ_BATT_REMOVAL,
- -+ AXP192_IRQ_BATT_ENT_ACT_MODE,
- -+ AXP192_IRQ_BATT_EXIT_ACT_MODE,
- -+ AXP192_IRQ_CHARG,
- -+ AXP192_IRQ_CHARG_DONE,
- -+ AXP192_IRQ_BATT_TEMP_HIGH,
- -+ AXP192_IRQ_BATT_TEMP_LOW,
- -+ AXP192_IRQ_DIE_TEMP_HIGH,
- -+ AXP192_IRQ_CHARG_I_LOW,
- -+ AXP192_IRQ_DCDC1_V_LONG,
- -+ AXP192_IRQ_DCDC2_V_LONG,
- -+ AXP192_IRQ_DCDC3_V_LONG,
- -+ AXP192_IRQ_PEK_SHORT = 22,
- -+ AXP192_IRQ_PEK_LONG,
- -+ AXP192_IRQ_N_OE_PWR_ON,
- -+ AXP192_IRQ_N_OE_PWR_OFF,
- -+ AXP192_IRQ_VBUS_VALID,
- -+ AXP192_IRQ_VBUS_NOT_VALID,
- -+ AXP192_IRQ_VBUS_SESS_VALID,
- -+ AXP192_IRQ_VBUS_SESS_END,
- -+ AXP192_IRQ_LOW_PWR_LVL = 31,
- -+ AXP192_IRQ_TIMER,
- -+ AXP192_IRQ_GPIO2_INPUT = 37,
- -+ AXP192_IRQ_GPIO1_INPUT,
- -+ AXP192_IRQ_GPIO0_INPUT,
- -+};
- -+
- - enum {
- - AXP20X_IRQ_ACIN_OVER_V = 1,
- - AXP20X_IRQ_ACIN_PLUGIN,
- -@@ -472,8 +647,9 @@ enum {
- - AXP20X_IRQ_LOW_PWR_LVL1,
- - AXP20X_IRQ_LOW_PWR_LVL2,
- - AXP20X_IRQ_TIMER,
- -- AXP20X_IRQ_PEK_RIS_EDGE,
- -+ /* out of bit order to make sure the press event is handled first */
- - AXP20X_IRQ_PEK_FAL_EDGE,
- -+ AXP20X_IRQ_PEK_RIS_EDGE,
- - AXP20X_IRQ_GPIO3_INPUT,
- - AXP20X_IRQ_GPIO2_INPUT,
- - AXP20X_IRQ_GPIO1_INPUT,
- -@@ -502,8 +678,9 @@ enum axp22x_irqs {
- - AXP22X_IRQ_LOW_PWR_LVL1,
- - AXP22X_IRQ_LOW_PWR_LVL2,
- - AXP22X_IRQ_TIMER,
- -- AXP22X_IRQ_PEK_RIS_EDGE,
- -+ /* out of bit order to make sure the press event is handled first */
- - AXP22X_IRQ_PEK_FAL_EDGE,
- -+ AXP22X_IRQ_PEK_RIS_EDGE,
- - AXP22X_IRQ_GPIO1_INPUT,
- - AXP22X_IRQ_GPIO0_INPUT,
- - };
- -@@ -545,6 +722,16 @@ enum axp288_irqs {
- - AXP288_IRQ_BC_USB_CHNG,
- - };
- -
- -+enum axp313a_irqs {
- -+ AXP313A_IRQ_DIE_TEMP_HIGH,
- -+ AXP313A_IRQ_DCDC2_V_LOW = 2,
- -+ AXP313A_IRQ_DCDC3_V_LOW,
- -+ AXP313A_IRQ_PEK_LONG,
- -+ AXP313A_IRQ_PEK_SHORT,
- -+ AXP313A_IRQ_PEK_FAL_EDGE,
- -+ AXP313A_IRQ_PEK_RIS_EDGE,
- -+};
- -+
- - enum axp803_irqs {
- - AXP803_IRQ_ACIN_OVER_V = 1,
- - AXP803_IRQ_ACIN_PLUGIN,
- -@@ -571,8 +758,9 @@ enum axp803_irqs {
- - AXP803_IRQ_LOW_PWR_LVL1,
- - AXP803_IRQ_LOW_PWR_LVL2,
- - AXP803_IRQ_TIMER,
- -- AXP803_IRQ_PEK_RIS_EDGE,
- -+ /* out of bit order to make sure the press event is handled first */
- - AXP803_IRQ_PEK_FAL_EDGE,
- -+ AXP803_IRQ_PEK_RIS_EDGE,
- - AXP803_IRQ_PEK_SHORT,
- - AXP803_IRQ_PEK_LONG,
- - AXP803_IRQ_PEK_OVER_OFF,
- -@@ -623,8 +811,9 @@ enum axp809_irqs {
- - AXP809_IRQ_LOW_PWR_LVL1,
- - AXP809_IRQ_LOW_PWR_LVL2,
- - AXP809_IRQ_TIMER,
- -- AXP809_IRQ_PEK_RIS_EDGE,
- -+ /* out of bit order to make sure the press event is handled first */
- - AXP809_IRQ_PEK_FAL_EDGE,
- -+ AXP809_IRQ_PEK_RIS_EDGE,
- - AXP809_IRQ_PEK_SHORT,
- - AXP809_IRQ_PEK_LONG,
- - AXP809_IRQ_PEK_OVER_OFF,
- -@@ -632,6 +821,23 @@ enum axp809_irqs {
- - AXP809_IRQ_GPIO0_INPUT,
- - };
- -
- -+enum axp15060_irqs {
- -+ AXP15060_IRQ_DIE_TEMP_HIGH_LV1 = 1,
- -+ AXP15060_IRQ_DIE_TEMP_HIGH_LV2,
- -+ AXP15060_IRQ_DCDC1_V_LOW,
- -+ AXP15060_IRQ_DCDC2_V_LOW,
- -+ AXP15060_IRQ_DCDC3_V_LOW,
- -+ AXP15060_IRQ_DCDC4_V_LOW,
- -+ AXP15060_IRQ_DCDC5_V_LOW,
- -+ AXP15060_IRQ_DCDC6_V_LOW,
- -+ AXP15060_IRQ_PEK_LONG,
- -+ AXP15060_IRQ_PEK_SHORT,
- -+ AXP15060_IRQ_GPIO1_INPUT,
- -+ AXP15060_IRQ_PEK_FAL_EDGE,
- -+ AXP15060_IRQ_PEK_RIS_EDGE,
- -+ AXP15060_IRQ_GPIO2_INPUT,
- -+};
- -+
- - struct axp20x_dev {
- - struct device *dev;
- - int irq;
- -@@ -698,4 +904,4 @@ int axp20x_device_probe(struct axp20x_de
- - */
- - void axp20x_device_remove(struct axp20x_dev *axp20x);
- -
- --#endif /* __LINUX_MFD_AXP20X_H */
- -+#endif /* __LINUX_MFD_AXP20X_H */
- -\ No newline at end of file
- From 78ee0a6febcd62e931fe70ce62bd2fe68038dc78 Mon Sep 17 00:00:00 2001
- From: Chukun Pan <[email protected]>
- Date: Sat, 18 Nov 2023 23:10:25 +0800
- Subject: [PATCH 3/4] sunxi: add support for Orange Pi Zero 3
- Key features:
- Allwinner H618 SoC (Quad core Cortex-A53)
- 1/1.5/2/4 GiB LPDDR4 DRAM
- 1 USB 2.0 type C port (Power + OTG)
- 1 USB 2.0 host port
- 1Gbps Ethernet port
- Micro-HDMI port
- MicroSD slot
- Installation:
- Write the image to SD Card with dd.
- Signed-off-by: Chukun Pan <[email protected]>
- ---
- package/boot/uboot-sunxi/Makefile | 10 +
- target/linux/sunxi/cortexa53/config-6.1 | 1 +
- target/linux/sunxi/image/cortexa53.mk | 12 +
- ...inner-h616-Split-Orange-Pi-Zero-2-DT.patch | 305 ++++++++++++++++++
- ...inner-h616-Add-OrangePi-Zero-3-board.patch | 140 ++++++++
- ...inner-h616-update-emac-for-Orange-Pi.patch | 57 ++++
- 6 files changed, 525 insertions(+)
- create mode 100644 target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch
- create mode 100644 target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch
- create mode 100644 target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch
- diff --git a/package/boot/uboot-sunxi/Makefile b/package/boot/uboot-sunxi/Makefile
- index de07dbdec2e97..112ea47d21d76 100644
- --- a/package/boot/uboot-sunxi/Makefile
- +++ b/package/boot/uboot-sunxi/Makefile
- @@ -339,6 +339,15 @@ define U-Boot/orangepi_zero2
- ATF:=h616
- endef
-
- +define U-Boot/orangepi_zero3
- + BUILD_SUBTARGET:=cortexa53
- + NAME:=Xunlong Orange Pi Zero3
- + BUILD_DEVICES:=xunlong_orangepi-zero3
- + DEPENDS:=+PACKAGE_u-boot-orangepi_zero3:trusted-firmware-a-sunxi-h616
- + UENV:=h616
- + ATF:=h616
- +endef
- +
- define U-Boot/Bananapi_M2_Ultra
- BUILD_SUBTARGET:=cortexa7
- NAME:=Bananapi M2 Ultra
- @@ -402,6 +411,7 @@ UBOOT_TARGETS := \
- orangepi_2 \
- orangepi_pc2 \
- orangepi_zero2 \
- + orangepi_zero3 \
- pangolin \
- pine64_plus \
- Sinovoip_BPI_M3 \
- diff --git a/target/linux/sunxi/cortexa53/config-6.1 b/target/linux/sunxi/cortexa53/config-6.1
- index f57c6645403ce..cac7fff4dc9f5 100644
- --- a/target/linux/sunxi/cortexa53/config-6.1
- +++ b/target/linux/sunxi/cortexa53/config-6.1
- @@ -53,6 +53,7 @@ CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
- CONFIG_MDIO_BUS_MUX=y
- CONFIG_MICREL_PHY=y
- CONFIG_MODULES_USE_ELF_RELA=y
- +CONFIG_MOTORCOMM_PHY=y
- CONFIG_MUSB_PIO_ONLY=y
- CONFIG_NEED_SG_DMA_LENGTH=y
- CONFIG_NOP_USB_XCEIV=y
- diff --git a/target/linux/sunxi/image/cortexa53.mk b/target/linux/sunxi/image/cortexa53.mk
- index 80718b34bf294..63ada59f85faf 100644
- --- a/target/linux/sunxi/image/cortexa53.mk
- +++ b/target/linux/sunxi/image/cortexa53.mk
- @@ -29,6 +29,11 @@ define Device/sun50i-h616
- $(Device/sun50i)
- endef
-
- +define Device/sun50i-h618
- + SOC := sun50i-h618
- + $(Device/sun50i)
- +endef
- +
- define Device/friendlyarm_nanopi-neo-plus2
- DEVICE_VENDOR := FriendlyARM
- DEVICE_MODEL := NanoPi NEO Plus2
- @@ -120,6 +125,13 @@ define Device/xunlong_orangepi-zero2
- endef
- TARGET_DEVICES += xunlong_orangepi-zero2
-
- +define Device/xunlong_orangepi-zero3
- + DEVICE_VENDOR := Xunlong
- + DEVICE_MODEL := Orange Pi Zero 3
- + $(Device/sun50i-h618)
- +endef
- +TARGET_DEVICES += xunlong_orangepi-zero3
- +
- define Device/xunlong_orangepi-zero-plus
- DEVICE_VENDOR := Xunlong
- DEVICE_MODEL := Orange Pi Zero Plus
- diff --git a/target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch b/target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch
- new file mode 100644
- index 0000000000000..0747e6a8e02ed
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch
- @@ -0,0 +1,305 @@
- +From 322bf103204b8f786547acbeed85569254e7088f Mon Sep 17 00:00:00 2001
- +From: Andre Przywara <[email protected]>
- +Date: Fri, 4 Aug 2023 18:08:54 +0100
- +Subject: [PATCH] arm64: dts: allwinner: h616: Split Orange Pi Zero 2 DT
- +
- +The Orange Pi Zero 2 got a successor (Zero 3), which shares quite some
- +DT nodes with the Zero 2, but comes with a different PMIC.
- +
- +Move the common parts (except the PMIC) into a new shared file, and
- +include that from the existing board .dts file.
- +
- +No functional change, the generated DTB is the same, except for some
- +phandle numbering differences.
- +
- +Signed-off-by: Andre Przywara <[email protected]>
- +Acked-by: Jernej Skrabec <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Jernej Skrabec <[email protected]>
- +---
- + .../allwinner/sun50i-h616-orangepi-zero.dtsi | 134 ++++++++++++++++++
- + .../allwinner/sun50i-h616-orangepi-zero2.dts | 119 +---------------
- + 2 files changed, 135 insertions(+), 118 deletions(-)
- + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
- +
- +--- /dev/null
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
- +@@ -0,0 +1,134 @@
- ++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
- ++/*
- ++ * Copyright (C) 2020 Arm Ltd.
- ++ *
- ++ * DT nodes common between Orange Pi Zero 2 and Orange Pi Zero 3.
- ++ * Excludes PMIC nodes and properties, since they are different between the two.
- ++ */
- ++
- ++#include "sun50i-h616.dtsi"
- ++
- ++#include <dt-bindings/gpio/gpio.h>
- ++#include <dt-bindings/interrupt-controller/arm-gic.h>
- ++#include <dt-bindings/leds/common.h>
- ++
- ++/ {
- ++ aliases {
- ++ ethernet0 = &emac0;
- ++ serial0 = &uart0;
- ++ };
- ++
- ++ chosen {
- ++ stdout-path = "serial0:115200n8";
- ++ };
- ++
- ++ leds {
- ++ compatible = "gpio-leds";
- ++
- ++ led-0 {
- ++ function = LED_FUNCTION_POWER;
- ++ color = <LED_COLOR_ID_RED>;
- ++ gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */
- ++ default-state = "on";
- ++ };
- ++
- ++ led-1 {
- ++ function = LED_FUNCTION_STATUS;
- ++ color = <LED_COLOR_ID_GREEN>;
- ++ gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */
- ++ };
- ++ };
- ++
- ++ reg_vcc5v: vcc5v {
- ++ /* board wide 5V supply directly from the USB-C socket */
- ++ compatible = "regulator-fixed";
- ++ regulator-name = "vcc-5v";
- ++ regulator-min-microvolt = <5000000>;
- ++ regulator-max-microvolt = <5000000>;
- ++ regulator-always-on;
- ++ };
- ++
- ++ reg_usb1_vbus: regulator-usb1-vbus {
- ++ compatible = "regulator-fixed";
- ++ regulator-name = "usb1-vbus";
- ++ regulator-min-microvolt = <5000000>;
- ++ regulator-max-microvolt = <5000000>;
- ++ vin-supply = <®_vcc5v>;
- ++ enable-active-high;
- ++ gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */
- ++ };
- ++};
- ++
- ++&ehci1 {
- ++ status = "okay";
- ++};
- ++
- ++/* USB 2 & 3 are on headers only. */
- ++
- ++&emac0 {
- ++ pinctrl-names = "default";
- ++ pinctrl-0 = <&ext_rgmii_pins>;
- ++ phy-mode = "rgmii";
- ++ phy-handle = <&ext_rgmii_phy>;
- ++ allwinner,rx-delay-ps = <3100>;
- ++ allwinner,tx-delay-ps = <700>;
- ++ status = "okay";
- ++};
- ++
- ++&mdio0 {
- ++ ext_rgmii_phy: ethernet-phy@1 {
- ++ compatible = "ethernet-phy-ieee802.3-c22";
- ++ reg = <1>;
- ++ };
- ++};
- ++
- ++&mmc0 {
- ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
- ++ bus-width = <4>;
- ++ status = "okay";
- ++};
- ++
- ++&ohci1 {
- ++ status = "okay";
- ++};
- ++
- ++&spi0 {
- ++ status = "okay";
- ++ pinctrl-names = "default";
- ++ pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>;
- ++
- ++ flash@0 {
- ++ #address-cells = <1>;
- ++ #size-cells = <1>;
- ++ compatible = "jedec,spi-nor";
- ++ reg = <0>;
- ++ spi-max-frequency = <40000000>;
- ++ };
- ++};
- ++
- ++&uart0 {
- ++ pinctrl-names = "default";
- ++ pinctrl-0 = <&uart0_ph_pins>;
- ++ status = "okay";
- ++};
- ++
- ++&usbotg {
- ++ /*
- ++ * PHY0 pins are connected to a USB-C socket, but a role switch
- ++ * is not implemented: both CC pins are pulled to GND.
- ++ * The VBUS pins power the device, so a fixed peripheral mode
- ++ * is the best choice.
- ++ * The board can be powered via GPIOs, in this case port0 *can*
- ++ * act as a host (with a cable/adapter ignoring CC), as VBUS is
- ++ * then provided by the GPIOs. Any user of this setup would
- ++ * need to adjust the DT accordingly: dr_mode set to "host",
- ++ * enabling OHCI0 and EHCI0.
- ++ */
- ++ dr_mode = "peripheral";
- ++ status = "okay";
- ++};
- ++
- ++&usbphy {
- ++ usb1_vbus-supply = <®_usb1_vbus>;
- ++ status = "okay";
- ++};
- +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
- +@@ -5,95 +5,19 @@
- +
- + /dts-v1/;
- +
- +-#include "sun50i-h616.dtsi"
- +-
- +-#include <dt-bindings/gpio/gpio.h>
- +-#include <dt-bindings/interrupt-controller/arm-gic.h>
- +-#include <dt-bindings/leds/common.h>
- ++#include "sun50i-h616-orangepi-zero.dtsi"
- +
- + / {
- + model = "OrangePi Zero2";
- + compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
- +-
- +- aliases {
- +- ethernet0 = &emac0;
- +- serial0 = &uart0;
- +- };
- +-
- +- chosen {
- +- stdout-path = "serial0:115200n8";
- +- };
- +-
- +- leds {
- +- compatible = "gpio-leds";
- +-
- +- led-0 {
- +- function = LED_FUNCTION_POWER;
- +- color = <LED_COLOR_ID_RED>;
- +- gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */
- +- default-state = "on";
- +- };
- +-
- +- led-1 {
- +- function = LED_FUNCTION_STATUS;
- +- color = <LED_COLOR_ID_GREEN>;
- +- gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */
- +- };
- +- };
- +-
- +- reg_vcc5v: vcc5v {
- +- /* board wide 5V supply directly from the USB-C socket */
- +- compatible = "regulator-fixed";
- +- regulator-name = "vcc-5v";
- +- regulator-min-microvolt = <5000000>;
- +- regulator-max-microvolt = <5000000>;
- +- regulator-always-on;
- +- };
- +-
- +- reg_usb1_vbus: regulator-usb1-vbus {
- +- compatible = "regulator-fixed";
- +- regulator-name = "usb1-vbus";
- +- regulator-min-microvolt = <5000000>;
- +- regulator-max-microvolt = <5000000>;
- +- vin-supply = <®_vcc5v>;
- +- enable-active-high;
- +- gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */
- +- };
- +-};
- +-
- +-&ehci1 {
- +- status = "okay";
- + };
- +
- +-/* USB 2 & 3 are on headers only. */
- +-
- + &emac0 {
- +- pinctrl-names = "default";
- +- pinctrl-0 = <&ext_rgmii_pins>;
- +- phy-mode = "rgmii";
- +- phy-handle = <&ext_rgmii_phy>;
- + phy-supply = <®_dcdce>;
- +- allwinner,rx-delay-ps = <3100>;
- +- allwinner,tx-delay-ps = <700>;
- +- status = "okay";
- +-};
- +-
- +-&mdio0 {
- +- ext_rgmii_phy: ethernet-phy@1 {
- +- compatible = "ethernet-phy-ieee802.3-c22";
- +- reg = <1>;
- +- };
- + };
- +
- + &mmc0 {
- + vmmc-supply = <®_dcdce>;
- +- cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
- +- bus-width = <4>;
- +- status = "okay";
- +-};
- +-
- +-&ohci1 {
- +- status = "okay";
- + };
- +
- + &r_rsb {
- +@@ -211,44 +135,3 @@
- + vcc-ph-supply = <®_aldo1>;
- + vcc-pi-supply = <®_aldo1>;
- + };
- +-
- +-&spi0 {
- +- status = "okay";
- +- pinctrl-names = "default";
- +- pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>;
- +-
- +- flash@0 {
- +- #address-cells = <1>;
- +- #size-cells = <1>;
- +- compatible = "jedec,spi-nor";
- +- reg = <0>;
- +- spi-max-frequency = <40000000>;
- +- };
- +-};
- +-
- +-&uart0 {
- +- pinctrl-names = "default";
- +- pinctrl-0 = <&uart0_ph_pins>;
- +- status = "okay";
- +-};
- +-
- +-&usbotg {
- +- /*
- +- * PHY0 pins are connected to a USB-C socket, but a role switch
- +- * is not implemented: both CC pins are pulled to GND.
- +- * The VBUS pins power the device, so a fixed peripheral mode
- +- * is the best choice.
- +- * The board can be powered via GPIOs, in this case port0 *can*
- +- * act as a host (with a cable/adapter ignoring CC), as VBUS is
- +- * then provided by the GPIOs. Any user of this setup would
- +- * need to adjust the DT accordingly: dr_mode set to "host",
- +- * enabling OHCI0 and EHCI0.
- +- */
- +- dr_mode = "peripheral";
- +- status = "okay";
- +-};
- +-
- +-&usbphy {
- +- usb1_vbus-supply = <®_usb1_vbus>;
- +- status = "okay";
- +-};
- diff --git a/target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch b/target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch
- new file mode 100644
- index 0000000000000..4081a82d52444
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch
- @@ -0,0 +1,140 @@
- +From f1b3ddb3ecc2eec1f912383e01156c226daacfab Mon Sep 17 00:00:00 2001
- +From: Andre Przywara <[email protected]>
- +Date: Fri, 4 Aug 2023 18:08:56 +0100
- +Subject: [PATCH] arm64: dts: allwinner: h616: Add OrangePi Zero 3 board
- + support
- +
- +The OrangePi Zero 3 is a development board based on the Allwinner H618 SoC,
- +which seems to be just an H616 with more L2 cache. The board itself is a
- +slightly updated version of the Orange Pi Zero 2. It features:
- +- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
- +- 1/1.5/2/4 GiB LPDDR4 DRAM SKUs (only up to 1GB on the Zero2)
- +- AXP313a PMIC (more capable AXP305 on the Zero2)
- +- Raspberry-Pi-1 compatible GPIO header
- +- extra 13 pin expansion header, exposing pins for 2x USB 2.0 ports
- +- 1 USB 2.0 host port
- +- 1 USB 2.0 type C port (power supply + OTG)
- +- MicroSD slot
- +- on-board 16MiB bootable SPI NOR flash (only 2MB on the Zero2)
- +- 1Gbps Ethernet port (via Motorcomm YT8531 PHY) (RTL8211 on the Zero2)
- +- micro-HDMI port
- +- (yet) unsupported Allwinner WiFi/BT chip
- +
- +Add the devicetree file describing the currently supported features,
- +namely LEDs, SD card, PMIC, SPI flash, USB. Ethernet seems unstable at
- +the moment, though the basic functionality works.
- +
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Jernej Skrabec <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Jernej Skrabec <[email protected]>
- +---
- + arch/arm64/boot/dts/allwinner/Makefile | 1 +
- + .../allwinner/sun50i-h618-orangepi-zero3.dts | 94 +++++++++++++++++++
- + 2 files changed, 95 insertions(+)
- + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
- +
- +--- a/arch/arm64/boot/dts/allwinner/Makefile
- ++++ b/arch/arm64/boot/dts/allwinner/Makefile
- +@@ -40,3 +40,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-ta
- + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6-mini.dtb
- + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
- + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
- ++dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
- +--- /dev/null
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
- +@@ -0,0 +1,94 @@
- ++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
- ++/*
- ++ * Copyright (C) 2023 Arm Ltd.
- ++ */
- ++
- ++/dts-v1/;
- ++
- ++#include "sun50i-h616-orangepi-zero.dtsi"
- ++
- ++/ {
- ++ model = "OrangePi Zero3";
- ++ compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618";
- ++};
- ++
- ++&emac0 {
- ++ phy-supply = <®_dldo1>;
- ++};
- ++
- ++&ext_rgmii_phy {
- ++ motorcomm,clk-out-frequency-hz = <125000000>;
- ++};
- ++
- ++&mmc0 {
- ++ /*
- ++ * The schematic shows the card detect pin wired up to PF6, via an
- ++ * inverter, but it just doesn't work.
- ++ */
- ++ broken-cd;
- ++ vmmc-supply = <®_dldo1>;
- ++};
- ++
- ++&r_i2c {
- ++ status = "okay";
- ++
- ++ axp313: pmic@36 {
- ++ compatible = "x-powers,axp313a";
- ++ reg = <0x36>;
- ++ #interrupt-cells = <1>;
- ++ interrupt-controller;
- ++ interrupt-parent = <&pio>;
- ++ interrupts = <2 9 IRQ_TYPE_LEVEL_LOW>; /* PC9 */
- ++
- ++ vin1-supply = <®_vcc5v>;
- ++ vin2-supply = <®_vcc5v>;
- ++ vin3-supply = <®_vcc5v>;
- ++
- ++ regulators {
- ++ /* Supplies VCC-PLL, so needs to be always on. */
- ++ reg_aldo1: aldo1 {
- ++ regulator-always-on;
- ++ regulator-min-microvolt = <1800000>;
- ++ regulator-max-microvolt = <1800000>;
- ++ regulator-name = "vcc1v8";
- ++ };
- ++
- ++ /* Supplies VCC-IO, so needs to be always on. */
- ++ reg_dldo1: dldo1 {
- ++ regulator-always-on;
- ++ regulator-min-microvolt = <3300000>;
- ++ regulator-max-microvolt = <3300000>;
- ++ regulator-name = "vcc3v3";
- ++ };
- ++
- ++ reg_dcdc1: dcdc1 {
- ++ regulator-always-on;
- ++ regulator-min-microvolt = <810000>;
- ++ regulator-max-microvolt = <990000>;
- ++ regulator-name = "vdd-gpu-sys";
- ++ };
- ++
- ++ reg_dcdc2: dcdc2 {
- ++ regulator-always-on;
- ++ regulator-min-microvolt = <810000>;
- ++ regulator-max-microvolt = <1100000>;
- ++ regulator-name = "vdd-cpu";
- ++ };
- ++
- ++ reg_dcdc3: dcdc3 {
- ++ regulator-always-on;
- ++ regulator-min-microvolt = <1100000>;
- ++ regulator-max-microvolt = <1100000>;
- ++ regulator-name = "vdd-dram";
- ++ };
- ++ };
- ++ };
- ++};
- ++
- ++&pio {
- ++ vcc-pc-supply = <®_dldo1>;
- ++ vcc-pf-supply = <®_dldo1>;
- ++ vcc-pg-supply = <®_aldo1>;
- ++ vcc-ph-supply = <®_dldo1>;
- ++ vcc-pi-supply = <®_dldo1>;
- ++};
- diff --git a/target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch b/target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch
- new file mode 100644
- index 0000000000000..a492eed551247
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch
- @@ -0,0 +1,57 @@
- +From b9622937d95809ef89904583191571a9fa326402 Mon Sep 17 00:00:00 2001
- +From: Chukun Pan <[email protected]>
- +Date: Sun, 29 Oct 2023 15:40:09 +0800
- +Subject: [PATCH] arm64: dts: allwinner: h616: update emac for Orange Pi Zero 3
- +
- +The current emac setting is not suitable for Orange Pi Zero 3,
- +move it back to Orange Pi Zero 2 DT. Also update phy mode and
- +delay values for emac on Orange Pi Zero 3.
- +With these changes, Ethernet now looks stable.
- +
- +Fixes: 322bf103204b ("arm64: dts: allwinner: h616: Split Orange Pi Zero 2 DT")
- +Signed-off-by: Chukun Pan <[email protected]>
- +Reviewed-by: Jernej Skrabec <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Jernej Skrabec <[email protected]>
- +---
- + arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi | 3 ---
- + arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts | 3 +++
- + arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts | 2 ++
- + 3 files changed, 5 insertions(+), 3 deletions(-)
- +
- +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
- +@@ -68,10 +68,7 @@
- + &emac0 {
- + pinctrl-names = "default";
- + pinctrl-0 = <&ext_rgmii_pins>;
- +- phy-mode = "rgmii";
- + phy-handle = <&ext_rgmii_phy>;
- +- allwinner,rx-delay-ps = <3100>;
- +- allwinner,tx-delay-ps = <700>;
- + status = "okay";
- + };
- +
- +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
- +@@ -13,6 +13,9 @@
- + };
- +
- + &emac0 {
- ++ allwinner,rx-delay-ps = <3100>;
- ++ allwinner,tx-delay-ps = <700>;
- ++ phy-mode = "rgmii";
- + phy-supply = <®_dcdce>;
- + };
- +
- +--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
- +@@ -13,6 +13,8 @@
- + };
- +
- + &emac0 {
- ++ allwinner,tx-delay-ps = <700>;
- ++ phy-mode = "rgmii-rxid";
- + phy-supply = <®_dldo1>;
- + };
- +
- From 601a80db2a3846adbc715e1ef3d3da1c156290a3 Mon Sep 17 00:00:00 2001
- From: Chukun Pan <[email protected]>
- Date: Wed, 6 Mar 2024 23:10:21 +0800
- Subject: [PATCH 4/4] sunxi: backport h616 thermal sensor support
- Backport H616 thermal sensor support from linux-next.
- Tested on the Orange Pi Zero 3 (H618 SoC).
- Signed-off-by: Chukun Pan <[email protected]>
- ---
- ...lwinner-h616-Add-SID-controller-node.patch | 31 ++++
- ...am-export-register-0-for-THS-on-H616.patch | 98 +++++++++++++
- ...-Add-D1-T113s-THS-controller-support.patch | 47 ++++++
- ...8i-Explain-unknown-H6-register-value.patch | 79 ++++++++++
- ...i-Extend-H6-calibration-to-support-4.patch | 74 ++++++++++
- ...-sun8i-Add-SRAM-register-access-code.patch | 126 ++++++++++++++++
- ...-Add-support-for-H616-THS-controller.patch | 50 +++++++
- ...Dont-fail-probe-due-to-zone-registra.patch | 68 +++++++++
- ...er-h616-Add-thermal-sensor-and-zones.patch | 138 ++++++++++++++++++
- 9 files changed, 711 insertions(+)
- create mode 100644 target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch
- create mode 100644 target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch
- create mode 100644 target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch
- create mode 100644 target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch
- create mode 100644 target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch
- create mode 100644 target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch
- create mode 100644 target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch
- create mode 100644 target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch
- create mode 100644 target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch
- diff --git a/target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch b/target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch
- new file mode 100644
- index 0000000000000..ce8add18ab434
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch
- @@ -0,0 +1,31 @@
- +From 951992797378a2177946400438f4d23c9fceae5b Mon Sep 17 00:00:00 2001
- +From: Martin Botka <[email protected]>
- +Date: Tue, 12 Sep 2023 14:25:13 +0200
- +Subject: [PATCH] arm64: dts: allwinner: h616: Add SID controller node
- +
- +Add node for the H616 SID controller
- +
- +Signed-off-by: Martin Botka <[email protected]>
- +Acked-by: Jernej Skrabec <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Jernej Skrabec <[email protected]>
- +---
- + arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 7 +++++++
- + 1 file changed, 7 insertions(+)
- +
- +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
- +@@ -133,6 +133,13 @@
- + #reset-cells = <1>;
- + };
- +
- ++ sid: efuse@3006000 {
- ++ compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid";
- ++ reg = <0x03006000 0x1000>;
- ++ #address-cells = <1>;
- ++ #size-cells = <1>;
- ++ };
- ++
- + watchdog: watchdog@30090a0 {
- + compatible = "allwinner,sun50i-h616-wdt",
- + "allwinner,sun6i-a31-wdt";
- diff --git a/target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch b/target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch
- new file mode 100644
- index 0000000000000..3453e2aa5330f
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch
- @@ -0,0 +1,98 @@
- +From 898d96c5464b69af44f6407c5de81ebc349d574b Mon Sep 17 00:00:00 2001
- +From: Andre Przywara <[email protected]>
- +Date: Mon, 19 Feb 2024 15:36:33 +0000
- +Subject: [PATCH] soc: sunxi: sram: export register 0 for THS on H616
- +
- +The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
- +in the SRAM control block. If bit 16 is set (the reset value), the
- +temperature readings of the THS are way off, leading to reports about
- +200C, at normal ambient temperatures. Clearing this bits brings the
- +reported values down to the expected values.
- +The BSP code clears this bit in firmware (U-Boot), and has an explicit
- +comment about this, but offers no real explanation.
- +
- +Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
- +visibility: all tested bit settings still allow full read and write
- +access by the CPU to the whole of SRAM C. Only bit 24 of the register at
- +offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
- +the THS switch functionality as an SRAM region would not reflect reality.
- +
- +Since we should not rely on firmware settings, allow other code (the THS
- +driver) to access this register, by exporting it through the already
- +existing regmap. This mimics what we already do for the LDO control and
- +the EMAC register.
- +
- +To avoid concurrent accesses to the same register at the same time, by
- +the SRAM switch code and the regmap code, use the same lock to protect
- +the access. The regmap subsystem allows to use an existing lock, so we
- +just need to hook in there.
- +
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Jernej Skrabec <[email protected]>
- +Signed-off-by: Daniel Lezcano <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/soc/sunxi/sunxi_sram.c | 22 ++++++++++++++++++++++
- + 1 file changed, 22 insertions(+)
- +
- +--- a/drivers/soc/sunxi/sunxi_sram.c
- ++++ b/drivers/soc/sunxi/sunxi_sram.c
- +@@ -284,6 +284,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
- + struct sunxi_sramc_variant {
- + int num_emac_clocks;
- + bool has_ldo_ctrl;
- ++ bool has_ths_offset;
- + };
- +
- + static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
- +@@ -305,8 +306,10 @@ static const struct sunxi_sramc_variant
- +
- + static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
- + .num_emac_clocks = 2,
- ++ .has_ths_offset = true,
- + };
- +
- ++#define SUNXI_SRAM_THS_OFFSET_REG 0x0
- + #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30
- + #define SUNXI_SYS_LDO_CTRL_REG 0x150
- +
- +@@ -315,6 +318,8 @@ static bool sunxi_sram_regmap_accessible
- + {
- + const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
- +
- ++ if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
- ++ return true;
- + if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
- + reg < SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
- + return true;
- +@@ -324,6 +329,20 @@ static bool sunxi_sram_regmap_accessible
- + return false;
- + }
- +
- ++static void sunxi_sram_lock(void *_lock)
- ++{
- ++ spinlock_t *lock = _lock;
- ++
- ++ spin_lock(lock);
- ++}
- ++
- ++static void sunxi_sram_unlock(void *_lock)
- ++{
- ++ spinlock_t *lock = _lock;
- ++
- ++ spin_unlock(lock);
- ++}
- ++
- + static struct regmap_config sunxi_sram_regmap_config = {
- + .reg_bits = 32,
- + .val_bits = 32,
- +@@ -333,6 +352,9 @@ static struct regmap_config sunxi_sram_r
- + /* other devices have no business accessing other registers */
- + .readable_reg = sunxi_sram_regmap_accessible_reg,
- + .writeable_reg = sunxi_sram_regmap_accessible_reg,
- ++ .lock = sunxi_sram_lock,
- ++ .unlock = sunxi_sram_unlock,
- ++ .lock_arg = &sram_lock,
- + };
- +
- + static int __init sunxi_sram_probe(struct platform_device *pdev)
- diff --git a/target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch b/target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch
- new file mode 100644
- index 0000000000000..8b199891184fe
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch
- @@ -0,0 +1,47 @@
- +From ebbf19e36d021f253425344b4d4b987f3b7d9be5 Mon Sep 17 00:00:00 2001
- +From: Maxim Kiselev <[email protected]>
- +Date: Mon, 18 Dec 2023 00:06:23 +0300
- +Subject: [PATCH] thermal/drivers/sun8i: Add D1/T113s THS controller support
- +
- +This patch adds a thermal sensor controller support for the D1/T113s,
- +which is similar to the one on H6, but with only one sensor and
- +different scale and offset values.
- +
- +Signed-off-by: Maxim Kiselev <[email protected]>
- +Acked-by: Jernej Skrabec <[email protected]>
- +Reviewed-by: Andre Przywara <[email protected]>
- +Signed-off-by: Daniel Lezcano <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/thermal/sun8i_thermal.c | 13 +++++++++++++
- + 1 file changed, 13 insertions(+)
- +
- +--- a/drivers/thermal/sun8i_thermal.c
- ++++ b/drivers/thermal/sun8i_thermal.c
- +@@ -610,6 +610,18 @@ static const struct ths_thermal_chip sun
- + .calc_temp = sun8i_ths_calc_temp,
- + };
- +
- ++static const struct ths_thermal_chip sun20i_d1_ths = {
- ++ .sensor_num = 1,
- ++ .has_bus_clk_reset = true,
- ++ .offset = 188552,
- ++ .scale = 673,
- ++ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
- ++ .calibrate = sun50i_h6_ths_calibrate,
- ++ .init = sun50i_h6_thermal_init,
- ++ .irq_ack = sun50i_h6_irq_ack,
- ++ .calc_temp = sun8i_ths_calc_temp,
- ++};
- ++
- + static const struct of_device_id of_ths_match[] = {
- + { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
- + { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
- +@@ -618,6 +630,7 @@ static const struct of_device_id of_ths_
- + { .compatible = "allwinner,sun50i-a100-ths", .data = &sun50i_a100_ths },
- + { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths },
- + { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
- ++ { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
- + { /* sentinel */ },
- + };
- + MODULE_DEVICE_TABLE(of, of_ths_match);
- diff --git a/target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch b/target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch
- new file mode 100644
- index 0000000000000..b8138a3870375
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch
- @@ -0,0 +1,79 @@
- +From 14f118aa50fe7c7c7330f56d007ecacca487cea8 Mon Sep 17 00:00:00 2001
- +From: Andre Przywara <[email protected]>
- +Date: Mon, 19 Feb 2024 15:36:35 +0000
- +Subject: [PATCH] thermal/drivers/sun8i: Explain unknown H6 register value
- +
- +So far we were ORing in some "unknown" value into the THS control
- +register on the Allwinner H6. This part of the register is not explained
- +in the H6 manual, but the H616 manual details those bits, and on closer
- +inspection the THS IP blocks in both SoCs seem very close:
- +- The BSP code for both SoCs writes the same values into THS_CTRL.
- +- The reset values of at least the first three registers are the same.
- +
- +Replace the "unknown" value with its proper meaning: "acquire time",
- +most probably the sample part of the sample & hold circuit of the ADC,
- +according to its explanation in the H616 manual.
- +
- +No functional change, just a macro rename and adjustment.
- +
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Jernej Skrabec <[email protected]>
- +Acked-by: Vasily Khoruzhick <[email protected]>
- +Signed-off-by: Daniel Lezcano <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/thermal/sun8i_thermal.c | 29 ++++++++++++++++-------------
- + 1 file changed, 16 insertions(+), 13 deletions(-)
- +
- +--- a/drivers/thermal/sun8i_thermal.c
- ++++ b/drivers/thermal/sun8i_thermal.c
- +@@ -50,7 +50,8 @@
- + #define SUN8I_THS_CTRL2_T_ACQ1(x) ((GENMASK(15, 0) & (x)) << 16)
- + #define SUN8I_THS_DATA_IRQ_STS(x) BIT(x + 8)
- +
- +-#define SUN50I_THS_CTRL0_T_ACQ(x) ((GENMASK(15, 0) & (x)) << 16)
- ++#define SUN50I_THS_CTRL0_T_ACQ(x) (GENMASK(15, 0) & ((x) - 1))
- ++#define SUN50I_THS_CTRL0_T_SAMPLE_PER(x) ((GENMASK(15, 0) & ((x) - 1)) << 16)
- + #define SUN50I_THS_FILTER_EN BIT(2)
- + #define SUN50I_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
- + #define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12)
- +@@ -410,25 +411,27 @@ static int sun8i_h3_thermal_init(struct
- + return 0;
- + }
- +
- +-/*
- +- * Without this undocumented value, the returned temperatures would
- +- * be higher than real ones by about 20C.
- +- */
- +-#define SUN50I_H6_CTRL0_UNK 0x0000002f
- +-
- + static int sun50i_h6_thermal_init(struct ths_device *tmdev)
- + {
- + int val;
- +
- + /*
- +- * T_acq = 20us
- +- * clkin = 24MHz
- +- *
- +- * x = T_acq * clkin - 1
- +- * = 479
- ++ * The manual recommends an overall sample frequency of 50 KHz (20us,
- ++ * 480 cycles at 24 MHz), which provides plenty of time for both the
- ++ * acquisition time (>24 cycles) and the actual conversion time
- ++ * (>14 cycles).
- ++ * The lower half of the CTRL register holds the "acquire time", in
- ++ * clock cycles, which the manual recommends to be 2us:
- ++ * 24MHz * 2us = 48 cycles.
- ++ * The high half of THS_CTRL encodes the sample frequency, in clock
- ++ * cycles: 24MHz * 20us = 480 cycles.
- ++ * This is explained in the H616 manual, but apparently wrongly
- ++ * described in the H6 manual, although the BSP code does the same
- ++ * for both SoCs.
- + */
- + regmap_write(tmdev->regmap, SUN50I_THS_CTRL0,
- +- SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479));
- ++ SUN50I_THS_CTRL0_T_ACQ(48) |
- ++ SUN50I_THS_CTRL0_T_SAMPLE_PER(480));
- + /* average over 4 samples */
- + regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC,
- + SUN50I_THS_FILTER_EN |
- diff --git a/target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch b/target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch
- new file mode 100644
- index 0000000000000..3d01a507fac39
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch
- @@ -0,0 +1,74 @@
- +From 6c04a419a4c5fb18edefc44dd676fb95c7f6c55d Mon Sep 17 00:00:00 2001
- +From: Maksim Kiselev <[email protected]>
- +Date: Mon, 19 Feb 2024 15:36:36 +0000
- +Subject: [PATCH] thermal/drivers/sun8i: Extend H6 calibration to support 4
- + sensors
- +
- +The H616 SoC resembles the H6 thermal sensor controller, with a few
- +changes like four sensors.
- +
- +Extend sun50i_h6_ths_calibrate() function to support calibration of
- +these sensors.
- +
- +Co-developed-by: Martin Botka <[email protected]>
- +Signed-off-by: Martin Botka <[email protected]>
- +Signed-off-by: Maksim Kiselev <[email protected]>
- +Reviewed-by: Andre Przywara <[email protected]>
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Jernej Skrabec <[email protected]>
- +Acked-by: Vasily Khoruzhick <[email protected]>
- +Signed-off-by: Daniel Lezcano <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/thermal/sun8i_thermal.c | 28 ++++++++++++++++++++--------
- + 1 file changed, 20 insertions(+), 8 deletions(-)
- +
- +--- a/drivers/thermal/sun8i_thermal.c
- ++++ b/drivers/thermal/sun8i_thermal.c
- +@@ -224,16 +224,21 @@ static int sun50i_h6_ths_calibrate(struc
- + struct device *dev = tmdev->dev;
- + int i, ft_temp;
- +
- +- if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num)
- ++ if (!caldata[0])
- + return -EINVAL;
- +
- + /*
- + * efuse layout:
- + *
- +- * 0 11 16 32
- +- * +-------+-------+-------+
- +- * |temp| |sensor0|sensor1|
- +- * +-------+-------+-------+
- ++ * 0 11 16 27 32 43 48 57
- ++ * +----------+-----------+-----------+-----------+
- ++ * | temp | |sensor0| |sensor1| |sensor2| |
- ++ * +----------+-----------+-----------+-----------+
- ++ * ^ ^ ^
- ++ * | | |
- ++ * | | sensor3[11:8]
- ++ * | sensor3[7:4]
- ++ * sensor3[3:0]
- + *
- + * The calibration data on the H6 is the ambient temperature and
- + * sensor values that are filled during the factory test stage.
- +@@ -246,9 +251,16 @@ static int sun50i_h6_ths_calibrate(struc
- + ft_temp = (caldata[0] & FT_TEMP_MASK) * 100;
- +
- + for (i = 0; i < tmdev->chip->sensor_num; i++) {
- +- int sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
- +- int cdata, offset;
- +- int sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
- ++ int sensor_reg, sensor_temp, cdata, offset;
- ++
- ++ if (i == 3)
- ++ sensor_reg = (caldata[1] >> 12)
- ++ | ((caldata[2] >> 12) << 4)
- ++ | ((caldata[3] >> 12) << 8);
- ++ else
- ++ sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
- ++
- ++ sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
- +
- + /*
- + * Calibration data is CALIBRATE_DEFAULT - (calculated
- diff --git a/target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch b/target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch
- new file mode 100644
- index 0000000000000..6db1e32cfb5a3
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch
- @@ -0,0 +1,126 @@
- +From f8b54d1120b81ed57bed96cc8e814ba08886d1e5 Mon Sep 17 00:00:00 2001
- +From: Andre Przywara <[email protected]>
- +Date: Mon, 19 Feb 2024 15:36:37 +0000
- +Subject: [PATCH] thermal/drivers/sun8i: Add SRAM register access code
- +
- +The Allwinner H616 SoC needs to clear a bit in one register in the SRAM
- +controller, to report reasonable temperature values. On reset, bit 16 in
- +register 0x3000000 is set, which leads to the driver reporting
- +temperatures around 200C. Clearing this bit brings the values down to the
- +expected range. The BSP code does a one-time write in U-Boot, with a
- +comment just mentioning the effect on the THS, but offering no further
- +explanation.
- +
- +To not rely on firmware to set things up for us, add code that queries
- +the SRAM controller device via a DT phandle link, then clear just this
- +single bit.
- +
- +Signed-off-by: Andre Przywara <[email protected]>
- +Acked-by: Vasily Khoruzhick <[email protected]>
- +Signed-off-by: Daniel Lezcano <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/thermal/sun8i_thermal.c | 51 +++++++++++++++++++++++++++++++++
- + 1 file changed, 51 insertions(+)
- +
- +--- a/drivers/thermal/sun8i_thermal.c
- ++++ b/drivers/thermal/sun8i_thermal.c
- +@@ -15,6 +15,7 @@
- + #include <linux/module.h>
- + #include <linux/nvmem-consumer.h>
- + #include <linux/of_device.h>
- ++#include <linux/of_platform.h>
- + #include <linux/platform_device.h>
- + #include <linux/regmap.h>
- + #include <linux/reset.h>
- +@@ -68,6 +69,7 @@ struct tsensor {
- + struct ths_thermal_chip {
- + bool has_mod_clk;
- + bool has_bus_clk_reset;
- ++ bool needs_sram;
- + int sensor_num;
- + int offset;
- + int scale;
- +@@ -85,12 +87,16 @@ struct ths_device {
- + const struct ths_thermal_chip *chip;
- + struct device *dev;
- + struct regmap *regmap;
- ++ struct regmap_field *sram_regmap_field;
- + struct reset_control *reset;
- + struct clk *bus_clk;
- + struct clk *mod_clk;
- + struct tsensor sensor[MAX_SENSOR_NUM];
- + };
- +
- ++/* The H616 needs to have a bit 16 in the SRAM control register cleared. */
- ++static const struct reg_field sun8i_ths_sram_reg_field = REG_FIELD(0x0, 16, 16);
- ++
- + /* Temp Unit: millidegree Celsius */
- + static int sun8i_ths_calc_temp(struct ths_device *tmdev,
- + int id, int reg)
- +@@ -337,6 +343,34 @@ static void sun8i_ths_reset_control_asse
- + reset_control_assert(data);
- + }
- +
- ++static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
- ++{
- ++ struct device_node *sram_node;
- ++ struct platform_device *sram_pdev;
- ++ struct regmap *regmap = NULL;
- ++
- ++ sram_node = of_parse_phandle(node, "allwinner,sram", 0);
- ++ if (!sram_node)
- ++ return ERR_PTR(-ENODEV);
- ++
- ++ sram_pdev = of_find_device_by_node(sram_node);
- ++ if (!sram_pdev) {
- ++ /* platform device might not be probed yet */
- ++ regmap = ERR_PTR(-EPROBE_DEFER);
- ++ goto out_put_node;
- ++ }
- ++
- ++ /* If no regmap is found then the other device driver is at fault */
- ++ regmap = dev_get_regmap(&sram_pdev->dev, NULL);
- ++ if (!regmap)
- ++ regmap = ERR_PTR(-EINVAL);
- ++
- ++ platform_device_put(sram_pdev);
- ++out_put_node:
- ++ of_node_put(sram_node);
- ++ return regmap;
- ++}
- ++
- + static int sun8i_ths_resource_init(struct ths_device *tmdev)
- + {
- + struct device *dev = tmdev->dev;
- +@@ -381,6 +415,19 @@ static int sun8i_ths_resource_init(struc
- + if (ret)
- + return ret;
- +
- ++ if (tmdev->chip->needs_sram) {
- ++ struct regmap *regmap;
- ++
- ++ regmap = sun8i_ths_get_sram_regmap(dev->of_node);
- ++ if (IS_ERR(regmap))
- ++ return PTR_ERR(regmap);
- ++ tmdev->sram_regmap_field = devm_regmap_field_alloc(dev,
- ++ regmap,
- ++ sun8i_ths_sram_reg_field);
- ++ if (IS_ERR(tmdev->sram_regmap_field))
- ++ return PTR_ERR(tmdev->sram_regmap_field);
- ++ }
- ++
- + ret = sun8i_ths_calibrate(tmdev);
- + if (ret)
- + return ret;
- +@@ -427,6 +474,10 @@ static int sun50i_h6_thermal_init(struct
- + {
- + int val;
- +
- ++ /* The H616 needs to have a bit in the SRAM control register cleared. */
- ++ if (tmdev->sram_regmap_field)
- ++ regmap_field_write(tmdev->sram_regmap_field, 0);
- ++
- + /*
- + * The manual recommends an overall sample frequency of 50 KHz (20us,
- + * 480 cycles at 24 MHz), which provides plenty of time for both the
- diff --git a/target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch b/target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch
- new file mode 100644
- index 0000000000000..e743d344c6e97
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch
- @@ -0,0 +1,50 @@
- +From e7dbfa19572a1440a2e67ef70f94ff204849a0a8 Mon Sep 17 00:00:00 2001
- +From: Martin Botka <[email protected]>
- +Date: Mon, 19 Feb 2024 15:36:38 +0000
- +Subject: [PATCH] thermal/drivers/sun8i: Add support for H616 THS controller
- +
- +Add support for the thermal sensor found in H616 SoCs, is the same as
- +the H6 thermal sensor controller, but with four sensors.
- +Also the registers readings are wrong, unless a bit in the first SYS_CFG
- +register cleared, so set exercise the SRAM regmap to take care of that.
- +
- +Signed-off-by: Martin Botka <[email protected]>
- +Signed-off-by: Andre Przywara <[email protected]>
- +Acked-by: Vasily Khoruzhick <[email protected]>
- +Signed-off-by: Daniel Lezcano <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/thermal/sun8i_thermal.c | 15 +++++++++++++++
- + 1 file changed, 15 insertions(+)
- +
- +--- a/drivers/thermal/sun8i_thermal.c
- ++++ b/drivers/thermal/sun8i_thermal.c
- +@@ -688,6 +688,20 @@ static const struct ths_thermal_chip sun
- + .calc_temp = sun8i_ths_calc_temp,
- + };
- +
- ++static const struct ths_thermal_chip sun50i_h616_ths = {
- ++ .sensor_num = 4,
- ++ .has_bus_clk_reset = true,
- ++ .needs_sram = true,
- ++ .ft_deviation = 8000,
- ++ .offset = 263655,
- ++ .scale = 810,
- ++ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
- ++ .calibrate = sun50i_h6_ths_calibrate,
- ++ .init = sun50i_h6_thermal_init,
- ++ .irq_ack = sun50i_h6_irq_ack,
- ++ .calc_temp = sun8i_ths_calc_temp,
- ++};
- ++
- + static const struct of_device_id of_ths_match[] = {
- + { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
- + { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
- +@@ -697,6 +711,7 @@ static const struct of_device_id of_ths_
- + { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths },
- + { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
- + { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
- ++ { .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths },
- + { /* sentinel */ },
- + };
- + MODULE_DEVICE_TABLE(of, of_ths_match);
- diff --git a/target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch b/target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch
- new file mode 100644
- index 0000000000000..384bf55084f30
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch
- @@ -0,0 +1,68 @@
- +From 9ac53d5532cc4bb595bbee86ccba2172ccc336c3 Mon Sep 17 00:00:00 2001
- +From: Mark Brown <[email protected]>
- +Date: Tue, 23 Jan 2024 23:33:07 +0000
- +Subject: [PATCH] thermal/drivers/sun8i: Don't fail probe due to zone
- + registration failure
- +
- +Currently the sun8i thermal driver will fail to probe if any of the
- +thermal zones it is registering fails to register with the thermal core.
- +Since we currently do not define any trip points for the GPU thermal
- +zones on at least A64 or H5 this means that we have no thermal support
- +on these platforms:
- +
- +[ 1.698703] thermal_sys: Failed to find 'trips' node
- +[ 1.698707] thermal_sys: Failed to find trip points for thermal-sensor id=1
- +
- +even though the main CPU thermal zone on both SoCs is fully configured.
- +This does not seem ideal, while we may not be able to use all the zones
- +it seems better to have those zones which are usable be operational.
- +Instead just carry on registering zones if we get any non-deferral
- +error, allowing use of those zones which are usable.
- +
- +This means that we also need to update the interrupt handler to not
- +attempt to notify the core for events on zones which we have not
- +registered, I didn't see an ability to mask individual interrupts and
- +I would expect that interrupts would still be indicated in the ISR even
- +if they were masked.
- +
- +Reviewed-by: Vasily Khoruzhick <[email protected]>
- +Acked-by: Jernej Skrabec <[email protected]>
- +Signed-off-by: Mark Brown <[email protected]>
- +Signed-off-by: Daniel Lezcano <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +---
- + drivers/thermal/sun8i_thermal.c | 16 ++++++++++++++--
- + 1 file changed, 14 insertions(+), 2 deletions(-)
- +
- +--- a/drivers/thermal/sun8i_thermal.c
- ++++ b/drivers/thermal/sun8i_thermal.c
- +@@ -197,6 +197,9 @@ static irqreturn_t sun8i_irq_thread(int
- + int i;
- +
- + for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) {
- ++ /* We allow some zones to not register. */
- ++ if (IS_ERR(tmdev->sensor[i].tzd))
- ++ continue;
- + thermal_zone_device_update(tmdev->sensor[i].tzd,
- + THERMAL_EVENT_UNSPECIFIED);
- + }
- +@@ -531,8 +534,17 @@ static int sun8i_ths_register(struct ths
- + i,
- + &tmdev->sensor[i],
- + &ths_ops);
- +- if (IS_ERR(tmdev->sensor[i].tzd))
- +- return PTR_ERR(tmdev->sensor[i].tzd);
- ++
- ++ /*
- ++ * If an individual zone fails to register for reasons
- ++ * other than probe deferral (eg, a bad DT) then carry
- ++ * on, other zones might register successfully.
- ++ */
- ++ if (IS_ERR(tmdev->sensor[i].tzd)) {
- ++ if (PTR_ERR(tmdev->sensor[i].tzd) == -EPROBE_DEFER)
- ++ return PTR_ERR(tmdev->sensor[i].tzd);
- ++ continue;
- ++ }
- +
- + if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd))
- + dev_warn(tmdev->dev,
- diff --git a/target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch b/target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch
- new file mode 100644
- index 0000000000000..cd6542bf14419
- --- /dev/null
- +++ b/target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch
- @@ -0,0 +1,138 @@
- +From f4318af40544b8e7ff5a6b667ede60e6cf808262 Mon Sep 17 00:00:00 2001
- +From: Martin Botka <[email protected]>
- +Date: Mon, 19 Feb 2024 15:36:39 +0000
- +Subject: [PATCH] arm64: dts: allwinner: h616: Add thermal sensor and zones
- +
- +There are four thermal sensors:
- +- CPU
- +- GPU
- +- VE
- +- DRAM
- +
- +Add the thermal sensor configuration and the thermal zones.
- +
- +Signed-off-by: Martin Botka <[email protected]>
- +Signed-off-by: Andre Przywara <[email protected]>
- +Reviewed-by: Jernej Skrabec <[email protected]>
- +Link: https://lore.kernel.org/r/[email protected]
- +Signed-off-by: Jernej Skrabec <[email protected]>
- +---
- + .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++
- + 1 file changed, 88 insertions(+)
- +
- +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
- ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
- +@@ -9,6 +9,7 @@
- + #include <dt-bindings/clock/sun6i-rtc.h>
- + #include <dt-bindings/reset/sun50i-h616-ccu.h>
- + #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
- ++#include <dt-bindings/thermal/thermal.h>
- +
- + / {
- + interrupt-parent = <&gic>;
- +@@ -138,6 +139,10 @@
- + reg = <0x03006000 0x1000>;
- + #address-cells = <1>;
- + #size-cells = <1>;
- ++
- ++ ths_calibration: thermal-sensor-calibration@14 {
- ++ reg = <0x14 0x8>;
- ++ };
- + };
- +
- + watchdog: watchdog@30090a0 {
- +@@ -511,6 +516,19 @@
- + };
- + };
- +
- ++ ths: thermal-sensor@5070400 {
- ++ compatible = "allwinner,sun50i-h616-ths";
- ++ reg = <0x05070400 0x400>;
- ++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
- ++ clocks = <&ccu CLK_BUS_THS>;
- ++ clock-names = "bus";
- ++ resets = <&ccu RST_BUS_THS>;
- ++ nvmem-cells = <&ths_calibration>;
- ++ nvmem-cell-names = "calibration";
- ++ allwinner,sram = <&syscon>;
- ++ #thermal-sensor-cells = <1>;
- ++ };
- ++
- + usbotg: usb@5100000 {
- + compatible = "allwinner,sun50i-h616-musb",
- + "allwinner,sun8i-h3-musb";
- +@@ -755,4 +773,74 @@
- + #size-cells = <0>;
- + };
- + };
- ++
- ++ thermal-zones {
- ++ cpu-thermal {
- ++ polling-delay-passive = <500>;
- ++ polling-delay = <1000>;
- ++ thermal-sensors = <&ths 2>;
- ++ sustainable-power = <1000>;
- ++
- ++ trips {
- ++ cpu_threshold: cpu-trip-0 {
- ++ temperature = <60000>;
- ++ type = "passive";
- ++ hysteresis = <0>;
- ++ };
- ++ cpu_target: cpu-trip-1 {
- ++ temperature = <70000>;
- ++ type = "passive";
- ++ hysteresis = <0>;
- ++ };
- ++ cpu_critical: cpu-trip-2 {
- ++ temperature = <110000>;
- ++ type = "critical";
- ++ hysteresis = <0>;
- ++ };
- ++ };
- ++ };
- ++
- ++ gpu-thermal {
- ++ polling-delay-passive = <500>;
- ++ polling-delay = <1000>;
- ++ thermal-sensors = <&ths 0>;
- ++ sustainable-power = <1100>;
- ++
- ++ trips {
- ++ gpu_temp_critical: gpu-trip-0 {
- ++ temperature = <110000>;
- ++ type = "critical";
- ++ hysteresis = <0>;
- ++ };
- ++ };
- ++ };
- ++
- ++ ve-thermal {
- ++ polling-delay-passive = <0>;
- ++ polling-delay = <0>;
- ++ thermal-sensors = <&ths 1>;
- ++
- ++ trips {
- ++ ve_temp_critical: ve-trip-0 {
- ++ temperature = <110000>;
- ++ type = "critical";
- ++ hysteresis = <0>;
- ++ };
- ++ };
- ++ };
- ++
- ++ ddr-thermal {
- ++ polling-delay-passive = <0>;
- ++ polling-delay = <0>;
- ++ thermal-sensors = <&ths 3>;
- ++
- ++ trips {
- ++ ddr_temp_critical: ddr-trip-0 {
- ++ temperature = <110000>;
- ++ type = "critical";
- ++ hysteresis = <0>;
- ++ };
- ++ };
- ++ };
- ++ };
- + };
|