asus-wmi.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765
  1. /*
  2. * Asus PC WMI hotkey driver
  3. *
  4. * Copyright(C) 2010 Intel Corporation.
  5. * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
  6. *
  7. * Portions based on wistron_btns.c:
  8. * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
  9. * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
  10. * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  25. */
  26. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  27. #include <linux/kernel.h>
  28. #include <linux/module.h>
  29. #include <linux/init.h>
  30. #include <linux/types.h>
  31. #include <linux/slab.h>
  32. #include <linux/input.h>
  33. #include <linux/input/sparse-keymap.h>
  34. #include <linux/fb.h>
  35. #include <linux/backlight.h>
  36. #include <linux/leds.h>
  37. #include <linux/rfkill.h>
  38. #include <linux/pci.h>
  39. #include <linux/pci_hotplug.h>
  40. #include <linux/hwmon.h>
  41. #include <linux/hwmon-sysfs.h>
  42. #include <linux/debugfs.h>
  43. #include <linux/seq_file.h>
  44. #include <linux/platform_device.h>
  45. #include <acpi/acpi_bus.h>
  46. #include <acpi/acpi_drivers.h>
  47. #include "asus-wmi.h"
  48. MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>, "
  49. "Yong Wang <yong.y.wang@intel.com>");
  50. MODULE_DESCRIPTION("Asus Generic WMI Driver");
  51. MODULE_LICENSE("GPL");
  52. #define to_platform_driver(drv) \
  53. (container_of((drv), struct platform_driver, driver))
  54. #define to_asus_wmi_driver(pdrv) \
  55. (container_of((pdrv), struct asus_wmi_driver, platform_driver))
  56. #define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
  57. #define NOTIFY_BRNUP_MIN 0x11
  58. #define NOTIFY_BRNUP_MAX 0x1f
  59. #define NOTIFY_BRNDOWN_MIN 0x20
  60. #define NOTIFY_BRNDOWN_MAX 0x2e
  61. #define NOTIFY_KBD_BRTUP 0xc4
  62. #define NOTIFY_KBD_BRTDWN 0xc5
  63. /* WMI Methods */
  64. #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
  65. #define ASUS_WMI_METHODID_SFBD 0x44424653 /* Set First Boot Device */
  66. #define ASUS_WMI_METHODID_GLCD 0x44434C47 /* Get LCD status */
  67. #define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */
  68. #define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */
  69. #define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */
  70. #define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */
  71. #define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */
  72. #define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */
  73. #define ASUS_WMI_METHODID_DEVP 0x50564544 /* DEVice Policy */
  74. #define ASUS_WMI_METHODID_OSVR 0x5256534F /* OS VeRsion */
  75. #define ASUS_WMI_METHODID_DSTS 0x53544344 /* Device STatuS */
  76. #define ASUS_WMI_METHODID_DSTS2 0x53545344 /* Device STatuS #2*/
  77. #define ASUS_WMI_METHODID_BSTS 0x53545342 /* Bios STatuS ? */
  78. #define ASUS_WMI_METHODID_DEVS 0x53564544 /* DEVice Set */
  79. #define ASUS_WMI_METHODID_CFVS 0x53564643 /* CPU Frequency Volt Set */
  80. #define ASUS_WMI_METHODID_KBFT 0x5446424B /* KeyBoard FilTer */
  81. #define ASUS_WMI_METHODID_INIT 0x54494E49 /* INITialize */
  82. #define ASUS_WMI_METHODID_HKEY 0x59454B48 /* Hot KEY ?? */
  83. #define ASUS_WMI_UNSUPPORTED_METHOD 0xFFFFFFFE
  84. /* Wireless */
  85. #define ASUS_WMI_DEVID_HW_SWITCH 0x00010001
  86. #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002
  87. #define ASUS_WMI_DEVID_WLAN 0x00010011
  88. #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013
  89. #define ASUS_WMI_DEVID_GPS 0x00010015
  90. #define ASUS_WMI_DEVID_WIMAX 0x00010017
  91. #define ASUS_WMI_DEVID_WWAN3G 0x00010019
  92. #define ASUS_WMI_DEVID_UWB 0x00010021
  93. /* Leds */
  94. /* 0x000200XX and 0x000400XX */
  95. /* Backlight and Brightness */
  96. #define ASUS_WMI_DEVID_BACKLIGHT 0x00050011
  97. #define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012
  98. #define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021
  99. #define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */
  100. /* Misc */
  101. #define ASUS_WMI_DEVID_CAMERA 0x00060013
  102. /* Storage */
  103. #define ASUS_WMI_DEVID_CARDREADER 0x00080013
  104. /* Input */
  105. #define ASUS_WMI_DEVID_TOUCHPAD 0x00100011
  106. #define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012
  107. /* Fan, Thermal */
  108. #define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011
  109. #define ASUS_WMI_DEVID_FAN_CTRL 0x00110012
  110. /* Power */
  111. #define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
  112. /* DSTS masks */
  113. #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
  114. #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
  115. #define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000
  116. #define ASUS_WMI_DSTS_USER_BIT 0x00020000
  117. #define ASUS_WMI_DSTS_BIOS_BIT 0x00040000
  118. #define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
  119. #define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
  120. struct bios_args {
  121. u32 arg0;
  122. u32 arg1;
  123. } __packed;
  124. /*
  125. * <platform>/ - debugfs root directory
  126. * dev_id - current dev_id
  127. * ctrl_param - current ctrl_param
  128. * method_id - current method_id
  129. * devs - call DEVS(dev_id, ctrl_param) and print result
  130. * dsts - call DSTS(dev_id) and print result
  131. * call - call method_id(dev_id, ctrl_param) and print result
  132. */
  133. struct asus_wmi_debug {
  134. struct dentry *root;
  135. u32 method_id;
  136. u32 dev_id;
  137. u32 ctrl_param;
  138. };
  139. struct asus_rfkill {
  140. struct asus_wmi *asus;
  141. struct rfkill *rfkill;
  142. u32 dev_id;
  143. };
  144. struct asus_wmi {
  145. int dsts_id;
  146. int spec;
  147. int sfun;
  148. struct input_dev *inputdev;
  149. struct backlight_device *backlight_device;
  150. struct device *hwmon_device;
  151. struct platform_device *platform_device;
  152. struct led_classdev tpd_led;
  153. int tpd_led_wk;
  154. struct led_classdev kbd_led;
  155. int kbd_led_wk;
  156. struct workqueue_struct *led_workqueue;
  157. struct work_struct tpd_led_work;
  158. struct work_struct kbd_led_work;
  159. struct asus_rfkill wlan;
  160. struct asus_rfkill bluetooth;
  161. struct asus_rfkill wimax;
  162. struct asus_rfkill wwan3g;
  163. struct hotplug_slot *hotplug_slot;
  164. struct mutex hotplug_lock;
  165. struct mutex wmi_lock;
  166. struct workqueue_struct *hotplug_workqueue;
  167. struct work_struct hotplug_work;
  168. struct asus_wmi_debug debug;
  169. struct asus_wmi_driver *driver;
  170. };
  171. static int asus_wmi_input_init(struct asus_wmi *asus)
  172. {
  173. int err;
  174. asus->inputdev = input_allocate_device();
  175. if (!asus->inputdev)
  176. return -ENOMEM;
  177. asus->inputdev->name = asus->driver->input_name;
  178. asus->inputdev->phys = asus->driver->input_phys;
  179. asus->inputdev->id.bustype = BUS_HOST;
  180. asus->inputdev->dev.parent = &asus->platform_device->dev;
  181. set_bit(EV_REP, asus->inputdev->evbit);
  182. err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
  183. if (err)
  184. goto err_free_dev;
  185. err = input_register_device(asus->inputdev);
  186. if (err)
  187. goto err_free_keymap;
  188. return 0;
  189. err_free_keymap:
  190. sparse_keymap_free(asus->inputdev);
  191. err_free_dev:
  192. input_free_device(asus->inputdev);
  193. return err;
  194. }
  195. static void asus_wmi_input_exit(struct asus_wmi *asus)
  196. {
  197. if (asus->inputdev) {
  198. sparse_keymap_free(asus->inputdev);
  199. input_unregister_device(asus->inputdev);
  200. }
  201. asus->inputdev = NULL;
  202. }
  203. static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
  204. u32 *retval)
  205. {
  206. struct bios_args args = {
  207. .arg0 = arg0,
  208. .arg1 = arg1,
  209. };
  210. struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
  211. struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
  212. acpi_status status;
  213. union acpi_object *obj;
  214. u32 tmp;
  215. status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id,
  216. &input, &output);
  217. if (ACPI_FAILURE(status))
  218. goto exit;
  219. obj = (union acpi_object *)output.pointer;
  220. if (obj && obj->type == ACPI_TYPE_INTEGER)
  221. tmp = (u32) obj->integer.value;
  222. else
  223. tmp = 0;
  224. if (retval)
  225. *retval = tmp;
  226. kfree(obj);
  227. exit:
  228. if (ACPI_FAILURE(status))
  229. return -EIO;
  230. if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
  231. return -ENODEV;
  232. return 0;
  233. }
  234. static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
  235. {
  236. return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval);
  237. }
  238. static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
  239. u32 *retval)
  240. {
  241. return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
  242. ctrl_param, retval);
  243. }
  244. /* Helper for special devices with magic return codes */
  245. static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
  246. u32 dev_id, u32 mask)
  247. {
  248. u32 retval = 0;
  249. int err;
  250. err = asus_wmi_get_devstate(asus, dev_id, &retval);
  251. if (err < 0)
  252. return err;
  253. if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT))
  254. return -ENODEV;
  255. if (mask == ASUS_WMI_DSTS_STATUS_BIT) {
  256. if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT)
  257. return -ENODEV;
  258. }
  259. return retval & mask;
  260. }
  261. static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
  262. {
  263. return asus_wmi_get_devstate_bits(asus, dev_id,
  264. ASUS_WMI_DSTS_STATUS_BIT);
  265. }
  266. /*
  267. * LEDs
  268. */
  269. /*
  270. * These functions actually update the LED's, and are called from a
  271. * workqueue. By doing this as separate work rather than when the LED
  272. * subsystem asks, we avoid messing with the Asus ACPI stuff during a
  273. * potentially bad time, such as a timer interrupt.
  274. */
  275. static void tpd_led_update(struct work_struct *work)
  276. {
  277. int ctrl_param;
  278. struct asus_wmi *asus;
  279. asus = container_of(work, struct asus_wmi, tpd_led_work);
  280. ctrl_param = asus->tpd_led_wk;
  281. asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
  282. }
  283. static void tpd_led_set(struct led_classdev *led_cdev,
  284. enum led_brightness value)
  285. {
  286. struct asus_wmi *asus;
  287. asus = container_of(led_cdev, struct asus_wmi, tpd_led);
  288. asus->tpd_led_wk = !!value;
  289. queue_work(asus->led_workqueue, &asus->tpd_led_work);
  290. }
  291. static int read_tpd_led_state(struct asus_wmi *asus)
  292. {
  293. return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED);
  294. }
  295. static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
  296. {
  297. struct asus_wmi *asus;
  298. asus = container_of(led_cdev, struct asus_wmi, tpd_led);
  299. return read_tpd_led_state(asus);
  300. }
  301. static void kbd_led_update(struct work_struct *work)
  302. {
  303. int ctrl_param = 0;
  304. struct asus_wmi *asus;
  305. asus = container_of(work, struct asus_wmi, kbd_led_work);
  306. /*
  307. * bits 0-2: level
  308. * bit 7: light on/off
  309. */
  310. if (asus->kbd_led_wk > 0)
  311. ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
  312. asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
  313. }
  314. static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
  315. {
  316. int retval;
  317. /*
  318. * bits 0-2: level
  319. * bit 7: light on/off
  320. * bit 8-10: environment (0: dark, 1: normal, 2: light)
  321. * bit 17: status unknown
  322. */
  323. retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT,
  324. 0xFFFF);
  325. if (retval == 0x8000)
  326. retval = -ENODEV;
  327. if (retval >= 0) {
  328. if (level)
  329. *level = retval & 0x80 ? retval & 0x7F : 0;
  330. if (env)
  331. *env = (retval >> 8) & 0x7F;
  332. retval = 0;
  333. }
  334. return retval;
  335. }
  336. static void kbd_led_set(struct led_classdev *led_cdev,
  337. enum led_brightness value)
  338. {
  339. struct asus_wmi *asus;
  340. asus = container_of(led_cdev, struct asus_wmi, kbd_led);
  341. if (value > asus->kbd_led.max_brightness)
  342. value = asus->kbd_led.max_brightness;
  343. else if (value < 0)
  344. value = 0;
  345. asus->kbd_led_wk = value;
  346. queue_work(asus->led_workqueue, &asus->kbd_led_work);
  347. }
  348. static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
  349. {
  350. struct asus_wmi *asus;
  351. int retval, value;
  352. asus = container_of(led_cdev, struct asus_wmi, kbd_led);
  353. retval = kbd_led_read(asus, &value, NULL);
  354. if (retval < 0)
  355. return retval;
  356. return value;
  357. }
  358. static void asus_wmi_led_exit(struct asus_wmi *asus)
  359. {
  360. if (asus->tpd_led.dev)
  361. led_classdev_unregister(&asus->tpd_led);
  362. if (asus->led_workqueue)
  363. destroy_workqueue(asus->led_workqueue);
  364. }
  365. static int asus_wmi_led_init(struct asus_wmi *asus)
  366. {
  367. int rv = 0;
  368. asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
  369. if (!asus->led_workqueue)
  370. return -ENOMEM;
  371. if (read_tpd_led_state(asus) >= 0) {
  372. INIT_WORK(&asus->tpd_led_work, tpd_led_update);
  373. asus->tpd_led.name = "asus::touchpad";
  374. asus->tpd_led.brightness_set = tpd_led_set;
  375. asus->tpd_led.brightness_get = tpd_led_get;
  376. asus->tpd_led.max_brightness = 1;
  377. rv = led_classdev_register(&asus->platform_device->dev,
  378. &asus->tpd_led);
  379. if (rv)
  380. goto error;
  381. }
  382. if (kbd_led_read(asus, NULL, NULL) >= 0) {
  383. INIT_WORK(&asus->kbd_led_work, kbd_led_update);
  384. asus->kbd_led.name = "asus::kbd_backlight";
  385. asus->kbd_led.brightness_set = kbd_led_set;
  386. asus->kbd_led.brightness_get = kbd_led_get;
  387. asus->kbd_led.max_brightness = 3;
  388. rv = led_classdev_register(&asus->platform_device->dev,
  389. &asus->kbd_led);
  390. }
  391. error:
  392. if (rv)
  393. asus_wmi_led_exit(asus);
  394. return rv;
  395. }
  396. /*
  397. * PCI hotplug (for wlan rfkill)
  398. */
  399. static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
  400. {
  401. int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
  402. if (result < 0)
  403. return false;
  404. return !result;
  405. }
  406. static void asus_rfkill_hotplug(struct asus_wmi *asus)
  407. {
  408. struct pci_dev *dev;
  409. struct pci_bus *bus;
  410. bool blocked;
  411. bool absent;
  412. u32 l;
  413. mutex_lock(&asus->wmi_lock);
  414. blocked = asus_wlan_rfkill_blocked(asus);
  415. mutex_unlock(&asus->wmi_lock);
  416. mutex_lock(&asus->hotplug_lock);
  417. if (asus->wlan.rfkill)
  418. rfkill_set_sw_state(asus->wlan.rfkill, blocked);
  419. if (asus->hotplug_slot) {
  420. bus = pci_find_bus(0, 1);
  421. if (!bus) {
  422. pr_warn("Unable to find PCI bus 1?\n");
  423. goto out_unlock;
  424. }
  425. if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
  426. pr_err("Unable to read PCI config space?\n");
  427. goto out_unlock;
  428. }
  429. absent = (l == 0xffffffff);
  430. if (blocked != absent) {
  431. pr_warn("BIOS says wireless lan is %s, "
  432. "but the pci device is %s\n",
  433. blocked ? "blocked" : "unblocked",
  434. absent ? "absent" : "present");
  435. pr_warn("skipped wireless hotplug as probably "
  436. "inappropriate for this model\n");
  437. goto out_unlock;
  438. }
  439. if (!blocked) {
  440. dev = pci_get_slot(bus, 0);
  441. if (dev) {
  442. /* Device already present */
  443. pci_dev_put(dev);
  444. goto out_unlock;
  445. }
  446. dev = pci_scan_single_device(bus, 0);
  447. if (dev) {
  448. pci_bus_assign_resources(bus);
  449. if (pci_bus_add_device(dev))
  450. pr_err("Unable to hotplug wifi\n");
  451. }
  452. } else {
  453. dev = pci_get_slot(bus, 0);
  454. if (dev) {
  455. pci_remove_bus_device(dev);
  456. pci_dev_put(dev);
  457. }
  458. }
  459. }
  460. out_unlock:
  461. mutex_unlock(&asus->hotplug_lock);
  462. }
  463. static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
  464. {
  465. struct asus_wmi *asus = data;
  466. if (event != ACPI_NOTIFY_BUS_CHECK)
  467. return;
  468. /*
  469. * We can't call directly asus_rfkill_hotplug because most
  470. * of the time WMBC is still being executed and not reetrant.
  471. * There is currently no way to tell ACPICA that we want this
  472. * method to be serialized, we schedule a asus_rfkill_hotplug
  473. * call later, in a safer context.
  474. */
  475. queue_work(asus->hotplug_workqueue, &asus->hotplug_work);
  476. }
  477. static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
  478. {
  479. acpi_status status;
  480. acpi_handle handle;
  481. status = acpi_get_handle(NULL, node, &handle);
  482. if (ACPI_SUCCESS(status)) {
  483. status = acpi_install_notify_handler(handle,
  484. ACPI_SYSTEM_NOTIFY,
  485. asus_rfkill_notify, asus);
  486. if (ACPI_FAILURE(status))
  487. pr_warn("Failed to register notify on %s\n", node);
  488. } else
  489. return -ENODEV;
  490. return 0;
  491. }
  492. static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
  493. {
  494. acpi_status status = AE_OK;
  495. acpi_handle handle;
  496. status = acpi_get_handle(NULL, node, &handle);
  497. if (ACPI_SUCCESS(status)) {
  498. status = acpi_remove_notify_handler(handle,
  499. ACPI_SYSTEM_NOTIFY,
  500. asus_rfkill_notify);
  501. if (ACPI_FAILURE(status))
  502. pr_err("Error removing rfkill notify handler %s\n",
  503. node);
  504. }
  505. }
  506. static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
  507. u8 *value)
  508. {
  509. struct asus_wmi *asus = hotplug_slot->private;
  510. int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
  511. if (result < 0)
  512. return result;
  513. *value = !!result;
  514. return 0;
  515. }
  516. static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
  517. {
  518. kfree(hotplug_slot->info);
  519. kfree(hotplug_slot);
  520. }
  521. static struct hotplug_slot_ops asus_hotplug_slot_ops = {
  522. .owner = THIS_MODULE,
  523. .get_adapter_status = asus_get_adapter_status,
  524. .get_power_status = asus_get_adapter_status,
  525. };
  526. static void asus_hotplug_work(struct work_struct *work)
  527. {
  528. struct asus_wmi *asus;
  529. asus = container_of(work, struct asus_wmi, hotplug_work);
  530. asus_rfkill_hotplug(asus);
  531. }
  532. static int asus_setup_pci_hotplug(struct asus_wmi *asus)
  533. {
  534. int ret = -ENOMEM;
  535. struct pci_bus *bus = pci_find_bus(0, 1);
  536. if (!bus) {
  537. pr_err("Unable to find wifi PCI bus\n");
  538. return -ENODEV;
  539. }
  540. asus->hotplug_workqueue =
  541. create_singlethread_workqueue("hotplug_workqueue");
  542. if (!asus->hotplug_workqueue)
  543. goto error_workqueue;
  544. INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
  545. asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
  546. if (!asus->hotplug_slot)
  547. goto error_slot;
  548. asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
  549. GFP_KERNEL);
  550. if (!asus->hotplug_slot->info)
  551. goto error_info;
  552. asus->hotplug_slot->private = asus;
  553. asus->hotplug_slot->release = &asus_cleanup_pci_hotplug;
  554. asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
  555. asus_get_adapter_status(asus->hotplug_slot,
  556. &asus->hotplug_slot->info->adapter_status);
  557. ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
  558. if (ret) {
  559. pr_err("Unable to register hotplug slot - %d\n", ret);
  560. goto error_register;
  561. }
  562. return 0;
  563. error_register:
  564. kfree(asus->hotplug_slot->info);
  565. error_info:
  566. kfree(asus->hotplug_slot);
  567. asus->hotplug_slot = NULL;
  568. error_slot:
  569. destroy_workqueue(asus->hotplug_workqueue);
  570. error_workqueue:
  571. return ret;
  572. }
  573. /*
  574. * Rfkill devices
  575. */
  576. static int asus_rfkill_set(void *data, bool blocked)
  577. {
  578. struct asus_rfkill *priv = data;
  579. u32 ctrl_param = !blocked;
  580. return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL);
  581. }
  582. static void asus_rfkill_query(struct rfkill *rfkill, void *data)
  583. {
  584. struct asus_rfkill *priv = data;
  585. int result;
  586. result = asus_wmi_get_devstate_simple(priv->asus, priv->dev_id);
  587. if (result < 0)
  588. return;
  589. rfkill_set_sw_state(priv->rfkill, !result);
  590. }
  591. static int asus_rfkill_wlan_set(void *data, bool blocked)
  592. {
  593. struct asus_rfkill *priv = data;
  594. struct asus_wmi *asus = priv->asus;
  595. int ret;
  596. /*
  597. * This handler is enabled only if hotplug is enabled.
  598. * In this case, the asus_wmi_set_devstate() will
  599. * trigger a wmi notification and we need to wait
  600. * this call to finish before being able to call
  601. * any wmi method
  602. */
  603. mutex_lock(&asus->wmi_lock);
  604. ret = asus_rfkill_set(data, blocked);
  605. mutex_unlock(&asus->wmi_lock);
  606. return ret;
  607. }
  608. static const struct rfkill_ops asus_rfkill_wlan_ops = {
  609. .set_block = asus_rfkill_wlan_set,
  610. .query = asus_rfkill_query,
  611. };
  612. static const struct rfkill_ops asus_rfkill_ops = {
  613. .set_block = asus_rfkill_set,
  614. .query = asus_rfkill_query,
  615. };
  616. static int asus_new_rfkill(struct asus_wmi *asus,
  617. struct asus_rfkill *arfkill,
  618. const char *name, enum rfkill_type type, int dev_id)
  619. {
  620. int result = asus_wmi_get_devstate_simple(asus, dev_id);
  621. struct rfkill **rfkill = &arfkill->rfkill;
  622. if (result < 0)
  623. return result;
  624. arfkill->dev_id = dev_id;
  625. arfkill->asus = asus;
  626. if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless)
  627. *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
  628. &asus_rfkill_wlan_ops, arfkill);
  629. else
  630. *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
  631. &asus_rfkill_ops, arfkill);
  632. if (!*rfkill)
  633. return -EINVAL;
  634. rfkill_init_sw_state(*rfkill, !result);
  635. result = rfkill_register(*rfkill);
  636. if (result) {
  637. rfkill_destroy(*rfkill);
  638. *rfkill = NULL;
  639. return result;
  640. }
  641. return 0;
  642. }
  643. static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
  644. {
  645. asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
  646. asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
  647. asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
  648. if (asus->wlan.rfkill) {
  649. rfkill_unregister(asus->wlan.rfkill);
  650. rfkill_destroy(asus->wlan.rfkill);
  651. asus->wlan.rfkill = NULL;
  652. }
  653. /*
  654. * Refresh pci hotplug in case the rfkill state was changed after
  655. * asus_unregister_rfkill_notifier()
  656. */
  657. asus_rfkill_hotplug(asus);
  658. if (asus->hotplug_slot)
  659. pci_hp_deregister(asus->hotplug_slot);
  660. if (asus->hotplug_workqueue)
  661. destroy_workqueue(asus->hotplug_workqueue);
  662. if (asus->bluetooth.rfkill) {
  663. rfkill_unregister(asus->bluetooth.rfkill);
  664. rfkill_destroy(asus->bluetooth.rfkill);
  665. asus->bluetooth.rfkill = NULL;
  666. }
  667. if (asus->wimax.rfkill) {
  668. rfkill_unregister(asus->wimax.rfkill);
  669. rfkill_destroy(asus->wimax.rfkill);
  670. asus->wimax.rfkill = NULL;
  671. }
  672. if (asus->wwan3g.rfkill) {
  673. rfkill_unregister(asus->wwan3g.rfkill);
  674. rfkill_destroy(asus->wwan3g.rfkill);
  675. asus->wwan3g.rfkill = NULL;
  676. }
  677. }
  678. static int asus_wmi_rfkill_init(struct asus_wmi *asus)
  679. {
  680. int result = 0;
  681. mutex_init(&asus->hotplug_lock);
  682. mutex_init(&asus->wmi_lock);
  683. result = asus_new_rfkill(asus, &asus->wlan, "asus-wlan",
  684. RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN);
  685. if (result && result != -ENODEV)
  686. goto exit;
  687. result = asus_new_rfkill(asus, &asus->bluetooth,
  688. "asus-bluetooth", RFKILL_TYPE_BLUETOOTH,
  689. ASUS_WMI_DEVID_BLUETOOTH);
  690. if (result && result != -ENODEV)
  691. goto exit;
  692. result = asus_new_rfkill(asus, &asus->wimax, "asus-wimax",
  693. RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX);
  694. if (result && result != -ENODEV)
  695. goto exit;
  696. result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g",
  697. RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G);
  698. if (result && result != -ENODEV)
  699. goto exit;
  700. if (!asus->driver->hotplug_wireless)
  701. goto exit;
  702. result = asus_setup_pci_hotplug(asus);
  703. /*
  704. * If we get -EBUSY then something else is handling the PCI hotplug -
  705. * don't fail in this case
  706. */
  707. if (result == -EBUSY)
  708. result = 0;
  709. asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
  710. asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
  711. asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
  712. /*
  713. * Refresh pci hotplug in case the rfkill state was changed during
  714. * setup.
  715. */
  716. asus_rfkill_hotplug(asus);
  717. exit:
  718. if (result && result != -ENODEV)
  719. asus_wmi_rfkill_exit(asus);
  720. if (result == -ENODEV)
  721. result = 0;
  722. return result;
  723. }
  724. /*
  725. * Hwmon device
  726. */
  727. static ssize_t asus_hwmon_pwm1(struct device *dev,
  728. struct device_attribute *attr,
  729. char *buf)
  730. {
  731. struct asus_wmi *asus = dev_get_drvdata(dev);
  732. u32 value;
  733. int err;
  734. err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
  735. if (err < 0)
  736. return err;
  737. value &= 0xFF;
  738. if (value == 1) /* Low Speed */
  739. value = 85;
  740. else if (value == 2)
  741. value = 170;
  742. else if (value == 3)
  743. value = 255;
  744. else if (value != 0) {
  745. pr_err("Unknown fan speed %#x", value);
  746. value = -1;
  747. }
  748. return sprintf(buf, "%d\n", value);
  749. }
  750. static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0);
  751. static ssize_t
  752. show_name(struct device *dev, struct device_attribute *attr, char *buf)
  753. {
  754. return sprintf(buf, "asus\n");
  755. }
  756. static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
  757. static struct attribute *hwmon_attributes[] = {
  758. &sensor_dev_attr_pwm1.dev_attr.attr,
  759. &sensor_dev_attr_name.dev_attr.attr,
  760. NULL
  761. };
  762. static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
  763. struct attribute *attr, int idx)
  764. {
  765. struct device *dev = container_of(kobj, struct device, kobj);
  766. struct platform_device *pdev = to_platform_device(dev->parent);
  767. struct asus_wmi *asus = platform_get_drvdata(pdev);
  768. bool ok = true;
  769. int dev_id = -1;
  770. u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
  771. if (attr == &sensor_dev_attr_pwm1.dev_attr.attr)
  772. dev_id = ASUS_WMI_DEVID_FAN_CTRL;
  773. if (dev_id != -1) {
  774. int err = asus_wmi_get_devstate(asus, dev_id, &value);
  775. if (err < 0)
  776. return 0; /* can't return negative here */
  777. }
  778. if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) {
  779. /*
  780. * We need to find a better way, probably using sfun,
  781. * bits or spec ...
  782. * Currently we disable it if:
  783. * - ASUS_WMI_UNSUPPORTED_METHOD is returned
  784. * - reverved bits are non-zero
  785. * - sfun and presence bit are not set
  786. */
  787. if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
  788. || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
  789. ok = false;
  790. }
  791. return ok ? attr->mode : 0;
  792. }
  793. static struct attribute_group hwmon_attribute_group = {
  794. .is_visible = asus_hwmon_sysfs_is_visible,
  795. .attrs = hwmon_attributes
  796. };
  797. static void asus_wmi_hwmon_exit(struct asus_wmi *asus)
  798. {
  799. struct device *hwmon;
  800. hwmon = asus->hwmon_device;
  801. if (!hwmon)
  802. return;
  803. sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group);
  804. hwmon_device_unregister(hwmon);
  805. asus->hwmon_device = NULL;
  806. }
  807. static int asus_wmi_hwmon_init(struct asus_wmi *asus)
  808. {
  809. struct device *hwmon;
  810. int result;
  811. hwmon = hwmon_device_register(&asus->platform_device->dev);
  812. if (IS_ERR(hwmon)) {
  813. pr_err("Could not register asus hwmon device\n");
  814. return PTR_ERR(hwmon);
  815. }
  816. dev_set_drvdata(hwmon, asus);
  817. asus->hwmon_device = hwmon;
  818. result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group);
  819. if (result)
  820. asus_wmi_hwmon_exit(asus);
  821. return result;
  822. }
  823. /*
  824. * Backlight
  825. */
  826. static int read_backlight_power(struct asus_wmi *asus)
  827. {
  828. int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT);
  829. if (ret < 0)
  830. return ret;
  831. return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
  832. }
  833. static int read_brightness_max(struct asus_wmi *asus)
  834. {
  835. u32 retval;
  836. int err;
  837. err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
  838. if (err < 0)
  839. return err;
  840. retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK;
  841. retval >>= 8;
  842. if (!retval)
  843. return -ENODEV;
  844. return retval;
  845. }
  846. static int read_brightness(struct backlight_device *bd)
  847. {
  848. struct asus_wmi *asus = bl_get_data(bd);
  849. u32 retval;
  850. int err;
  851. err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
  852. if (err < 0)
  853. return err;
  854. return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
  855. }
  856. static int update_bl_status(struct backlight_device *bd)
  857. {
  858. struct asus_wmi *asus = bl_get_data(bd);
  859. u32 ctrl_param;
  860. int power, err;
  861. ctrl_param = bd->props.brightness;
  862. err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
  863. ctrl_param, NULL);
  864. if (err < 0)
  865. return err;
  866. power = read_backlight_power(asus);
  867. if (power != -ENODEV && bd->props.power != power) {
  868. ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
  869. err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
  870. ctrl_param, NULL);
  871. }
  872. return err;
  873. }
  874. static const struct backlight_ops asus_wmi_bl_ops = {
  875. .get_brightness = read_brightness,
  876. .update_status = update_bl_status,
  877. };
  878. static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code)
  879. {
  880. struct backlight_device *bd = asus->backlight_device;
  881. int old = bd->props.brightness;
  882. int new = old;
  883. if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
  884. new = code - NOTIFY_BRNUP_MIN + 1;
  885. else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
  886. new = code - NOTIFY_BRNDOWN_MIN;
  887. bd->props.brightness = new;
  888. backlight_update_status(bd);
  889. backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
  890. return old;
  891. }
  892. static int asus_wmi_backlight_init(struct asus_wmi *asus)
  893. {
  894. struct backlight_device *bd;
  895. struct backlight_properties props;
  896. int max;
  897. int power;
  898. max = read_brightness_max(asus);
  899. if (max == -ENODEV)
  900. max = 0;
  901. else if (max < 0)
  902. return max;
  903. power = read_backlight_power(asus);
  904. if (power == -ENODEV)
  905. power = FB_BLANK_UNBLANK;
  906. else if (power < 0)
  907. return power;
  908. memset(&props, 0, sizeof(struct backlight_properties));
  909. props.type = BACKLIGHT_PLATFORM;
  910. props.max_brightness = max;
  911. bd = backlight_device_register(asus->driver->name,
  912. &asus->platform_device->dev, asus,
  913. &asus_wmi_bl_ops, &props);
  914. if (IS_ERR(bd)) {
  915. pr_err("Could not register backlight device\n");
  916. return PTR_ERR(bd);
  917. }
  918. asus->backlight_device = bd;
  919. bd->props.brightness = read_brightness(bd);
  920. bd->props.power = power;
  921. backlight_update_status(bd);
  922. return 0;
  923. }
  924. static void asus_wmi_backlight_exit(struct asus_wmi *asus)
  925. {
  926. if (asus->backlight_device)
  927. backlight_device_unregister(asus->backlight_device);
  928. asus->backlight_device = NULL;
  929. }
  930. static void asus_wmi_notify(u32 value, void *context)
  931. {
  932. struct asus_wmi *asus = context;
  933. struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
  934. union acpi_object *obj;
  935. acpi_status status;
  936. int code;
  937. int orig_code;
  938. unsigned int key_value = 1;
  939. bool autorelease = 1;
  940. status = wmi_get_event_data(value, &response);
  941. if (status != AE_OK) {
  942. pr_err("bad event status 0x%x\n", status);
  943. return;
  944. }
  945. obj = (union acpi_object *)response.pointer;
  946. if (!obj || obj->type != ACPI_TYPE_INTEGER)
  947. goto exit;
  948. code = obj->integer.value;
  949. orig_code = code;
  950. if (asus->driver->key_filter) {
  951. asus->driver->key_filter(asus->driver, &code, &key_value,
  952. &autorelease);
  953. if (code == ASUS_WMI_KEY_IGNORE)
  954. goto exit;
  955. }
  956. if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
  957. code = NOTIFY_BRNUP_MIN;
  958. else if (code >= NOTIFY_BRNDOWN_MIN &&
  959. code <= NOTIFY_BRNDOWN_MAX)
  960. code = NOTIFY_BRNDOWN_MIN;
  961. if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
  962. if (!acpi_video_backlight_support())
  963. asus_wmi_backlight_notify(asus, orig_code);
  964. } else if (!sparse_keymap_report_event(asus->inputdev, code,
  965. key_value, autorelease))
  966. pr_info("Unknown key %x pressed\n", code);
  967. exit:
  968. kfree(obj);
  969. }
  970. /*
  971. * Sys helpers
  972. */
  973. static int parse_arg(const char *buf, unsigned long count, int *val)
  974. {
  975. if (!count)
  976. return 0;
  977. if (sscanf(buf, "%i", val) != 1)
  978. return -EINVAL;
  979. return count;
  980. }
  981. static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
  982. const char *buf, size_t count)
  983. {
  984. u32 retval;
  985. int rv, err, value;
  986. value = asus_wmi_get_devstate_simple(asus, devid);
  987. if (value == -ENODEV) /* Check device presence */
  988. return value;
  989. rv = parse_arg(buf, count, &value);
  990. err = asus_wmi_set_devstate(devid, value, &retval);
  991. if (err < 0)
  992. return err;
  993. return rv;
  994. }
  995. static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
  996. {
  997. int value = asus_wmi_get_devstate_simple(asus, devid);
  998. if (value < 0)
  999. return value;
  1000. return sprintf(buf, "%d\n", value);
  1001. }
  1002. #define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
  1003. static ssize_t show_##_name(struct device *dev, \
  1004. struct device_attribute *attr, \
  1005. char *buf) \
  1006. { \
  1007. struct asus_wmi *asus = dev_get_drvdata(dev); \
  1008. \
  1009. return show_sys_wmi(asus, _cm, buf); \
  1010. } \
  1011. static ssize_t store_##_name(struct device *dev, \
  1012. struct device_attribute *attr, \
  1013. const char *buf, size_t count) \
  1014. { \
  1015. struct asus_wmi *asus = dev_get_drvdata(dev); \
  1016. \
  1017. return store_sys_wmi(asus, _cm, buf, count); \
  1018. } \
  1019. static struct device_attribute dev_attr_##_name = { \
  1020. .attr = { \
  1021. .name = __stringify(_name), \
  1022. .mode = _mode }, \
  1023. .show = show_##_name, \
  1024. .store = store_##_name, \
  1025. }
  1026. ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD);
  1027. ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA);
  1028. ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER);
  1029. static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
  1030. const char *buf, size_t count)
  1031. {
  1032. int value;
  1033. if (!count || sscanf(buf, "%i", &value) != 1)
  1034. return -EINVAL;
  1035. if (value < 0 || value > 2)
  1036. return -EINVAL;
  1037. return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL);
  1038. }
  1039. static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
  1040. static struct attribute *platform_attributes[] = {
  1041. &dev_attr_cpufv.attr,
  1042. &dev_attr_camera.attr,
  1043. &dev_attr_cardr.attr,
  1044. &dev_attr_touchpad.attr,
  1045. NULL
  1046. };
  1047. static mode_t asus_sysfs_is_visible(struct kobject *kobj,
  1048. struct attribute *attr, int idx)
  1049. {
  1050. struct device *dev = container_of(kobj, struct device, kobj);
  1051. struct platform_device *pdev = to_platform_device(dev);
  1052. struct asus_wmi *asus = platform_get_drvdata(pdev);
  1053. bool ok = true;
  1054. int devid = -1;
  1055. if (attr == &dev_attr_camera.attr)
  1056. devid = ASUS_WMI_DEVID_CAMERA;
  1057. else if (attr == &dev_attr_cardr.attr)
  1058. devid = ASUS_WMI_DEVID_CARDREADER;
  1059. else if (attr == &dev_attr_touchpad.attr)
  1060. devid = ASUS_WMI_DEVID_TOUCHPAD;
  1061. if (devid != -1)
  1062. ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
  1063. return ok ? attr->mode : 0;
  1064. }
  1065. static struct attribute_group platform_attribute_group = {
  1066. .is_visible = asus_sysfs_is_visible,
  1067. .attrs = platform_attributes
  1068. };
  1069. static void asus_wmi_sysfs_exit(struct platform_device *device)
  1070. {
  1071. sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
  1072. }
  1073. static int asus_wmi_sysfs_init(struct platform_device *device)
  1074. {
  1075. return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
  1076. }
  1077. /*
  1078. * Platform device
  1079. */
  1080. static int asus_wmi_platform_init(struct asus_wmi *asus)
  1081. {
  1082. int rv;
  1083. /* INIT enable hotkeys on some models */
  1084. if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
  1085. pr_info("Initialization: %#x", rv);
  1086. /* We don't know yet what to do with this version... */
  1087. if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
  1088. pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF);
  1089. asus->spec = rv;
  1090. }
  1091. /*
  1092. * The SFUN method probably allows the original driver to get the list
  1093. * of features supported by a given model. For now, 0x0100 or 0x0800
  1094. * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
  1095. * The significance of others is yet to be found.
  1096. */
  1097. if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
  1098. pr_info("SFUN value: %#x", rv);
  1099. asus->sfun = rv;
  1100. }
  1101. /*
  1102. * Eee PC and Notebooks seems to have different method_id for DSTS,
  1103. * but it may also be related to the BIOS's SPEC.
  1104. * Note, on most Eeepc, there is no way to check if a method exist
  1105. * or note, while on notebooks, they returns 0xFFFFFFFE on failure,
  1106. * but once again, SPEC may probably be used for that kind of things.
  1107. */
  1108. if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL))
  1109. asus->dsts_id = ASUS_WMI_METHODID_DSTS;
  1110. else if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, 0, 0, NULL))
  1111. asus->dsts_id = ASUS_WMI_METHODID_DSTS2;
  1112. if (!asus->dsts_id) {
  1113. pr_err("Can't find DSTS");
  1114. return -ENODEV;
  1115. }
  1116. return asus_wmi_sysfs_init(asus->platform_device);
  1117. }
  1118. static void asus_wmi_platform_exit(struct asus_wmi *asus)
  1119. {
  1120. asus_wmi_sysfs_exit(asus->platform_device);
  1121. }
  1122. /*
  1123. * debugfs
  1124. */
  1125. struct asus_wmi_debugfs_node {
  1126. struct asus_wmi *asus;
  1127. char *name;
  1128. int (*show) (struct seq_file *m, void *data);
  1129. };
  1130. static int show_dsts(struct seq_file *m, void *data)
  1131. {
  1132. struct asus_wmi *asus = m->private;
  1133. int err;
  1134. u32 retval = -1;
  1135. err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
  1136. if (err < 0)
  1137. return err;
  1138. seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval);
  1139. return 0;
  1140. }
  1141. static int show_devs(struct seq_file *m, void *data)
  1142. {
  1143. struct asus_wmi *asus = m->private;
  1144. int err;
  1145. u32 retval = -1;
  1146. err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
  1147. &retval);
  1148. if (err < 0)
  1149. return err;
  1150. seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id,
  1151. asus->debug.ctrl_param, retval);
  1152. return 0;
  1153. }
  1154. static int show_call(struct seq_file *m, void *data)
  1155. {
  1156. struct asus_wmi *asus = m->private;
  1157. struct bios_args args = {
  1158. .arg0 = asus->debug.dev_id,
  1159. .arg1 = asus->debug.ctrl_param,
  1160. };
  1161. struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
  1162. struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
  1163. union acpi_object *obj;
  1164. acpi_status status;
  1165. status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
  1166. 1, asus->debug.method_id,
  1167. &input, &output);
  1168. if (ACPI_FAILURE(status))
  1169. return -EIO;
  1170. obj = (union acpi_object *)output.pointer;
  1171. if (obj && obj->type == ACPI_TYPE_INTEGER)
  1172. seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id,
  1173. asus->debug.dev_id, asus->debug.ctrl_param,
  1174. (u32) obj->integer.value);
  1175. else
  1176. seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id,
  1177. asus->debug.dev_id, asus->debug.ctrl_param,
  1178. obj ? obj->type : -1);
  1179. kfree(obj);
  1180. return 0;
  1181. }
  1182. static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = {
  1183. {NULL, "devs", show_devs},
  1184. {NULL, "dsts", show_dsts},
  1185. {NULL, "call", show_call},
  1186. };
  1187. static int asus_wmi_debugfs_open(struct inode *inode, struct file *file)
  1188. {
  1189. struct asus_wmi_debugfs_node *node = inode->i_private;
  1190. return single_open(file, node->show, node->asus);
  1191. }
  1192. static const struct file_operations asus_wmi_debugfs_io_ops = {
  1193. .owner = THIS_MODULE,
  1194. .open = asus_wmi_debugfs_open,
  1195. .read = seq_read,
  1196. .llseek = seq_lseek,
  1197. .release = single_release,
  1198. };
  1199. static void asus_wmi_debugfs_exit(struct asus_wmi *asus)
  1200. {
  1201. debugfs_remove_recursive(asus->debug.root);
  1202. }
  1203. static int asus_wmi_debugfs_init(struct asus_wmi *asus)
  1204. {
  1205. struct dentry *dent;
  1206. int i;
  1207. asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
  1208. if (!asus->debug.root) {
  1209. pr_err("failed to create debugfs directory");
  1210. goto error_debugfs;
  1211. }
  1212. dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR,
  1213. asus->debug.root, &asus->debug.method_id);
  1214. if (!dent)
  1215. goto error_debugfs;
  1216. dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR,
  1217. asus->debug.root, &asus->debug.dev_id);
  1218. if (!dent)
  1219. goto error_debugfs;
  1220. dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR,
  1221. asus->debug.root, &asus->debug.ctrl_param);
  1222. if (!dent)
  1223. goto error_debugfs;
  1224. for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
  1225. struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
  1226. node->asus = asus;
  1227. dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
  1228. asus->debug.root, node,
  1229. &asus_wmi_debugfs_io_ops);
  1230. if (!dent) {
  1231. pr_err("failed to create debug file: %s\n", node->name);
  1232. goto error_debugfs;
  1233. }
  1234. }
  1235. return 0;
  1236. error_debugfs:
  1237. asus_wmi_debugfs_exit(asus);
  1238. return -ENOMEM;
  1239. }
  1240. /*
  1241. * WMI Driver
  1242. */
  1243. static int asus_wmi_add(struct platform_device *pdev)
  1244. {
  1245. struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
  1246. struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
  1247. struct asus_wmi *asus;
  1248. acpi_status status;
  1249. int err;
  1250. asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
  1251. if (!asus)
  1252. return -ENOMEM;
  1253. asus->driver = wdrv;
  1254. asus->platform_device = pdev;
  1255. wdrv->platform_device = pdev;
  1256. platform_set_drvdata(asus->platform_device, asus);
  1257. if (wdrv->quirks)
  1258. wdrv->quirks(asus->driver);
  1259. err = asus_wmi_platform_init(asus);
  1260. if (err)
  1261. goto fail_platform;
  1262. err = asus_wmi_input_init(asus);
  1263. if (err)
  1264. goto fail_input;
  1265. err = asus_wmi_hwmon_init(asus);
  1266. if (err)
  1267. goto fail_hwmon;
  1268. err = asus_wmi_led_init(asus);
  1269. if (err)
  1270. goto fail_leds;
  1271. err = asus_wmi_rfkill_init(asus);
  1272. if (err)
  1273. goto fail_rfkill;
  1274. if (!acpi_video_backlight_support()) {
  1275. err = asus_wmi_backlight_init(asus);
  1276. if (err && err != -ENODEV)
  1277. goto fail_backlight;
  1278. } else
  1279. pr_info("Backlight controlled by ACPI video driver\n");
  1280. status = wmi_install_notify_handler(asus->driver->event_guid,
  1281. asus_wmi_notify, asus);
  1282. if (ACPI_FAILURE(status)) {
  1283. pr_err("Unable to register notify handler - %d\n", status);
  1284. err = -ENODEV;
  1285. goto fail_wmi_handler;
  1286. }
  1287. err = asus_wmi_debugfs_init(asus);
  1288. if (err)
  1289. goto fail_debugfs;
  1290. return 0;
  1291. fail_debugfs:
  1292. wmi_remove_notify_handler(asus->driver->event_guid);
  1293. fail_wmi_handler:
  1294. asus_wmi_backlight_exit(asus);
  1295. fail_backlight:
  1296. asus_wmi_rfkill_exit(asus);
  1297. fail_rfkill:
  1298. asus_wmi_led_exit(asus);
  1299. fail_leds:
  1300. asus_wmi_hwmon_exit(asus);
  1301. fail_hwmon:
  1302. asus_wmi_input_exit(asus);
  1303. fail_input:
  1304. asus_wmi_platform_exit(asus);
  1305. fail_platform:
  1306. kfree(asus);
  1307. return err;
  1308. }
  1309. static int asus_wmi_remove(struct platform_device *device)
  1310. {
  1311. struct asus_wmi *asus;
  1312. asus = platform_get_drvdata(device);
  1313. wmi_remove_notify_handler(asus->driver->event_guid);
  1314. asus_wmi_backlight_exit(asus);
  1315. asus_wmi_input_exit(asus);
  1316. asus_wmi_hwmon_exit(asus);
  1317. asus_wmi_led_exit(asus);
  1318. asus_wmi_rfkill_exit(asus);
  1319. asus_wmi_debugfs_exit(asus);
  1320. asus_wmi_platform_exit(asus);
  1321. kfree(asus);
  1322. return 0;
  1323. }
  1324. /*
  1325. * Platform driver - hibernate/resume callbacks
  1326. */
  1327. static int asus_hotk_thaw(struct device *device)
  1328. {
  1329. struct asus_wmi *asus = dev_get_drvdata(device);
  1330. if (asus->wlan.rfkill) {
  1331. bool wlan;
  1332. /*
  1333. * Work around bios bug - acpi _PTS turns off the wireless led
  1334. * during suspend. Normally it restores it on resume, but
  1335. * we should kick it ourselves in case hibernation is aborted.
  1336. */
  1337. wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
  1338. asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL);
  1339. }
  1340. return 0;
  1341. }
  1342. static int asus_hotk_restore(struct device *device)
  1343. {
  1344. struct asus_wmi *asus = dev_get_drvdata(device);
  1345. int bl;
  1346. /* Refresh both wlan rfkill state and pci hotplug */
  1347. if (asus->wlan.rfkill)
  1348. asus_rfkill_hotplug(asus);
  1349. if (asus->bluetooth.rfkill) {
  1350. bl = !asus_wmi_get_devstate_simple(asus,
  1351. ASUS_WMI_DEVID_BLUETOOTH);
  1352. rfkill_set_sw_state(asus->bluetooth.rfkill, bl);
  1353. }
  1354. if (asus->wimax.rfkill) {
  1355. bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX);
  1356. rfkill_set_sw_state(asus->wimax.rfkill, bl);
  1357. }
  1358. if (asus->wwan3g.rfkill) {
  1359. bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G);
  1360. rfkill_set_sw_state(asus->wwan3g.rfkill, bl);
  1361. }
  1362. return 0;
  1363. }
  1364. static const struct dev_pm_ops asus_pm_ops = {
  1365. .thaw = asus_hotk_thaw,
  1366. .restore = asus_hotk_restore,
  1367. };
  1368. static int asus_wmi_probe(struct platform_device *pdev)
  1369. {
  1370. struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
  1371. struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
  1372. int ret;
  1373. if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
  1374. pr_warn("Management GUID not found\n");
  1375. return -ENODEV;
  1376. }
  1377. if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
  1378. pr_warn("Event GUID not found\n");
  1379. return -ENODEV;
  1380. }
  1381. if (wdrv->probe) {
  1382. ret = wdrv->probe(pdev);
  1383. if (ret)
  1384. return ret;
  1385. }
  1386. return asus_wmi_add(pdev);
  1387. }
  1388. static bool used;
  1389. int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver)
  1390. {
  1391. struct platform_driver *platform_driver;
  1392. struct platform_device *platform_device;
  1393. if (used)
  1394. return -EBUSY;
  1395. platform_driver = &driver->platform_driver;
  1396. platform_driver->remove = asus_wmi_remove;
  1397. platform_driver->driver.owner = driver->owner;
  1398. platform_driver->driver.name = driver->name;
  1399. platform_driver->driver.pm = &asus_pm_ops;
  1400. platform_device = platform_create_bundle(platform_driver,
  1401. asus_wmi_probe,
  1402. NULL, 0, NULL, 0);
  1403. if (IS_ERR(platform_device))
  1404. return PTR_ERR(platform_device);
  1405. used = true;
  1406. return 0;
  1407. }
  1408. EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
  1409. void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
  1410. {
  1411. platform_device_unregister(driver->platform_device);
  1412. platform_driver_unregister(&driver->platform_driver);
  1413. used = false;
  1414. }
  1415. EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
  1416. static int __init asus_wmi_init(void)
  1417. {
  1418. if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
  1419. pr_info("Asus Management GUID not found");
  1420. return -ENODEV;
  1421. }
  1422. pr_info("ASUS WMI generic driver loaded");
  1423. return 0;
  1424. }
  1425. static void __exit asus_wmi_exit(void)
  1426. {
  1427. pr_info("ASUS WMI generic driver unloaded");
  1428. }
  1429. module_init(asus_wmi_init);
  1430. module_exit(asus_wmi_exit);