uniwill-acpi.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Linux driver for Uniwill notebooks.
  4. *
  5. * Special thanks go to Pőcze Barnabás, Christoffer Sandberg and Werner Sembach
  6. * for supporting the development of this driver either through prior work or
  7. * by answering questions regarding the underlying ACPI and WMI interfaces.
  8. *
  9. * Copyright (C) 2025 Armin Wolf <W_Armin@gmx.de>
  10. */
  11. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12. #include <linux/acpi.h>
  13. #include <linux/array_size.h>
  14. #include <linux/bits.h>
  15. #include <linux/bitfield.h>
  16. #include <linux/cleanup.h>
  17. #include <linux/debugfs.h>
  18. #include <linux/delay.h>
  19. #include <linux/device.h>
  20. #include <linux/device/driver.h>
  21. #include <linux/dmi.h>
  22. #include <linux/errno.h>
  23. #include <linux/fixp-arith.h>
  24. #include <linux/hwmon.h>
  25. #include <linux/hwmon-sysfs.h>
  26. #include <linux/init.h>
  27. #include <linux/input.h>
  28. #include <linux/input/sparse-keymap.h>
  29. #include <linux/kernel.h>
  30. #include <linux/kstrtox.h>
  31. #include <linux/leds.h>
  32. #include <linux/led-class-multicolor.h>
  33. #include <linux/limits.h>
  34. #include <linux/list.h>
  35. #include <linux/minmax.h>
  36. #include <linux/module.h>
  37. #include <linux/mutex.h>
  38. #include <linux/notifier.h>
  39. #include <linux/platform_device.h>
  40. #include <linux/pm.h>
  41. #include <linux/printk.h>
  42. #include <linux/regmap.h>
  43. #include <linux/string.h>
  44. #include <linux/sysfs.h>
  45. #include <linux/types.h>
  46. #include <linux/units.h>
  47. #include <acpi/battery.h>
  48. #include "uniwill-wmi.h"
  49. #define EC_ADDR_BAT_POWER_UNIT_1 0x0400
  50. #define EC_ADDR_BAT_POWER_UNIT_2 0x0401
  51. #define EC_ADDR_BAT_DESIGN_CAPACITY_1 0x0402
  52. #define EC_ADDR_BAT_DESIGN_CAPACITY_2 0x0403
  53. #define EC_ADDR_BAT_FULL_CAPACITY_1 0x0404
  54. #define EC_ADDR_BAT_FULL_CAPACITY_2 0x0405
  55. #define EC_ADDR_BAT_DESIGN_VOLTAGE_1 0x0408
  56. #define EC_ADDR_BAT_DESIGN_VOLTAGE_2 0x0409
  57. #define EC_ADDR_BAT_STATUS_1 0x0432
  58. #define BAT_DISCHARGING BIT(0)
  59. #define EC_ADDR_BAT_STATUS_2 0x0433
  60. #define EC_ADDR_BAT_CURRENT_1 0x0434
  61. #define EC_ADDR_BAT_CURRENT_2 0x0435
  62. #define EC_ADDR_BAT_REMAIN_CAPACITY_1 0x0436
  63. #define EC_ADDR_BAT_REMAIN_CAPACITY_2 0x0437
  64. #define EC_ADDR_BAT_VOLTAGE_1 0x0438
  65. #define EC_ADDR_BAT_VOLTAGE_2 0x0439
  66. #define EC_ADDR_CPU_TEMP 0x043E
  67. #define EC_ADDR_GPU_TEMP 0x044F
  68. #define EC_ADDR_SYSTEM_ID 0x0456
  69. #define HAS_GPU BIT(7)
  70. #define EC_ADDR_MAIN_FAN_RPM_1 0x0464
  71. #define EC_ADDR_MAIN_FAN_RPM_2 0x0465
  72. #define EC_ADDR_SECOND_FAN_RPM_1 0x046C
  73. #define EC_ADDR_SECOND_FAN_RPM_2 0x046D
  74. #define EC_ADDR_DEVICE_STATUS 0x047B
  75. #define WIFI_STATUS_ON BIT(7)
  76. /* BIT(5) is also unset depending on the rfkill state (bluetooth?) */
  77. #define EC_ADDR_BAT_ALERT 0x0494
  78. #define EC_ADDR_BAT_CYCLE_COUNT_1 0x04A6
  79. #define EC_ADDR_BAT_CYCLE_COUNT_2 0x04A7
  80. #define EC_ADDR_PROJECT_ID 0x0740
  81. #define EC_ADDR_AP_OEM 0x0741
  82. #define ENABLE_MANUAL_CTRL BIT(0)
  83. #define ITE_KBD_EFFECT_REACTIVE BIT(3)
  84. #define FAN_ABNORMAL BIT(5)
  85. #define EC_ADDR_SUPPORT_5 0x0742
  86. #define FAN_TURBO_SUPPORTED BIT(4)
  87. #define FAN_SUPPORT BIT(5)
  88. #define EC_ADDR_CTGP_DB_CTRL 0x0743
  89. #define CTGP_DB_GENERAL_ENABLE BIT(0)
  90. #define CTGP_DB_DB_ENABLE BIT(1)
  91. #define CTGP_DB_CTGP_ENABLE BIT(2)
  92. #define EC_ADDR_CTGP_DB_CTGP_OFFSET 0x0744
  93. #define EC_ADDR_CTGP_DB_TPP_OFFSET 0x0745
  94. #define EC_ADDR_CTGP_DB_DB_OFFSET 0x0746
  95. #define EC_ADDR_LIGHTBAR_AC_CTRL 0x0748
  96. #define LIGHTBAR_APP_EXISTS BIT(0)
  97. #define LIGHTBAR_POWER_SAVE BIT(1)
  98. #define LIGHTBAR_S0_OFF BIT(2)
  99. #define LIGHTBAR_S3_OFF BIT(3) // Breathing animation when suspended
  100. #define LIGHTBAR_WELCOME BIT(7) // Rainbow animation
  101. #define EC_ADDR_LIGHTBAR_AC_RED 0x0749
  102. #define EC_ADDR_LIGHTBAR_AC_GREEN 0x074A
  103. #define EC_ADDR_LIGHTBAR_AC_BLUE 0x074B
  104. #define EC_ADDR_BIOS_OEM 0x074E
  105. #define FN_LOCK_STATUS BIT(4)
  106. #define EC_ADDR_MANUAL_FAN_CTRL 0x0751
  107. #define FAN_LEVEL_MASK GENMASK(2, 0)
  108. #define FAN_MODE_TURBO BIT(4)
  109. #define FAN_MODE_HIGH BIT(5)
  110. #define FAN_MODE_BOOST BIT(6)
  111. #define FAN_MODE_USER BIT(7)
  112. #define EC_ADDR_PWM_1 0x075B
  113. #define EC_ADDR_PWM_2 0x075C
  114. /* Unreliable */
  115. #define EC_ADDR_SUPPORT_1 0x0765
  116. #define AIRPLANE_MODE BIT(0)
  117. #define GPS_SWITCH BIT(1)
  118. #define OVERCLOCK BIT(2)
  119. #define MACRO_KEY BIT(3)
  120. #define SHORTCUT_KEY BIT(4)
  121. #define SUPER_KEY_LOCK BIT(5)
  122. #define LIGHTBAR BIT(6)
  123. #define FAN_BOOST BIT(7)
  124. #define EC_ADDR_SUPPORT_2 0x0766
  125. #define SILENT_MODE BIT(0)
  126. #define USB_CHARGING BIT(1)
  127. #define RGB_KEYBOARD BIT(2)
  128. #define CHINA_MODE BIT(5)
  129. #define MY_BATTERY BIT(6)
  130. #define EC_ADDR_TRIGGER 0x0767
  131. #define TRIGGER_SUPER_KEY_LOCK BIT(0)
  132. #define TRIGGER_LIGHTBAR BIT(1)
  133. #define TRIGGER_FAN_BOOST BIT(2)
  134. #define TRIGGER_SILENT_MODE BIT(3)
  135. #define TRIGGER_USB_CHARGING BIT(4)
  136. #define RGB_APPLY_COLOR BIT(5)
  137. #define RGB_LOGO_EFFECT BIT(6)
  138. #define RGB_RAINBOW_EFFECT BIT(7)
  139. #define EC_ADDR_SWITCH_STATUS 0x0768
  140. #define SUPER_KEY_LOCK_STATUS BIT(0)
  141. #define LIGHTBAR_STATUS BIT(1)
  142. #define FAN_BOOST_STATUS BIT(2)
  143. #define MACRO_KEY_STATUS BIT(3)
  144. #define MY_BAT_POWER_BAT_STATUS BIT(4)
  145. #define EC_ADDR_RGB_RED 0x0769
  146. #define EC_ADDR_RGB_GREEN 0x076A
  147. #define EC_ADDR_RGB_BLUE 0x076B
  148. #define EC_ADDR_ROMID_START 0x0770
  149. #define ROMID_LENGTH 14
  150. #define EC_ADDR_ROMID_EXTRA_1 0x077E
  151. #define EC_ADDR_ROMID_EXTRA_2 0x077F
  152. #define EC_ADDR_BIOS_OEM_2 0x0782
  153. #define FAN_V2_NEW BIT(0)
  154. #define FAN_QKEY BIT(1)
  155. #define FAN_TABLE_OFFICE_MODE BIT(2)
  156. #define FAN_V3 BIT(3)
  157. #define DEFAULT_MODE BIT(4)
  158. #define EC_ADDR_PL1_SETTING 0x0783
  159. #define EC_ADDR_PL2_SETTING 0x0784
  160. #define EC_ADDR_PL4_SETTING 0x0785
  161. #define EC_ADDR_FAN_DEFAULT 0x0786
  162. #define FAN_CURVE_LENGTH 5
  163. #define EC_ADDR_KBD_STATUS 0x078C
  164. #define KBD_WHITE_ONLY BIT(0) // ~single color
  165. #define KBD_SINGLE_COLOR_OFF BIT(1)
  166. #define KBD_TURBO_LEVEL_MASK GENMASK(3, 2)
  167. #define KBD_APPLY BIT(4)
  168. #define KBD_BRIGHTNESS GENMASK(7, 5)
  169. #define EC_ADDR_FAN_CTRL 0x078E
  170. #define FAN3P5 BIT(1)
  171. #define CHARGING_PROFILE BIT(3)
  172. #define UNIVERSAL_FAN_CTRL BIT(6)
  173. #define EC_ADDR_BIOS_OEM_3 0x07A3
  174. #define FAN_REDUCED_DURY_CYCLE BIT(5)
  175. #define FAN_ALWAYS_ON BIT(6)
  176. #define EC_ADDR_BIOS_BYTE 0x07A4
  177. #define FN_LOCK_SWITCH BIT(3)
  178. #define EC_ADDR_OEM_3 0x07A5
  179. #define POWER_LED_MASK GENMASK(1, 0)
  180. #define POWER_LED_LEFT 0x00
  181. #define POWER_LED_BOTH 0x01
  182. #define POWER_LED_NONE 0x02
  183. #define FAN_QUIET BIT(2)
  184. #define OVERBOOST BIT(4)
  185. #define HIGH_POWER BIT(7)
  186. #define EC_ADDR_OEM_4 0x07A6
  187. #define OVERBOOST_DYN_TEMP_OFF BIT(1)
  188. #define TOUCHPAD_TOGGLE_OFF BIT(6)
  189. #define EC_ADDR_CHARGE_CTRL 0x07B9
  190. #define CHARGE_CTRL_MASK GENMASK(6, 0)
  191. #define CHARGE_CTRL_REACHED BIT(7)
  192. #define EC_ADDR_UNIVERSAL_FAN_CTRL 0x07C5
  193. #define SPLIT_TABLES BIT(7)
  194. #define EC_ADDR_AP_OEM_6 0x07C6
  195. #define ENABLE_UNIVERSAL_FAN_CTRL BIT(2)
  196. #define BATTERY_CHARGE_FULL_OVER_24H BIT(3)
  197. #define BATTERY_ERM_STATUS_REACHED BIT(4)
  198. #define EC_ADDR_CHARGE_PRIO 0x07CC
  199. #define CHARGING_PERFORMANCE BIT(7)
  200. /* Same bits as EC_ADDR_LIGHTBAR_AC_CTRL except LIGHTBAR_S3_OFF */
  201. #define EC_ADDR_LIGHTBAR_BAT_CTRL 0x07E2
  202. #define EC_ADDR_LIGHTBAR_BAT_RED 0x07E3
  203. #define EC_ADDR_LIGHTBAR_BAT_GREEN 0x07E4
  204. #define EC_ADDR_LIGHTBAR_BAT_BLUE 0x07E5
  205. #define EC_ADDR_CPU_TEMP_END_TABLE 0x0F00
  206. #define EC_ADDR_CPU_TEMP_START_TABLE 0x0F10
  207. #define EC_ADDR_CPU_FAN_SPEED_TABLE 0x0F20
  208. #define EC_ADDR_GPU_TEMP_END_TABLE 0x0F30
  209. #define EC_ADDR_GPU_TEMP_START_TABLE 0x0F40
  210. #define EC_ADDR_GPU_FAN_SPEED_TABLE 0x0F50
  211. /*
  212. * Those two registers technically allow for manual fan control,
  213. * but are unstable on some models and are likely not meant to
  214. * be used by applications as they are only accessible when using
  215. * the WMI interface.
  216. */
  217. #define EC_ADDR_PWM_1_WRITEABLE 0x1804
  218. #define EC_ADDR_PWM_2_WRITEABLE 0x1809
  219. #define DRIVER_NAME "uniwill"
  220. /*
  221. * The OEM software always sleeps up to 6 ms after reading/writing EC
  222. * registers, so we emulate this behaviour for maximum compatibility.
  223. */
  224. #define UNIWILL_EC_DELAY_US 6000
  225. #define PWM_MAX 200
  226. #define FAN_TABLE_LENGTH 16
  227. #define LED_CHANNELS 3
  228. #define LED_MAX_BRIGHTNESS 200
  229. #define UNIWILL_FEATURE_FN_LOCK BIT(0)
  230. #define UNIWILL_FEATURE_SUPER_KEY BIT(1)
  231. #define UNIWILL_FEATURE_TOUCHPAD_TOGGLE BIT(2)
  232. #define UNIWILL_FEATURE_LIGHTBAR BIT(3)
  233. #define UNIWILL_FEATURE_BATTERY BIT(4)
  234. #define UNIWILL_FEATURE_HWMON BIT(5)
  235. #define UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL BIT(6)
  236. struct uniwill_data {
  237. struct device *dev;
  238. acpi_handle handle;
  239. struct regmap *regmap;
  240. unsigned int features;
  241. struct acpi_battery_hook hook;
  242. unsigned int last_charge_ctrl;
  243. struct mutex battery_lock; /* Protects the list of currently registered batteries */
  244. unsigned int last_status;
  245. unsigned int last_switch_status;
  246. struct mutex super_key_lock; /* Protects the toggling of the super key lock state */
  247. struct list_head batteries;
  248. struct mutex led_lock; /* Protects writes to the lightbar registers */
  249. struct led_classdev_mc led_mc_cdev;
  250. struct mc_subled led_mc_subled_info[LED_CHANNELS];
  251. struct mutex input_lock; /* Protects input sequence during notify */
  252. struct input_dev *input_device;
  253. struct notifier_block nb;
  254. };
  255. struct uniwill_battery_entry {
  256. struct list_head head;
  257. struct power_supply *battery;
  258. };
  259. struct uniwill_device_descriptor {
  260. unsigned int features;
  261. /* Executed during driver probing */
  262. int (*probe)(struct uniwill_data *data);
  263. };
  264. static bool force;
  265. module_param_unsafe(force, bool, 0);
  266. MODULE_PARM_DESC(force, "Force loading without checking for supported devices\n");
  267. /*
  268. * Contains device specific data like the feature bitmap since
  269. * the associated registers are not always reliable.
  270. */
  271. static struct uniwill_device_descriptor device_descriptor __ro_after_init;
  272. static const char * const uniwill_temp_labels[] = {
  273. "CPU",
  274. "GPU",
  275. };
  276. static const char * const uniwill_fan_labels[] = {
  277. "Main",
  278. "Secondary",
  279. };
  280. static const struct key_entry uniwill_keymap[] = {
  281. /* Reported via keyboard controller */
  282. { KE_IGNORE, UNIWILL_OSD_CAPSLOCK, { KEY_CAPSLOCK }},
  283. { KE_IGNORE, UNIWILL_OSD_NUMLOCK, { KEY_NUMLOCK }},
  284. /*
  285. * Reported when the user enables/disables the super key.
  286. * Those events might even be reported when the change was done
  287. * using the sysfs attribute!
  288. */
  289. { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_DISABLE, { KEY_UNKNOWN }},
  290. { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_ENABLE, { KEY_UNKNOWN }},
  291. /* Optional, might not be reported by all devices */
  292. { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_STATE_CHANGED, { KEY_UNKNOWN }},
  293. /* Reported in manual mode when toggling the airplane mode status */
  294. { KE_KEY, UNIWILL_OSD_RFKILL, { KEY_RFKILL }},
  295. { KE_IGNORE, UNIWILL_OSD_RADIOON, { KEY_UNKNOWN }},
  296. { KE_IGNORE, UNIWILL_OSD_RADIOOFF, { KEY_UNKNOWN }},
  297. /* Reported when user wants to cycle the platform profile */
  298. { KE_KEY, UNIWILL_OSD_PERFORMANCE_MODE_TOGGLE, { KEY_F14 }},
  299. /* Reported when the user wants to adjust the brightness of the keyboard */
  300. { KE_KEY, UNIWILL_OSD_KBDILLUMDOWN, { KEY_KBDILLUMDOWN }},
  301. { KE_KEY, UNIWILL_OSD_KBDILLUMUP, { KEY_KBDILLUMUP }},
  302. /* Reported when the user wants to toggle the microphone mute status */
  303. { KE_KEY, UNIWILL_OSD_MIC_MUTE, { KEY_MICMUTE }},
  304. /* Reported when the user wants to toggle the mute status */
  305. { KE_IGNORE, UNIWILL_OSD_MUTE, { KEY_MUTE }},
  306. /* Reported when the user wants to toggle the brightness of the keyboard */
  307. { KE_KEY, UNIWILL_OSD_KBDILLUMTOGGLE, { KEY_KBDILLUMTOGGLE }},
  308. { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL0, { KEY_KBDILLUMTOGGLE }},
  309. { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL1, { KEY_KBDILLUMTOGGLE }},
  310. { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL2, { KEY_KBDILLUMTOGGLE }},
  311. { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL3, { KEY_KBDILLUMTOGGLE }},
  312. { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL4, { KEY_KBDILLUMTOGGLE }},
  313. /* FIXME: find out the exact meaning of those events */
  314. { KE_IGNORE, UNIWILL_OSD_BAT_CHARGE_FULL_24_H, { KEY_UNKNOWN }},
  315. { KE_IGNORE, UNIWILL_OSD_BAT_ERM_UPDATE, { KEY_UNKNOWN }},
  316. /* Reported when the user wants to toggle the benchmark mode status */
  317. { KE_IGNORE, UNIWILL_OSD_BENCHMARK_MODE_TOGGLE, { KEY_UNKNOWN }},
  318. /* Reported when the user wants to toggle the webcam */
  319. { KE_IGNORE, UNIWILL_OSD_WEBCAM_TOGGLE, { KEY_UNKNOWN }},
  320. { KE_END }
  321. };
  322. static inline bool uniwill_device_supports(struct uniwill_data *data,
  323. unsigned int features)
  324. {
  325. return (data->features & features) == features;
  326. }
  327. static int uniwill_ec_reg_write(void *context, unsigned int reg, unsigned int val)
  328. {
  329. union acpi_object params[2] = {
  330. {
  331. .integer = {
  332. .type = ACPI_TYPE_INTEGER,
  333. .value = reg,
  334. },
  335. },
  336. {
  337. .integer = {
  338. .type = ACPI_TYPE_INTEGER,
  339. .value = val,
  340. },
  341. },
  342. };
  343. struct uniwill_data *data = context;
  344. struct acpi_object_list input = {
  345. .count = ARRAY_SIZE(params),
  346. .pointer = params,
  347. };
  348. acpi_status status;
  349. status = acpi_evaluate_object(data->handle, "ECRW", &input, NULL);
  350. if (ACPI_FAILURE(status))
  351. return -EIO;
  352. usleep_range(UNIWILL_EC_DELAY_US, UNIWILL_EC_DELAY_US * 2);
  353. return 0;
  354. }
  355. static int uniwill_ec_reg_read(void *context, unsigned int reg, unsigned int *val)
  356. {
  357. union acpi_object params[1] = {
  358. {
  359. .integer = {
  360. .type = ACPI_TYPE_INTEGER,
  361. .value = reg,
  362. },
  363. },
  364. };
  365. struct uniwill_data *data = context;
  366. struct acpi_object_list input = {
  367. .count = ARRAY_SIZE(params),
  368. .pointer = params,
  369. };
  370. unsigned long long output;
  371. acpi_status status;
  372. status = acpi_evaluate_integer(data->handle, "ECRR", &input, &output);
  373. if (ACPI_FAILURE(status))
  374. return -EIO;
  375. if (output > U8_MAX)
  376. return -ENXIO;
  377. usleep_range(UNIWILL_EC_DELAY_US, UNIWILL_EC_DELAY_US * 2);
  378. *val = output;
  379. return 0;
  380. }
  381. static const struct regmap_bus uniwill_ec_bus = {
  382. .reg_write = uniwill_ec_reg_write,
  383. .reg_read = uniwill_ec_reg_read,
  384. .reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
  385. .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
  386. };
  387. static bool uniwill_writeable_reg(struct device *dev, unsigned int reg)
  388. {
  389. switch (reg) {
  390. case EC_ADDR_AP_OEM:
  391. case EC_ADDR_LIGHTBAR_AC_CTRL:
  392. case EC_ADDR_LIGHTBAR_AC_RED:
  393. case EC_ADDR_LIGHTBAR_AC_GREEN:
  394. case EC_ADDR_LIGHTBAR_AC_BLUE:
  395. case EC_ADDR_BIOS_OEM:
  396. case EC_ADDR_TRIGGER:
  397. case EC_ADDR_OEM_4:
  398. case EC_ADDR_CHARGE_CTRL:
  399. case EC_ADDR_LIGHTBAR_BAT_CTRL:
  400. case EC_ADDR_LIGHTBAR_BAT_RED:
  401. case EC_ADDR_LIGHTBAR_BAT_GREEN:
  402. case EC_ADDR_LIGHTBAR_BAT_BLUE:
  403. case EC_ADDR_CTGP_DB_CTRL:
  404. case EC_ADDR_CTGP_DB_CTGP_OFFSET:
  405. case EC_ADDR_CTGP_DB_TPP_OFFSET:
  406. case EC_ADDR_CTGP_DB_DB_OFFSET:
  407. return true;
  408. default:
  409. return false;
  410. }
  411. }
  412. static bool uniwill_readable_reg(struct device *dev, unsigned int reg)
  413. {
  414. switch (reg) {
  415. case EC_ADDR_CPU_TEMP:
  416. case EC_ADDR_GPU_TEMP:
  417. case EC_ADDR_MAIN_FAN_RPM_1:
  418. case EC_ADDR_MAIN_FAN_RPM_2:
  419. case EC_ADDR_SECOND_FAN_RPM_1:
  420. case EC_ADDR_SECOND_FAN_RPM_2:
  421. case EC_ADDR_BAT_ALERT:
  422. case EC_ADDR_PROJECT_ID:
  423. case EC_ADDR_AP_OEM:
  424. case EC_ADDR_LIGHTBAR_AC_CTRL:
  425. case EC_ADDR_LIGHTBAR_AC_RED:
  426. case EC_ADDR_LIGHTBAR_AC_GREEN:
  427. case EC_ADDR_LIGHTBAR_AC_BLUE:
  428. case EC_ADDR_BIOS_OEM:
  429. case EC_ADDR_PWM_1:
  430. case EC_ADDR_PWM_2:
  431. case EC_ADDR_TRIGGER:
  432. case EC_ADDR_SWITCH_STATUS:
  433. case EC_ADDR_OEM_4:
  434. case EC_ADDR_CHARGE_CTRL:
  435. case EC_ADDR_LIGHTBAR_BAT_CTRL:
  436. case EC_ADDR_LIGHTBAR_BAT_RED:
  437. case EC_ADDR_LIGHTBAR_BAT_GREEN:
  438. case EC_ADDR_LIGHTBAR_BAT_BLUE:
  439. case EC_ADDR_SYSTEM_ID:
  440. case EC_ADDR_CTGP_DB_CTRL:
  441. case EC_ADDR_CTGP_DB_CTGP_OFFSET:
  442. case EC_ADDR_CTGP_DB_TPP_OFFSET:
  443. case EC_ADDR_CTGP_DB_DB_OFFSET:
  444. return true;
  445. default:
  446. return false;
  447. }
  448. }
  449. static bool uniwill_volatile_reg(struct device *dev, unsigned int reg)
  450. {
  451. switch (reg) {
  452. case EC_ADDR_CPU_TEMP:
  453. case EC_ADDR_GPU_TEMP:
  454. case EC_ADDR_MAIN_FAN_RPM_1:
  455. case EC_ADDR_MAIN_FAN_RPM_2:
  456. case EC_ADDR_SECOND_FAN_RPM_1:
  457. case EC_ADDR_SECOND_FAN_RPM_2:
  458. case EC_ADDR_BAT_ALERT:
  459. case EC_ADDR_BIOS_OEM:
  460. case EC_ADDR_PWM_1:
  461. case EC_ADDR_PWM_2:
  462. case EC_ADDR_TRIGGER:
  463. case EC_ADDR_SWITCH_STATUS:
  464. case EC_ADDR_CHARGE_CTRL:
  465. return true;
  466. default:
  467. return false;
  468. }
  469. }
  470. static const struct regmap_config uniwill_ec_config = {
  471. .reg_bits = 16,
  472. .val_bits = 8,
  473. .writeable_reg = uniwill_writeable_reg,
  474. .readable_reg = uniwill_readable_reg,
  475. .volatile_reg = uniwill_volatile_reg,
  476. .can_sleep = true,
  477. .max_register = 0xFFF,
  478. .cache_type = REGCACHE_MAPLE,
  479. .use_single_read = true,
  480. .use_single_write = true,
  481. };
  482. static ssize_t fn_lock_store(struct device *dev, struct device_attribute *attr, const char *buf,
  483. size_t count)
  484. {
  485. struct uniwill_data *data = dev_get_drvdata(dev);
  486. unsigned int value;
  487. bool enable;
  488. int ret;
  489. ret = kstrtobool(buf, &enable);
  490. if (ret < 0)
  491. return ret;
  492. if (enable)
  493. value = FN_LOCK_STATUS;
  494. else
  495. value = 0;
  496. ret = regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS, value);
  497. if (ret < 0)
  498. return ret;
  499. return count;
  500. }
  501. static ssize_t fn_lock_show(struct device *dev, struct device_attribute *attr, char *buf)
  502. {
  503. struct uniwill_data *data = dev_get_drvdata(dev);
  504. unsigned int value;
  505. int ret;
  506. ret = regmap_read(data->regmap, EC_ADDR_BIOS_OEM, &value);
  507. if (ret < 0)
  508. return ret;
  509. return sysfs_emit(buf, "%d\n", !!(value & FN_LOCK_STATUS));
  510. }
  511. static DEVICE_ATTR_RW(fn_lock);
  512. static ssize_t super_key_enable_store(struct device *dev, struct device_attribute *attr,
  513. const char *buf, size_t count)
  514. {
  515. struct uniwill_data *data = dev_get_drvdata(dev);
  516. unsigned int value;
  517. bool enable;
  518. int ret;
  519. ret = kstrtobool(buf, &enable);
  520. if (ret < 0)
  521. return ret;
  522. guard(mutex)(&data->super_key_lock);
  523. ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value);
  524. if (ret < 0)
  525. return ret;
  526. /*
  527. * We can only toggle the super key lock, so we return early if the setting
  528. * is already in the correct state.
  529. */
  530. if (enable == !(value & SUPER_KEY_LOCK_STATUS))
  531. return count;
  532. ret = regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK,
  533. TRIGGER_SUPER_KEY_LOCK);
  534. if (ret < 0)
  535. return ret;
  536. return count;
  537. }
  538. static ssize_t super_key_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
  539. {
  540. struct uniwill_data *data = dev_get_drvdata(dev);
  541. unsigned int value;
  542. int ret;
  543. ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value);
  544. if (ret < 0)
  545. return ret;
  546. return sysfs_emit(buf, "%d\n", !(value & SUPER_KEY_LOCK_STATUS));
  547. }
  548. static DEVICE_ATTR_RW(super_key_enable);
  549. static ssize_t touchpad_toggle_enable_store(struct device *dev, struct device_attribute *attr,
  550. const char *buf, size_t count)
  551. {
  552. struct uniwill_data *data = dev_get_drvdata(dev);
  553. unsigned int value;
  554. bool enable;
  555. int ret;
  556. ret = kstrtobool(buf, &enable);
  557. if (ret < 0)
  558. return ret;
  559. if (enable)
  560. value = 0;
  561. else
  562. value = TOUCHPAD_TOGGLE_OFF;
  563. ret = regmap_update_bits(data->regmap, EC_ADDR_OEM_4, TOUCHPAD_TOGGLE_OFF, value);
  564. if (ret < 0)
  565. return ret;
  566. return count;
  567. }
  568. static ssize_t touchpad_toggle_enable_show(struct device *dev, struct device_attribute *attr,
  569. char *buf)
  570. {
  571. struct uniwill_data *data = dev_get_drvdata(dev);
  572. unsigned int value;
  573. int ret;
  574. ret = regmap_read(data->regmap, EC_ADDR_OEM_4, &value);
  575. if (ret < 0)
  576. return ret;
  577. return sysfs_emit(buf, "%d\n", !(value & TOUCHPAD_TOGGLE_OFF));
  578. }
  579. static DEVICE_ATTR_RW(touchpad_toggle_enable);
  580. static ssize_t rainbow_animation_store(struct device *dev, struct device_attribute *attr,
  581. const char *buf, size_t count)
  582. {
  583. struct uniwill_data *data = dev_get_drvdata(dev);
  584. unsigned int value;
  585. bool enable;
  586. int ret;
  587. ret = kstrtobool(buf, &enable);
  588. if (ret < 0)
  589. return ret;
  590. if (enable)
  591. value = LIGHTBAR_WELCOME;
  592. else
  593. value = 0;
  594. guard(mutex)(&data->led_lock);
  595. ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, LIGHTBAR_WELCOME, value);
  596. if (ret < 0)
  597. return ret;
  598. ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_BAT_CTRL, LIGHTBAR_WELCOME, value);
  599. if (ret < 0)
  600. return ret;
  601. return count;
  602. }
  603. static ssize_t rainbow_animation_show(struct device *dev, struct device_attribute *attr, char *buf)
  604. {
  605. struct uniwill_data *data = dev_get_drvdata(dev);
  606. unsigned int value;
  607. int ret;
  608. ret = regmap_read(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, &value);
  609. if (ret < 0)
  610. return ret;
  611. return sysfs_emit(buf, "%d\n", !!(value & LIGHTBAR_WELCOME));
  612. }
  613. static DEVICE_ATTR_RW(rainbow_animation);
  614. static ssize_t breathing_in_suspend_store(struct device *dev, struct device_attribute *attr,
  615. const char *buf, size_t count)
  616. {
  617. struct uniwill_data *data = dev_get_drvdata(dev);
  618. unsigned int value;
  619. bool enable;
  620. int ret;
  621. ret = kstrtobool(buf, &enable);
  622. if (ret < 0)
  623. return ret;
  624. if (enable)
  625. value = 0;
  626. else
  627. value = LIGHTBAR_S3_OFF;
  628. /* We only access a single register here, so we do not need to use data->led_lock */
  629. ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, LIGHTBAR_S3_OFF, value);
  630. if (ret < 0)
  631. return ret;
  632. return count;
  633. }
  634. static ssize_t breathing_in_suspend_show(struct device *dev, struct device_attribute *attr,
  635. char *buf)
  636. {
  637. struct uniwill_data *data = dev_get_drvdata(dev);
  638. unsigned int value;
  639. int ret;
  640. ret = regmap_read(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, &value);
  641. if (ret < 0)
  642. return ret;
  643. return sysfs_emit(buf, "%d\n", !(value & LIGHTBAR_S3_OFF));
  644. }
  645. static DEVICE_ATTR_RW(breathing_in_suspend);
  646. static ssize_t ctgp_offset_store(struct device *dev, struct device_attribute *attr,
  647. const char *buf, size_t count)
  648. {
  649. struct uniwill_data *data = dev_get_drvdata(dev);
  650. unsigned int value;
  651. int ret;
  652. ret = kstrtouint(buf, 0, &value);
  653. if (ret < 0)
  654. return ret;
  655. if (value > U8_MAX)
  656. return -EINVAL;
  657. ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_CTGP_OFFSET, value);
  658. if (ret < 0)
  659. return ret;
  660. return count;
  661. }
  662. static ssize_t ctgp_offset_show(struct device *dev, struct device_attribute *attr,
  663. char *buf)
  664. {
  665. struct uniwill_data *data = dev_get_drvdata(dev);
  666. unsigned int value;
  667. int ret;
  668. ret = regmap_read(data->regmap, EC_ADDR_CTGP_DB_CTGP_OFFSET, &value);
  669. if (ret < 0)
  670. return ret;
  671. return sysfs_emit(buf, "%u\n", value);
  672. }
  673. static DEVICE_ATTR_RW(ctgp_offset);
  674. static int uniwill_nvidia_ctgp_init(struct uniwill_data *data)
  675. {
  676. int ret;
  677. if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
  678. return 0;
  679. ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_CTGP_OFFSET, 0);
  680. if (ret < 0)
  681. return ret;
  682. ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_TPP_OFFSET, 255);
  683. if (ret < 0)
  684. return ret;
  685. ret = regmap_write(data->regmap, EC_ADDR_CTGP_DB_DB_OFFSET, 25);
  686. if (ret < 0)
  687. return ret;
  688. ret = regmap_set_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL,
  689. CTGP_DB_GENERAL_ENABLE | CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE);
  690. if (ret < 0)
  691. return ret;
  692. return 0;
  693. }
  694. static struct attribute *uniwill_attrs[] = {
  695. /* Keyboard-related */
  696. &dev_attr_fn_lock.attr,
  697. &dev_attr_super_key_enable.attr,
  698. &dev_attr_touchpad_toggle_enable.attr,
  699. /* Lightbar-related */
  700. &dev_attr_rainbow_animation.attr,
  701. &dev_attr_breathing_in_suspend.attr,
  702. /* Power-management-related */
  703. &dev_attr_ctgp_offset.attr,
  704. NULL
  705. };
  706. static umode_t uniwill_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
  707. {
  708. struct device *dev = kobj_to_dev(kobj);
  709. struct uniwill_data *data = dev_get_drvdata(dev);
  710. if (attr == &dev_attr_fn_lock.attr) {
  711. if (uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
  712. return attr->mode;
  713. }
  714. if (attr == &dev_attr_super_key_enable.attr) {
  715. if (uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
  716. return attr->mode;
  717. }
  718. if (attr == &dev_attr_touchpad_toggle_enable.attr) {
  719. if (uniwill_device_supports(data, UNIWILL_FEATURE_TOUCHPAD_TOGGLE))
  720. return attr->mode;
  721. }
  722. if (attr == &dev_attr_rainbow_animation.attr ||
  723. attr == &dev_attr_breathing_in_suspend.attr) {
  724. if (uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR))
  725. return attr->mode;
  726. }
  727. if (attr == &dev_attr_ctgp_offset.attr) {
  728. if (uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
  729. return attr->mode;
  730. }
  731. return 0;
  732. }
  733. static const struct attribute_group uniwill_group = {
  734. .is_visible = uniwill_attr_is_visible,
  735. .attrs = uniwill_attrs,
  736. };
  737. static const struct attribute_group *uniwill_groups[] = {
  738. &uniwill_group,
  739. NULL
  740. };
  741. static int uniwill_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
  742. long *val)
  743. {
  744. struct uniwill_data *data = dev_get_drvdata(dev);
  745. unsigned int value;
  746. __be16 rpm;
  747. int ret;
  748. switch (type) {
  749. case hwmon_temp:
  750. switch (channel) {
  751. case 0:
  752. ret = regmap_read(data->regmap, EC_ADDR_CPU_TEMP, &value);
  753. break;
  754. case 1:
  755. ret = regmap_read(data->regmap, EC_ADDR_GPU_TEMP, &value);
  756. break;
  757. default:
  758. return -EOPNOTSUPP;
  759. }
  760. if (ret < 0)
  761. return ret;
  762. *val = value * MILLIDEGREE_PER_DEGREE;
  763. return 0;
  764. case hwmon_fan:
  765. switch (channel) {
  766. case 0:
  767. ret = regmap_bulk_read(data->regmap, EC_ADDR_MAIN_FAN_RPM_1, &rpm,
  768. sizeof(rpm));
  769. break;
  770. case 1:
  771. ret = regmap_bulk_read(data->regmap, EC_ADDR_SECOND_FAN_RPM_1, &rpm,
  772. sizeof(rpm));
  773. break;
  774. default:
  775. return -EOPNOTSUPP;
  776. }
  777. if (ret < 0)
  778. return ret;
  779. *val = be16_to_cpu(rpm);
  780. return 0;
  781. case hwmon_pwm:
  782. switch (channel) {
  783. case 0:
  784. ret = regmap_read(data->regmap, EC_ADDR_PWM_1, &value);
  785. break;
  786. case 1:
  787. ret = regmap_read(data->regmap, EC_ADDR_PWM_2, &value);
  788. break;
  789. default:
  790. return -EOPNOTSUPP;
  791. }
  792. if (ret < 0)
  793. return ret;
  794. *val = fixp_linear_interpolate(0, 0, PWM_MAX, U8_MAX, value);
  795. return 0;
  796. default:
  797. return -EOPNOTSUPP;
  798. }
  799. }
  800. static int uniwill_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  801. int channel, const char **str)
  802. {
  803. switch (type) {
  804. case hwmon_temp:
  805. *str = uniwill_temp_labels[channel];
  806. return 0;
  807. case hwmon_fan:
  808. *str = uniwill_fan_labels[channel];
  809. return 0;
  810. default:
  811. return -EOPNOTSUPP;
  812. }
  813. }
  814. static const struct hwmon_ops uniwill_ops = {
  815. .visible = 0444,
  816. .read = uniwill_read,
  817. .read_string = uniwill_read_string,
  818. };
  819. static const struct hwmon_channel_info * const uniwill_info[] = {
  820. HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
  821. HWMON_CHANNEL_INFO(temp,
  822. HWMON_T_INPUT | HWMON_T_LABEL,
  823. HWMON_T_INPUT | HWMON_T_LABEL),
  824. HWMON_CHANNEL_INFO(fan,
  825. HWMON_F_INPUT | HWMON_F_LABEL,
  826. HWMON_F_INPUT | HWMON_F_LABEL),
  827. HWMON_CHANNEL_INFO(pwm,
  828. HWMON_PWM_INPUT,
  829. HWMON_PWM_INPUT),
  830. NULL
  831. };
  832. static const struct hwmon_chip_info uniwill_chip_info = {
  833. .ops = &uniwill_ops,
  834. .info = uniwill_info,
  835. };
  836. static int uniwill_hwmon_init(struct uniwill_data *data)
  837. {
  838. struct device *hdev;
  839. if (!uniwill_device_supports(data, UNIWILL_FEATURE_HWMON))
  840. return 0;
  841. hdev = devm_hwmon_device_register_with_info(data->dev, "uniwill", data,
  842. &uniwill_chip_info, NULL);
  843. return PTR_ERR_OR_ZERO(hdev);
  844. }
  845. static const unsigned int uniwill_led_channel_to_bat_reg[LED_CHANNELS] = {
  846. EC_ADDR_LIGHTBAR_BAT_RED,
  847. EC_ADDR_LIGHTBAR_BAT_GREEN,
  848. EC_ADDR_LIGHTBAR_BAT_BLUE,
  849. };
  850. static const unsigned int uniwill_led_channel_to_ac_reg[LED_CHANNELS] = {
  851. EC_ADDR_LIGHTBAR_AC_RED,
  852. EC_ADDR_LIGHTBAR_AC_GREEN,
  853. EC_ADDR_LIGHTBAR_AC_BLUE,
  854. };
  855. static int uniwill_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness)
  856. {
  857. struct led_classdev_mc *led_mc_cdev = lcdev_to_mccdev(led_cdev);
  858. struct uniwill_data *data = container_of(led_mc_cdev, struct uniwill_data, led_mc_cdev);
  859. unsigned int value;
  860. int ret;
  861. ret = led_mc_calc_color_components(led_mc_cdev, brightness);
  862. if (ret < 0)
  863. return ret;
  864. guard(mutex)(&data->led_lock);
  865. for (int i = 0; i < LED_CHANNELS; i++) {
  866. /* Prevent the brightness values from overflowing */
  867. value = min(LED_MAX_BRIGHTNESS, data->led_mc_subled_info[i].brightness);
  868. ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
  869. if (ret < 0)
  870. return ret;
  871. ret = regmap_write(data->regmap, uniwill_led_channel_to_bat_reg[i], value);
  872. if (ret < 0)
  873. return ret;
  874. }
  875. if (brightness)
  876. value = 0;
  877. else
  878. value = LIGHTBAR_S0_OFF;
  879. ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, LIGHTBAR_S0_OFF, value);
  880. if (ret < 0)
  881. return ret;
  882. return regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_BAT_CTRL, LIGHTBAR_S0_OFF, value);
  883. }
  884. #define LIGHTBAR_MASK (LIGHTBAR_APP_EXISTS | LIGHTBAR_S0_OFF | LIGHTBAR_S3_OFF | LIGHTBAR_WELCOME)
  885. static int uniwill_led_init(struct uniwill_data *data)
  886. {
  887. struct led_init_data init_data = {
  888. .devicename = DRIVER_NAME,
  889. .default_label = "multicolor:" LED_FUNCTION_STATUS,
  890. .devname_mandatory = true,
  891. };
  892. unsigned int color_indices[3] = {
  893. LED_COLOR_ID_RED,
  894. LED_COLOR_ID_GREEN,
  895. LED_COLOR_ID_BLUE,
  896. };
  897. unsigned int value;
  898. int ret;
  899. if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR))
  900. return 0;
  901. ret = devm_mutex_init(data->dev, &data->led_lock);
  902. if (ret < 0)
  903. return ret;
  904. /*
  905. * The EC has separate lightbar settings for AC and battery mode,
  906. * so we have to ensure that both settings are the same.
  907. */
  908. ret = regmap_read(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, &value);
  909. if (ret < 0)
  910. return ret;
  911. value |= LIGHTBAR_APP_EXISTS;
  912. ret = regmap_write(data->regmap, EC_ADDR_LIGHTBAR_AC_CTRL, value);
  913. if (ret < 0)
  914. return ret;
  915. /*
  916. * The breathing animation during suspend is not supported when
  917. * running on battery power.
  918. */
  919. value |= LIGHTBAR_S3_OFF;
  920. ret = regmap_update_bits(data->regmap, EC_ADDR_LIGHTBAR_BAT_CTRL, LIGHTBAR_MASK, value);
  921. if (ret < 0)
  922. return ret;
  923. data->led_mc_cdev.led_cdev.color = LED_COLOR_ID_MULTI;
  924. data->led_mc_cdev.led_cdev.max_brightness = LED_MAX_BRIGHTNESS;
  925. data->led_mc_cdev.led_cdev.flags = LED_REJECT_NAME_CONFLICT;
  926. data->led_mc_cdev.led_cdev.brightness_set_blocking = uniwill_led_brightness_set;
  927. if (value & LIGHTBAR_S0_OFF)
  928. data->led_mc_cdev.led_cdev.brightness = 0;
  929. else
  930. data->led_mc_cdev.led_cdev.brightness = LED_MAX_BRIGHTNESS;
  931. for (int i = 0; i < LED_CHANNELS; i++) {
  932. data->led_mc_subled_info[i].color_index = color_indices[i];
  933. ret = regmap_read(data->regmap, uniwill_led_channel_to_ac_reg[i], &value);
  934. if (ret < 0)
  935. return ret;
  936. /*
  937. * Make sure that the initial intensity value is not greater than
  938. * the maximum brightness.
  939. */
  940. value = min(LED_MAX_BRIGHTNESS, value);
  941. ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
  942. if (ret < 0)
  943. return ret;
  944. ret = regmap_write(data->regmap, uniwill_led_channel_to_bat_reg[i], value);
  945. if (ret < 0)
  946. return ret;
  947. data->led_mc_subled_info[i].intensity = value;
  948. data->led_mc_subled_info[i].channel = i;
  949. }
  950. data->led_mc_cdev.subled_info = data->led_mc_subled_info;
  951. data->led_mc_cdev.num_colors = LED_CHANNELS;
  952. return devm_led_classdev_multicolor_register_ext(data->dev, &data->led_mc_cdev,
  953. &init_data);
  954. }
  955. static int uniwill_get_property(struct power_supply *psy, const struct power_supply_ext *ext,
  956. void *drvdata, enum power_supply_property psp,
  957. union power_supply_propval *val)
  958. {
  959. struct uniwill_data *data = drvdata;
  960. union power_supply_propval prop;
  961. unsigned int regval;
  962. int ret;
  963. switch (psp) {
  964. case POWER_SUPPLY_PROP_HEALTH:
  965. ret = power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_PRESENT, &prop);
  966. if (ret < 0)
  967. return ret;
  968. if (!prop.intval) {
  969. val->intval = POWER_SUPPLY_HEALTH_NO_BATTERY;
  970. return 0;
  971. }
  972. ret = power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_STATUS, &prop);
  973. if (ret < 0)
  974. return ret;
  975. if (prop.intval == POWER_SUPPLY_STATUS_UNKNOWN) {
  976. val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
  977. return 0;
  978. }
  979. ret = regmap_read(data->regmap, EC_ADDR_BAT_ALERT, &regval);
  980. if (ret < 0)
  981. return ret;
  982. if (regval) {
  983. /* Charging issue */
  984. val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
  985. return 0;
  986. }
  987. val->intval = POWER_SUPPLY_HEALTH_GOOD;
  988. return 0;
  989. case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
  990. ret = regmap_read(data->regmap, EC_ADDR_CHARGE_CTRL, &regval);
  991. if (ret < 0)
  992. return ret;
  993. val->intval = clamp_val(FIELD_GET(CHARGE_CTRL_MASK, regval), 0, 100);
  994. return 0;
  995. default:
  996. return -EINVAL;
  997. }
  998. }
  999. static int uniwill_set_property(struct power_supply *psy, const struct power_supply_ext *ext,
  1000. void *drvdata, enum power_supply_property psp,
  1001. const union power_supply_propval *val)
  1002. {
  1003. struct uniwill_data *data = drvdata;
  1004. switch (psp) {
  1005. case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
  1006. if (val->intval < 1 || val->intval > 100)
  1007. return -EINVAL;
  1008. return regmap_update_bits(data->regmap, EC_ADDR_CHARGE_CTRL, CHARGE_CTRL_MASK,
  1009. val->intval);
  1010. default:
  1011. return -EINVAL;
  1012. }
  1013. }
  1014. static int uniwill_property_is_writeable(struct power_supply *psy,
  1015. const struct power_supply_ext *ext, void *drvdata,
  1016. enum power_supply_property psp)
  1017. {
  1018. if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD)
  1019. return true;
  1020. return false;
  1021. }
  1022. static const enum power_supply_property uniwill_properties[] = {
  1023. POWER_SUPPLY_PROP_HEALTH,
  1024. POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD,
  1025. };
  1026. static const struct power_supply_ext uniwill_extension = {
  1027. .name = DRIVER_NAME,
  1028. .properties = uniwill_properties,
  1029. .num_properties = ARRAY_SIZE(uniwill_properties),
  1030. .get_property = uniwill_get_property,
  1031. .set_property = uniwill_set_property,
  1032. .property_is_writeable = uniwill_property_is_writeable,
  1033. };
  1034. static int uniwill_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
  1035. {
  1036. struct uniwill_data *data = container_of(hook, struct uniwill_data, hook);
  1037. struct uniwill_battery_entry *entry;
  1038. int ret;
  1039. entry = kzalloc_obj(*entry);
  1040. if (!entry)
  1041. return -ENOMEM;
  1042. ret = power_supply_register_extension(battery, &uniwill_extension, data->dev, data);
  1043. if (ret < 0) {
  1044. kfree(entry);
  1045. return ret;
  1046. }
  1047. guard(mutex)(&data->battery_lock);
  1048. entry->battery = battery;
  1049. list_add(&entry->head, &data->batteries);
  1050. return 0;
  1051. }
  1052. static int uniwill_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
  1053. {
  1054. struct uniwill_data *data = container_of(hook, struct uniwill_data, hook);
  1055. struct uniwill_battery_entry *entry, *tmp;
  1056. scoped_guard(mutex, &data->battery_lock) {
  1057. list_for_each_entry_safe(entry, tmp, &data->batteries, head) {
  1058. if (entry->battery == battery) {
  1059. list_del(&entry->head);
  1060. kfree(entry);
  1061. break;
  1062. }
  1063. }
  1064. }
  1065. power_supply_unregister_extension(battery, &uniwill_extension);
  1066. return 0;
  1067. }
  1068. static int uniwill_battery_init(struct uniwill_data *data)
  1069. {
  1070. int ret;
  1071. if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
  1072. return 0;
  1073. ret = devm_mutex_init(data->dev, &data->battery_lock);
  1074. if (ret < 0)
  1075. return ret;
  1076. INIT_LIST_HEAD(&data->batteries);
  1077. data->hook.name = "Uniwill Battery Extension";
  1078. data->hook.add_battery = uniwill_add_battery;
  1079. data->hook.remove_battery = uniwill_remove_battery;
  1080. return devm_battery_hook_register(data->dev, &data->hook);
  1081. }
  1082. static int uniwill_notifier_call(struct notifier_block *nb, unsigned long action, void *dummy)
  1083. {
  1084. struct uniwill_data *data = container_of(nb, struct uniwill_data, nb);
  1085. struct uniwill_battery_entry *entry;
  1086. switch (action) {
  1087. case UNIWILL_OSD_BATTERY_ALERT:
  1088. if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
  1089. return NOTIFY_DONE;
  1090. mutex_lock(&data->battery_lock);
  1091. list_for_each_entry(entry, &data->batteries, head) {
  1092. power_supply_changed(entry->battery);
  1093. }
  1094. mutex_unlock(&data->battery_lock);
  1095. return NOTIFY_OK;
  1096. case UNIWILL_OSD_DC_ADAPTER_CHANGED:
  1097. /* noop for the time being, will change once charging priority
  1098. * gets implemented.
  1099. */
  1100. return NOTIFY_OK;
  1101. case UNIWILL_OSD_FN_LOCK:
  1102. if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
  1103. return NOTIFY_DONE;
  1104. sysfs_notify(&data->dev->kobj, NULL, "fn_lock");
  1105. return NOTIFY_OK;
  1106. default:
  1107. mutex_lock(&data->input_lock);
  1108. sparse_keymap_report_event(data->input_device, action, 1, true);
  1109. mutex_unlock(&data->input_lock);
  1110. return NOTIFY_OK;
  1111. }
  1112. }
  1113. static int uniwill_input_init(struct uniwill_data *data)
  1114. {
  1115. int ret;
  1116. ret = devm_mutex_init(data->dev, &data->input_lock);
  1117. if (ret < 0)
  1118. return ret;
  1119. data->input_device = devm_input_allocate_device(data->dev);
  1120. if (!data->input_device)
  1121. return -ENOMEM;
  1122. ret = sparse_keymap_setup(data->input_device, uniwill_keymap, NULL);
  1123. if (ret < 0)
  1124. return ret;
  1125. data->input_device->name = "Uniwill WMI hotkeys";
  1126. data->input_device->phys = "wmi/input0";
  1127. data->input_device->id.bustype = BUS_HOST;
  1128. ret = input_register_device(data->input_device);
  1129. if (ret < 0)
  1130. return ret;
  1131. data->nb.notifier_call = uniwill_notifier_call;
  1132. return devm_uniwill_wmi_register_notifier(data->dev, &data->nb);
  1133. }
  1134. static void uniwill_disable_manual_control(void *context)
  1135. {
  1136. struct uniwill_data *data = context;
  1137. regmap_clear_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL);
  1138. }
  1139. static int uniwill_ec_init(struct uniwill_data *data)
  1140. {
  1141. unsigned int value;
  1142. int ret;
  1143. ret = regmap_read(data->regmap, EC_ADDR_PROJECT_ID, &value);
  1144. if (ret < 0)
  1145. return ret;
  1146. dev_dbg(data->dev, "Project ID: %u\n", value);
  1147. ret = regmap_set_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL);
  1148. if (ret < 0)
  1149. return ret;
  1150. return devm_add_action_or_reset(data->dev, uniwill_disable_manual_control, data);
  1151. }
  1152. static int uniwill_probe(struct platform_device *pdev)
  1153. {
  1154. struct uniwill_data *data;
  1155. struct regmap *regmap;
  1156. acpi_handle handle;
  1157. int ret;
  1158. handle = ACPI_HANDLE(&pdev->dev);
  1159. if (!handle)
  1160. return -ENODEV;
  1161. data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  1162. if (!data)
  1163. return -ENOMEM;
  1164. data->dev = &pdev->dev;
  1165. data->handle = handle;
  1166. platform_set_drvdata(pdev, data);
  1167. regmap = devm_regmap_init(&pdev->dev, &uniwill_ec_bus, data, &uniwill_ec_config);
  1168. if (IS_ERR(regmap))
  1169. return PTR_ERR(regmap);
  1170. data->regmap = regmap;
  1171. ret = devm_mutex_init(&pdev->dev, &data->super_key_lock);
  1172. if (ret < 0)
  1173. return ret;
  1174. ret = uniwill_ec_init(data);
  1175. if (ret < 0)
  1176. return ret;
  1177. data->features = device_descriptor.features;
  1178. /*
  1179. * Some devices might need to perform some device-specific initialization steps
  1180. * before the supported features are initialized. Because of this we have to call
  1181. * this callback just after the EC itself was initialized.
  1182. */
  1183. if (device_descriptor.probe) {
  1184. ret = device_descriptor.probe(data);
  1185. if (ret < 0)
  1186. return ret;
  1187. }
  1188. ret = uniwill_battery_init(data);
  1189. if (ret < 0)
  1190. return ret;
  1191. ret = uniwill_led_init(data);
  1192. if (ret < 0)
  1193. return ret;
  1194. ret = uniwill_hwmon_init(data);
  1195. if (ret < 0)
  1196. return ret;
  1197. ret = uniwill_nvidia_ctgp_init(data);
  1198. if (ret < 0)
  1199. return ret;
  1200. return uniwill_input_init(data);
  1201. }
  1202. static void uniwill_shutdown(struct platform_device *pdev)
  1203. {
  1204. struct uniwill_data *data = platform_get_drvdata(pdev);
  1205. regmap_clear_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL);
  1206. }
  1207. static int uniwill_suspend_fn_lock(struct uniwill_data *data)
  1208. {
  1209. if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
  1210. return 0;
  1211. /*
  1212. * The EC_ADDR_BIOS_OEM is marked as volatile, so we have to restore it
  1213. * ourselves.
  1214. */
  1215. return regmap_read(data->regmap, EC_ADDR_BIOS_OEM, &data->last_status);
  1216. }
  1217. static int uniwill_suspend_super_key(struct uniwill_data *data)
  1218. {
  1219. if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
  1220. return 0;
  1221. /*
  1222. * The EC_ADDR_SWITCH_STATUS is marked as volatile, so we have to restore it
  1223. * ourselves.
  1224. */
  1225. return regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &data->last_switch_status);
  1226. }
  1227. static int uniwill_suspend_battery(struct uniwill_data *data)
  1228. {
  1229. if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
  1230. return 0;
  1231. /*
  1232. * Save the current charge limit in order to restore it during resume.
  1233. * We cannot use the regmap code for that since this register needs to
  1234. * be declared as volatile due to CHARGE_CTRL_REACHED.
  1235. */
  1236. return regmap_read(data->regmap, EC_ADDR_CHARGE_CTRL, &data->last_charge_ctrl);
  1237. }
  1238. static int uniwill_suspend_nvidia_ctgp(struct uniwill_data *data)
  1239. {
  1240. if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
  1241. return 0;
  1242. return regmap_clear_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL,
  1243. CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE);
  1244. }
  1245. static int uniwill_suspend(struct device *dev)
  1246. {
  1247. struct uniwill_data *data = dev_get_drvdata(dev);
  1248. int ret;
  1249. ret = uniwill_suspend_fn_lock(data);
  1250. if (ret < 0)
  1251. return ret;
  1252. ret = uniwill_suspend_super_key(data);
  1253. if (ret < 0)
  1254. return ret;
  1255. ret = uniwill_suspend_battery(data);
  1256. if (ret < 0)
  1257. return ret;
  1258. ret = uniwill_suspend_nvidia_ctgp(data);
  1259. if (ret < 0)
  1260. return ret;
  1261. regcache_cache_only(data->regmap, true);
  1262. regcache_mark_dirty(data->regmap);
  1263. return 0;
  1264. }
  1265. static int uniwill_resume_fn_lock(struct uniwill_data *data)
  1266. {
  1267. if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK))
  1268. return 0;
  1269. return regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS,
  1270. data->last_status);
  1271. }
  1272. static int uniwill_resume_super_key(struct uniwill_data *data)
  1273. {
  1274. unsigned int value;
  1275. int ret;
  1276. if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
  1277. return 0;
  1278. ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value);
  1279. if (ret < 0)
  1280. return ret;
  1281. if ((data->last_switch_status & SUPER_KEY_LOCK_STATUS) == (value & SUPER_KEY_LOCK_STATUS))
  1282. return 0;
  1283. return regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_SUPER_KEY_LOCK,
  1284. TRIGGER_SUPER_KEY_LOCK);
  1285. }
  1286. static int uniwill_resume_battery(struct uniwill_data *data)
  1287. {
  1288. if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY))
  1289. return 0;
  1290. return regmap_update_bits(data->regmap, EC_ADDR_CHARGE_CTRL, CHARGE_CTRL_MASK,
  1291. data->last_charge_ctrl);
  1292. }
  1293. static int uniwill_resume_nvidia_ctgp(struct uniwill_data *data)
  1294. {
  1295. if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
  1296. return 0;
  1297. return regmap_set_bits(data->regmap, EC_ADDR_CTGP_DB_CTRL,
  1298. CTGP_DB_DB_ENABLE | CTGP_DB_CTGP_ENABLE);
  1299. }
  1300. static int uniwill_resume(struct device *dev)
  1301. {
  1302. struct uniwill_data *data = dev_get_drvdata(dev);
  1303. int ret;
  1304. regcache_cache_only(data->regmap, false);
  1305. ret = regcache_sync(data->regmap);
  1306. if (ret < 0)
  1307. return ret;
  1308. ret = uniwill_resume_fn_lock(data);
  1309. if (ret < 0)
  1310. return ret;
  1311. ret = uniwill_resume_super_key(data);
  1312. if (ret < 0)
  1313. return ret;
  1314. ret = uniwill_resume_battery(data);
  1315. if (ret < 0)
  1316. return ret;
  1317. return uniwill_resume_nvidia_ctgp(data);
  1318. }
  1319. static DEFINE_SIMPLE_DEV_PM_OPS(uniwill_pm_ops, uniwill_suspend, uniwill_resume);
  1320. /*
  1321. * We only use the DMI table for auoloading because the ACPI device itself
  1322. * does not guarantee that the underlying EC implementation is supported.
  1323. */
  1324. static const struct acpi_device_id uniwill_id_table[] = {
  1325. { "INOU0000" },
  1326. { },
  1327. };
  1328. static struct platform_driver uniwill_driver = {
  1329. .driver = {
  1330. .name = DRIVER_NAME,
  1331. .dev_groups = uniwill_groups,
  1332. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  1333. .acpi_match_table = uniwill_id_table,
  1334. .pm = pm_sleep_ptr(&uniwill_pm_ops),
  1335. },
  1336. .probe = uniwill_probe,
  1337. .shutdown = uniwill_shutdown,
  1338. };
  1339. static struct uniwill_device_descriptor lapac71h_descriptor __initdata = {
  1340. .features = UNIWILL_FEATURE_FN_LOCK |
  1341. UNIWILL_FEATURE_SUPER_KEY |
  1342. UNIWILL_FEATURE_TOUCHPAD_TOGGLE |
  1343. UNIWILL_FEATURE_BATTERY |
  1344. UNIWILL_FEATURE_HWMON,
  1345. };
  1346. static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = {
  1347. .features = UNIWILL_FEATURE_FN_LOCK |
  1348. UNIWILL_FEATURE_SUPER_KEY |
  1349. UNIWILL_FEATURE_TOUCHPAD_TOGGLE |
  1350. UNIWILL_FEATURE_LIGHTBAR |
  1351. UNIWILL_FEATURE_BATTERY |
  1352. UNIWILL_FEATURE_HWMON,
  1353. };
  1354. static int phxarx1_phxaqf1_probe(struct uniwill_data *data)
  1355. {
  1356. unsigned int value;
  1357. int ret;
  1358. ret = regmap_read(data->regmap, EC_ADDR_SYSTEM_ID, &value);
  1359. if (ret < 0)
  1360. return ret;
  1361. if (value & HAS_GPU)
  1362. data->features |= UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL;
  1363. return 0;
  1364. };
  1365. static struct uniwill_device_descriptor phxarx1_phxaqf1_descriptor __initdata = {
  1366. .probe = phxarx1_phxaqf1_probe,
  1367. };
  1368. static struct uniwill_device_descriptor tux_featureset_1_descriptor __initdata = {
  1369. .features = UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL,
  1370. };
  1371. static struct uniwill_device_descriptor empty_descriptor __initdata = {};
  1372. static const struct dmi_system_id uniwill_dmi_table[] __initconst = {
  1373. {
  1374. .ident = "XMG FUSION 15",
  1375. .matches = {
  1376. DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
  1377. DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71A"),
  1378. },
  1379. .driver_data = &empty_descriptor,
  1380. },
  1381. {
  1382. .ident = "XMG FUSION 15",
  1383. .matches = {
  1384. DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
  1385. DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71B"),
  1386. },
  1387. .driver_data = &empty_descriptor,
  1388. },
  1389. {
  1390. .ident = "Intel NUC x15",
  1391. .matches = {
  1392. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
  1393. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPAC71H"),
  1394. },
  1395. .driver_data = &lapac71h_descriptor,
  1396. },
  1397. {
  1398. .ident = "Intel NUC x15",
  1399. .matches = {
  1400. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
  1401. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPKC71F"),
  1402. },
  1403. .driver_data = &lapkc71f_descriptor,
  1404. },
  1405. {
  1406. .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel",
  1407. .matches = {
  1408. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1409. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTxX1"),
  1410. },
  1411. .driver_data = &empty_descriptor,
  1412. },
  1413. {
  1414. .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel",
  1415. .matches = {
  1416. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1417. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTQx1"),
  1418. },
  1419. .driver_data = &tux_featureset_1_descriptor,
  1420. },
  1421. {
  1422. .ident = "TUXEDO InfinityBook Pro 14/16 Gen7 Intel",
  1423. .matches = {
  1424. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1425. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxARX1_PHxAQF1"),
  1426. },
  1427. .driver_data = &phxarx1_phxaqf1_descriptor,
  1428. },
  1429. {
  1430. .ident = "TUXEDO InfinityBook Pro 16 Gen7 Intel/Commodore Omnia-Book Pro Gen 7",
  1431. .matches = {
  1432. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1433. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6AG01_PH6AQ71_PH6AQI1"),
  1434. },
  1435. .driver_data = &tux_featureset_1_descriptor,
  1436. },
  1437. {
  1438. .ident = "TUXEDO InfinityBook Pro 14/16 Gen8 Intel/Commodore Omnia-Book Pro Gen 8",
  1439. .matches = {
  1440. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1441. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1"),
  1442. },
  1443. .driver_data = &empty_descriptor,
  1444. },
  1445. {
  1446. .ident = "TUXEDO InfinityBook Pro 14 Gen8 Intel/Commodore Omnia-Book Pro Gen 8",
  1447. .matches = {
  1448. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1449. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PG31"),
  1450. },
  1451. .driver_data = &tux_featureset_1_descriptor,
  1452. },
  1453. {
  1454. .ident = "TUXEDO InfinityBook Pro 16 Gen8 Intel",
  1455. .matches = {
  1456. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1457. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6PG01_PH6PG71"),
  1458. },
  1459. .driver_data = &tux_featureset_1_descriptor,
  1460. },
  1461. {
  1462. .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 AMD",
  1463. .matches = {
  1464. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1465. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxHRXx"),
  1466. },
  1467. .driver_data = &empty_descriptor,
  1468. },
  1469. {
  1470. .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 Intel/Commodore Omnia-Book 15 Gen9",
  1471. .matches = {
  1472. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1473. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxMRXx"),
  1474. },
  1475. .driver_data = &empty_descriptor,
  1476. },
  1477. {
  1478. .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD",
  1479. .matches = {
  1480. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1481. DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxHP4NAx"),
  1482. },
  1483. .driver_data = &empty_descriptor,
  1484. },
  1485. {
  1486. .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD",
  1487. .matches = {
  1488. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1489. DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxKK4NAx_XxSP4NAx"),
  1490. },
  1491. .driver_data = &empty_descriptor,
  1492. },
  1493. {
  1494. .ident = "TUXEDO InfinityBook Pro 15 Gen10 Intel",
  1495. .matches = {
  1496. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1497. DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxAR4NAx"),
  1498. },
  1499. .driver_data = &empty_descriptor,
  1500. },
  1501. {
  1502. .ident = "TUXEDO InfinityBook Max 15 Gen10 AMD",
  1503. .matches = {
  1504. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1505. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5KK45xS_X5SP45xS"),
  1506. },
  1507. .driver_data = &empty_descriptor,
  1508. },
  1509. {
  1510. .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD",
  1511. .matches = {
  1512. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1513. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6HP45xU"),
  1514. },
  1515. .driver_data = &empty_descriptor,
  1516. },
  1517. {
  1518. .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD",
  1519. .matches = {
  1520. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1521. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6KK45xU_X6SP45xU"),
  1522. },
  1523. .driver_data = &empty_descriptor,
  1524. },
  1525. {
  1526. .ident = "TUXEDO InfinityBook Max 15 Gen10 Intel",
  1527. .matches = {
  1528. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1529. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5AR45xS"),
  1530. },
  1531. .driver_data = &empty_descriptor,
  1532. },
  1533. {
  1534. .ident = "TUXEDO InfinityBook Max 16 Gen10 Intel",
  1535. .matches = {
  1536. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1537. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR55xU"),
  1538. },
  1539. .driver_data = &empty_descriptor,
  1540. },
  1541. {
  1542. .ident = "TUXEDO Polaris 15 Gen1 AMD",
  1543. .matches = {
  1544. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1545. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"),
  1546. },
  1547. .driver_data = &empty_descriptor,
  1548. },
  1549. {
  1550. .ident = "TUXEDO Polaris 15 Gen1 AMD",
  1551. .matches = {
  1552. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1553. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"),
  1554. },
  1555. .driver_data = &empty_descriptor,
  1556. },
  1557. {
  1558. .ident = "TUXEDO Polaris 17 Gen1 AMD",
  1559. .matches = {
  1560. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1561. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"),
  1562. },
  1563. .driver_data = &empty_descriptor,
  1564. },
  1565. {
  1566. .ident = "TUXEDO Polaris 17 Gen1 AMD",
  1567. .matches = {
  1568. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1569. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"),
  1570. },
  1571. .driver_data = &empty_descriptor,
  1572. },
  1573. {
  1574. .ident = "TUXEDO Polaris 15 Gen1 Intel",
  1575. .matches = {
  1576. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1577. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I1650TI"),
  1578. },
  1579. .driver_data = &empty_descriptor,
  1580. },
  1581. {
  1582. .ident = "TUXEDO Polaris 15 Gen1 Intel",
  1583. .matches = {
  1584. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1585. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I2060"),
  1586. },
  1587. .driver_data = &empty_descriptor,
  1588. },
  1589. {
  1590. .ident = "TUXEDO Polaris 17 Gen1 Intel",
  1591. .matches = {
  1592. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1593. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I1650TI"),
  1594. },
  1595. .driver_data = &empty_descriptor,
  1596. },
  1597. {
  1598. .ident = "TUXEDO Polaris 17 Gen1 Intel",
  1599. .matches = {
  1600. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1601. DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I2060"),
  1602. },
  1603. .driver_data = &empty_descriptor,
  1604. },
  1605. {
  1606. .ident = "TUXEDO Trinity 15 Intel Gen1",
  1607. .matches = {
  1608. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1609. DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1501I"),
  1610. },
  1611. .driver_data = &empty_descriptor,
  1612. },
  1613. {
  1614. .ident = "TUXEDO Trinity 17 Intel Gen1",
  1615. .matches = {
  1616. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1617. DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1701I"),
  1618. },
  1619. .driver_data = &empty_descriptor,
  1620. },
  1621. {
  1622. .ident = "TUXEDO Polaris 15/17 Gen2 AMD",
  1623. .matches = {
  1624. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1625. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxMGxx"),
  1626. },
  1627. .driver_data = &tux_featureset_1_descriptor,
  1628. },
  1629. {
  1630. .ident = "TUXEDO Polaris 15/17 Gen2 Intel",
  1631. .matches = {
  1632. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1633. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxNGxx"),
  1634. },
  1635. .driver_data = &tux_featureset_1_descriptor,
  1636. },
  1637. {
  1638. .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 AMD",
  1639. .matches = {
  1640. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1641. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxZGxx"),
  1642. },
  1643. .driver_data = &tux_featureset_1_descriptor,
  1644. },
  1645. {
  1646. .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 Intel",
  1647. .matches = {
  1648. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1649. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxTGxx"),
  1650. },
  1651. .driver_data = &tux_featureset_1_descriptor,
  1652. },
  1653. {
  1654. .ident = "TUXEDO Stellaris/Polaris 15/17 Gen4 AMD",
  1655. .matches = {
  1656. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1657. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
  1658. },
  1659. .driver_data = &tux_featureset_1_descriptor,
  1660. },
  1661. {
  1662. .ident = "TUXEDO Stellaris 15 Gen4 Intel",
  1663. .matches = {
  1664. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1665. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxAGxx"),
  1666. },
  1667. .driver_data = &tux_featureset_1_descriptor,
  1668. },
  1669. {
  1670. .ident = "TUXEDO Polaris 15/17 Gen5 AMD",
  1671. .matches = {
  1672. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1673. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
  1674. },
  1675. .driver_data = &tux_featureset_1_descriptor,
  1676. },
  1677. {
  1678. .ident = "TUXEDO Stellaris 16 Gen5 AMD",
  1679. .matches = {
  1680. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1681. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6XGxX"),
  1682. },
  1683. .driver_data = &tux_featureset_1_descriptor,
  1684. },
  1685. {
  1686. .ident = "TUXEDO Stellaris 16/17 Gen5 Intel/Commodore ORION Gen 5",
  1687. .matches = {
  1688. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1689. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxPXxx"),
  1690. },
  1691. .driver_data = &tux_featureset_1_descriptor,
  1692. },
  1693. {
  1694. .ident = "TUXEDO Stellaris Slim 15 Gen6 AMD",
  1695. .matches = {
  1696. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1697. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
  1698. },
  1699. .driver_data = &tux_featureset_1_descriptor,
  1700. },
  1701. {
  1702. .ident = "TUXEDO Stellaris Slim 15 Gen6 Intel/Commodore ORION Slim 15 Gen6",
  1703. .matches = {
  1704. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1705. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM5IXxA"),
  1706. },
  1707. .driver_data = &tux_featureset_1_descriptor,
  1708. },
  1709. {
  1710. .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6",
  1711. .matches = {
  1712. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1713. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB1"),
  1714. },
  1715. .driver_data = &tux_featureset_1_descriptor,
  1716. },
  1717. {
  1718. .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6",
  1719. .matches = {
  1720. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1721. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB2"),
  1722. },
  1723. .driver_data = &tux_featureset_1_descriptor,
  1724. },
  1725. {
  1726. .ident = "TUXEDO Stellaris 17 Gen6 Intel/Commodore ORION 17 Gen6",
  1727. .matches = {
  1728. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1729. DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM7IXxN"),
  1730. },
  1731. .driver_data = &tux_featureset_1_descriptor,
  1732. },
  1733. {
  1734. .ident = "TUXEDO Stellaris 16 Gen7 AMD",
  1735. .matches = {
  1736. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1737. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6FR5xxY"),
  1738. },
  1739. .driver_data = &tux_featureset_1_descriptor,
  1740. },
  1741. {
  1742. .ident = "TUXEDO Stellaris 16 Gen7 Intel",
  1743. .matches = {
  1744. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1745. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY"),
  1746. },
  1747. .driver_data = &tux_featureset_1_descriptor,
  1748. },
  1749. {
  1750. .ident = "TUXEDO Stellaris 16 Gen7 Intel",
  1751. .matches = {
  1752. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1753. DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY_mLED"),
  1754. },
  1755. .driver_data = &tux_featureset_1_descriptor,
  1756. },
  1757. {
  1758. .ident = "TUXEDO Book BA15 Gen10 AMD",
  1759. .matches = {
  1760. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1761. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5PU1G"),
  1762. },
  1763. .driver_data = &empty_descriptor,
  1764. },
  1765. {
  1766. .ident = "TUXEDO Pulse 14 Gen1 AMD",
  1767. .matches = {
  1768. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1769. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1401"),
  1770. },
  1771. .driver_data = &empty_descriptor,
  1772. },
  1773. {
  1774. .ident = "TUXEDO Pulse 15 Gen1 AMD",
  1775. .matches = {
  1776. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1777. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1501"),
  1778. },
  1779. .driver_data = &empty_descriptor,
  1780. },
  1781. {
  1782. .ident = "TUXEDO Pulse 15 Gen2 AMD",
  1783. .matches = {
  1784. DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
  1785. DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
  1786. },
  1787. .driver_data = &empty_descriptor,
  1788. },
  1789. { }
  1790. };
  1791. MODULE_DEVICE_TABLE(dmi, uniwill_dmi_table);
  1792. static int __init uniwill_init(void)
  1793. {
  1794. const struct uniwill_device_descriptor *descriptor;
  1795. const struct dmi_system_id *id;
  1796. int ret;
  1797. id = dmi_first_match(uniwill_dmi_table);
  1798. if (!id) {
  1799. if (!force)
  1800. return -ENODEV;
  1801. /* Assume that the device supports all features */
  1802. device_descriptor.features = UINT_MAX;
  1803. pr_warn("Loading on a potentially unsupported device\n");
  1804. } else {
  1805. /*
  1806. * Some devices might support additional features depending on
  1807. * the BIOS version/date, so we call this callback to let them
  1808. * modify their device descriptor accordingly.
  1809. */
  1810. if (id->callback) {
  1811. ret = id->callback(id);
  1812. if (ret < 0)
  1813. return ret;
  1814. }
  1815. descriptor = id->driver_data;
  1816. device_descriptor = *descriptor;
  1817. }
  1818. ret = platform_driver_register(&uniwill_driver);
  1819. if (ret < 0)
  1820. return ret;
  1821. ret = uniwill_wmi_register_driver();
  1822. if (ret < 0) {
  1823. platform_driver_unregister(&uniwill_driver);
  1824. return ret;
  1825. }
  1826. return 0;
  1827. }
  1828. module_init(uniwill_init);
  1829. static void __exit uniwill_exit(void)
  1830. {
  1831. uniwill_wmi_unregister_driver();
  1832. platform_driver_unregister(&uniwill_driver);
  1833. }
  1834. module_exit(uniwill_exit);
  1835. MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
  1836. MODULE_DESCRIPTION("Uniwill notebook driver");
  1837. MODULE_LICENSE("GPL");