x86-android-tablets.c 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * DMI based code to deal with broken DSDTs on X86 tablets which ship with
  4. * Android as (part of) the factory image. The factory kernels shipped on these
  5. * devices typically have a bunch of things hardcoded, rather than specified
  6. * in their DSDT.
  7. *
  8. * Copyright (C) 2021-2022 Hans de Goede <[email protected]>
  9. */
  10. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11. #include <linux/acpi.h>
  12. #include <linux/dmi.h>
  13. #include <linux/efi.h>
  14. #include <linux/gpio_keys.h>
  15. #include <linux/gpio/consumer.h>
  16. #include <linux/gpio/driver.h>
  17. #include <linux/gpio/machine.h>
  18. #include <linux/i2c.h>
  19. #include <linux/input.h>
  20. #include <linux/irq.h>
  21. #include <linux/irqdomain.h>
  22. #include <linux/module.h>
  23. #include <linux/mod_devicetable.h>
  24. #include <linux/pinctrl/consumer.h>
  25. #include <linux/pinctrl/machine.h>
  26. #include <linux/platform_data/lp855x.h>
  27. #include <linux/platform_device.h>
  28. #include <linux/power/bq24190_charger.h>
  29. #include <linux/reboot.h>
  30. #include <linux/rmi.h>
  31. #include <linux/serdev.h>
  32. #include <linux/spi/spi.h>
  33. #include <linux/string.h>
  34. /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */
  35. #include "../../gpio/gpiolib.h"
  36. #include "../../gpio/gpiolib-acpi.h"
  37. /*
  38. * Helper code to get Linux IRQ numbers given a description of the IRQ source
  39. * (either IOAPIC index, or GPIO chip name + pin-number).
  40. */
  41. enum x86_acpi_irq_type {
  42. X86_ACPI_IRQ_TYPE_NONE,
  43. X86_ACPI_IRQ_TYPE_APIC,
  44. X86_ACPI_IRQ_TYPE_GPIOINT,
  45. X86_ACPI_IRQ_TYPE_PMIC,
  46. };
  47. struct x86_acpi_irq_data {
  48. char *chip; /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */
  49. enum x86_acpi_irq_type type;
  50. enum irq_domain_bus_token domain;
  51. int index;
  52. int trigger; /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */
  53. int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */
  54. };
  55. static int gpiochip_find_match_label(struct gpio_chip *gc, void *data)
  56. {
  57. return gc->label && !strcmp(gc->label, data);
  58. }
  59. static int x86_android_tablet_get_gpiod(char *label, int pin, struct gpio_desc **desc)
  60. {
  61. struct gpio_desc *gpiod;
  62. struct gpio_chip *chip;
  63. chip = gpiochip_find(label, gpiochip_find_match_label);
  64. if (!chip) {
  65. pr_err("error cannot find GPIO chip %s\n", label);
  66. return -ENODEV;
  67. }
  68. gpiod = gpiochip_get_desc(chip, pin);
  69. if (IS_ERR(gpiod)) {
  70. pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin);
  71. return PTR_ERR(gpiod);
  72. }
  73. *desc = gpiod;
  74. return 0;
  75. }
  76. static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
  77. {
  78. struct irq_fwspec fwspec = { };
  79. struct irq_domain *domain;
  80. struct acpi_device *adev;
  81. struct gpio_desc *gpiod;
  82. unsigned int irq_type;
  83. acpi_handle handle;
  84. acpi_status status;
  85. int irq, ret;
  86. switch (data->type) {
  87. case X86_ACPI_IRQ_TYPE_APIC:
  88. /*
  89. * The DSDT may already reference the GSI in a device skipped by
  90. * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
  91. * to avoid EBUSY errors in this case.
  92. */
  93. acpi_unregister_gsi(data->index);
  94. irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
  95. if (irq < 0)
  96. pr_err("error %d getting APIC IRQ %d\n", irq, data->index);
  97. return irq;
  98. case X86_ACPI_IRQ_TYPE_GPIOINT:
  99. /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */
  100. ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod);
  101. if (ret)
  102. return ret;
  103. irq = gpiod_to_irq(gpiod);
  104. if (irq < 0) {
  105. pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index);
  106. return irq;
  107. }
  108. irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity);
  109. if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq))
  110. irq_set_irq_type(irq, irq_type);
  111. return irq;
  112. case X86_ACPI_IRQ_TYPE_PMIC:
  113. status = acpi_get_handle(NULL, data->chip, &handle);
  114. if (ACPI_FAILURE(status)) {
  115. pr_err("error could not get %s handle\n", data->chip);
  116. return -ENODEV;
  117. }
  118. adev = acpi_fetch_acpi_dev(handle);
  119. if (!adev) {
  120. pr_err("error could not get %s adev\n", data->chip);
  121. return -ENODEV;
  122. }
  123. fwspec.fwnode = acpi_fwnode_handle(adev);
  124. domain = irq_find_matching_fwspec(&fwspec, data->domain);
  125. if (!domain) {
  126. pr_err("error could not find IRQ domain for %s\n", data->chip);
  127. return -ENODEV;
  128. }
  129. return irq_create_mapping(domain, data->index);
  130. default:
  131. return 0;
  132. }
  133. }
  134. struct x86_i2c_client_info {
  135. struct i2c_board_info board_info;
  136. char *adapter_path;
  137. struct x86_acpi_irq_data irq_data;
  138. };
  139. struct x86_serdev_info {
  140. const char *ctrl_hid;
  141. const char *ctrl_uid;
  142. const char *ctrl_devname;
  143. /*
  144. * ATM the serdev core only supports of or ACPI matching; and sofar all
  145. * Android x86 tablets DSDTs have usable serdev nodes, but sometimes
  146. * under the wrong controller. So we just tie the existing serdev ACPI
  147. * node to the right controller.
  148. */
  149. const char *serdev_hid;
  150. };
  151. struct x86_dev_info {
  152. char *invalid_aei_gpiochip;
  153. const char * const *modules;
  154. const struct software_node *bat_swnode;
  155. struct gpiod_lookup_table * const *gpiod_lookup_tables;
  156. const struct x86_i2c_client_info *i2c_client_info;
  157. const struct platform_device_info *pdev_info;
  158. const struct x86_serdev_info *serdev_info;
  159. int i2c_client_count;
  160. int pdev_count;
  161. int serdev_count;
  162. int (*init)(void);
  163. void (*exit)(void);
  164. };
  165. /* Generic / shared charger / battery settings */
  166. static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" };
  167. static const char * const bq24190_psy[] = { "bq24190-charger" };
  168. static const char * const bq25890_psy[] = { "bq25890-charger" };
  169. static const struct property_entry fg_bq24190_supply_props[] = {
  170. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
  171. { }
  172. };
  173. static const struct software_node fg_bq24190_supply_node = {
  174. .properties = fg_bq24190_supply_props,
  175. };
  176. static const struct property_entry fg_bq25890_supply_props[] = {
  177. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy),
  178. { }
  179. };
  180. static const struct software_node fg_bq25890_supply_node = {
  181. .properties = fg_bq25890_supply_props,
  182. };
  183. /* LiPo HighVoltage (max 4.35V) settings used by most devs with a HV bat. */
  184. static const struct property_entry generic_lipo_hv_4v35_battery_props[] = {
  185. PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
  186. PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion"),
  187. PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
  188. PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
  189. PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 1856000),
  190. PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4352000),
  191. PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
  192. { }
  193. };
  194. static const struct software_node generic_lipo_hv_4v35_battery_node = {
  195. .properties = generic_lipo_hv_4v35_battery_props,
  196. };
  197. /* For enabling the bq24190 5V boost based on id-pin */
  198. static struct regulator_consumer_supply intel_int3496_consumer = {
  199. .supply = "vbus",
  200. .dev_name = "intel-int3496",
  201. };
  202. static const struct regulator_init_data bq24190_vbus_init_data = {
  203. .constraints = {
  204. .name = "bq24190_vbus",
  205. .valid_ops_mask = REGULATOR_CHANGE_STATUS,
  206. },
  207. .consumer_supplies = &intel_int3496_consumer,
  208. .num_consumer_supplies = 1,
  209. };
  210. static struct bq24190_platform_data bq24190_pdata = {
  211. .regulator_init_data = &bq24190_vbus_init_data,
  212. };
  213. static const char * const bq24190_modules[] __initconst = {
  214. "intel_crystal_cove_charger", /* For the bq24190 IRQ */
  215. "bq24190_charger", /* For the Vbus regulator for intel-int3496 */
  216. NULL
  217. };
  218. /* Generic pdevs array and gpio-lookups for micro USB ID pin handling */
  219. static const struct platform_device_info int3496_pdevs[] __initconst = {
  220. {
  221. /* For micro USB ID pin handling */
  222. .name = "intel-int3496",
  223. .id = PLATFORM_DEVID_NONE,
  224. },
  225. };
  226. static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
  227. .dev_id = "intel-int3496",
  228. .table = {
  229. GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH),
  230. { }
  231. },
  232. };
  233. static struct gpiod_lookup_table int3496_reference_gpios = {
  234. .dev_id = "intel-int3496",
  235. .table = {
  236. GPIO_LOOKUP("INT33FC:01", 15, "vbus", GPIO_ACTIVE_HIGH),
  237. GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH),
  238. GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH),
  239. { }
  240. },
  241. };
  242. /* Acer Iconia One 7 B1-750 has an Android factory img with everything hardcoded */
  243. static const char * const acer_b1_750_mount_matrix[] = {
  244. "-1", "0", "0",
  245. "0", "1", "0",
  246. "0", "0", "1"
  247. };
  248. static const struct property_entry acer_b1_750_bma250e_props[] = {
  249. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", acer_b1_750_mount_matrix),
  250. { }
  251. };
  252. static const struct software_node acer_b1_750_bma250e_node = {
  253. .properties = acer_b1_750_bma250e_props,
  254. };
  255. static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = {
  256. {
  257. /* Novatek NVT-ts touchscreen */
  258. .board_info = {
  259. .type = "NVT-ts",
  260. .addr = 0x34,
  261. .dev_name = "NVT-ts",
  262. },
  263. .adapter_path = "\\_SB_.I2C4",
  264. .irq_data = {
  265. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  266. .chip = "INT33FC:02",
  267. .index = 3,
  268. .trigger = ACPI_EDGE_SENSITIVE,
  269. .polarity = ACPI_ACTIVE_LOW,
  270. },
  271. }, {
  272. /* BMA250E accelerometer */
  273. .board_info = {
  274. .type = "bma250e",
  275. .addr = 0x18,
  276. .swnode = &acer_b1_750_bma250e_node,
  277. },
  278. .adapter_path = "\\_SB_.I2C3",
  279. .irq_data = {
  280. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  281. .chip = "INT33FC:02",
  282. .index = 25,
  283. .trigger = ACPI_LEVEL_SENSITIVE,
  284. .polarity = ACPI_ACTIVE_HIGH,
  285. },
  286. },
  287. };
  288. static struct gpiod_lookup_table acer_b1_750_goodix_gpios = {
  289. .dev_id = "i2c-NVT-ts",
  290. .table = {
  291. GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW),
  292. { }
  293. },
  294. };
  295. static struct gpiod_lookup_table * const acer_b1_750_gpios[] = {
  296. &acer_b1_750_goodix_gpios,
  297. &int3496_reference_gpios,
  298. NULL
  299. };
  300. static const struct x86_dev_info acer_b1_750_info __initconst = {
  301. .i2c_client_info = acer_b1_750_i2c_clients,
  302. .i2c_client_count = ARRAY_SIZE(acer_b1_750_i2c_clients),
  303. .pdev_info = int3496_pdevs,
  304. .pdev_count = ARRAY_SIZE(int3496_pdevs),
  305. .gpiod_lookup_tables = acer_b1_750_gpios,
  306. };
  307. /*
  308. * Advantech MICA-071
  309. * This is a standard Windows tablet, but it has an extra "quick launch" button
  310. * which is not described in the ACPI tables in anyway.
  311. * Use the x86-android-tablets infra to create a gpio-button device for this.
  312. */
  313. static struct gpio_keys_button advantech_mica_071_button = {
  314. .code = KEY_PROG1,
  315. /* .gpio gets filled in by advantech_mica_071_init() */
  316. .active_low = true,
  317. .desc = "prog1_key",
  318. .type = EV_KEY,
  319. .wakeup = false,
  320. .debounce_interval = 50,
  321. };
  322. static const struct gpio_keys_platform_data advantech_mica_071_button_pdata __initconst = {
  323. .buttons = &advantech_mica_071_button,
  324. .nbuttons = 1,
  325. .name = "prog1_key",
  326. };
  327. static const struct platform_device_info advantech_mica_071_pdevs[] __initconst = {
  328. {
  329. .name = "gpio-keys",
  330. .id = PLATFORM_DEVID_AUTO,
  331. .data = &advantech_mica_071_button_pdata,
  332. .size_data = sizeof(advantech_mica_071_button_pdata),
  333. },
  334. };
  335. static int __init advantech_mica_071_init(void)
  336. {
  337. struct gpio_desc *gpiod;
  338. int ret;
  339. ret = x86_android_tablet_get_gpiod("INT33FC:00", 2, &gpiod);
  340. if (ret < 0)
  341. return ret;
  342. advantech_mica_071_button.gpio = desc_to_gpio(gpiod);
  343. return 0;
  344. }
  345. static const struct x86_dev_info advantech_mica_071_info __initconst = {
  346. .pdev_info = advantech_mica_071_pdevs,
  347. .pdev_count = ARRAY_SIZE(advantech_mica_071_pdevs),
  348. .init = advantech_mica_071_init,
  349. };
  350. /* Asus ME176C and TF103C tablets shared data */
  351. static struct gpio_keys_button asus_me176c_tf103c_lid = {
  352. .code = SW_LID,
  353. /* .gpio gets filled in by asus_me176c_tf103c_init() */
  354. .active_low = true,
  355. .desc = "lid_sw",
  356. .type = EV_SW,
  357. .wakeup = true,
  358. .debounce_interval = 50,
  359. };
  360. static const struct gpio_keys_platform_data asus_me176c_tf103c_lid_pdata __initconst = {
  361. .buttons = &asus_me176c_tf103c_lid,
  362. .nbuttons = 1,
  363. .name = "lid_sw",
  364. };
  365. static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = {
  366. {
  367. .name = "gpio-keys",
  368. .id = PLATFORM_DEVID_AUTO,
  369. .data = &asus_me176c_tf103c_lid_pdata,
  370. .size_data = sizeof(asus_me176c_tf103c_lid_pdata),
  371. },
  372. {
  373. /* For micro USB ID pin handling */
  374. .name = "intel-int3496",
  375. .id = PLATFORM_DEVID_NONE,
  376. },
  377. };
  378. static int __init asus_me176c_tf103c_init(void)
  379. {
  380. struct gpio_desc *gpiod;
  381. int ret;
  382. ret = x86_android_tablet_get_gpiod("INT33FC:02", 12, &gpiod);
  383. if (ret < 0)
  384. return ret;
  385. asus_me176c_tf103c_lid.gpio = desc_to_gpio(gpiod);
  386. return 0;
  387. }
  388. /* Asus ME176C tablets have an Android factory img with everything hardcoded */
  389. static const char * const asus_me176c_accel_mount_matrix[] = {
  390. "-1", "0", "0",
  391. "0", "1", "0",
  392. "0", "0", "1"
  393. };
  394. static const struct property_entry asus_me176c_accel_props[] = {
  395. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix),
  396. { }
  397. };
  398. static const struct software_node asus_me176c_accel_node = {
  399. .properties = asus_me176c_accel_props,
  400. };
  401. static const struct property_entry asus_me176c_bq24190_props[] = {
  402. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
  403. PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
  404. PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
  405. PROPERTY_ENTRY_BOOL("omit-battery-class"),
  406. PROPERTY_ENTRY_BOOL("disable-reset"),
  407. { }
  408. };
  409. static const struct software_node asus_me176c_bq24190_node = {
  410. .properties = asus_me176c_bq24190_props,
  411. };
  412. static const struct property_entry asus_me176c_ug3105_props[] = {
  413. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
  414. PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
  415. PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000),
  416. { }
  417. };
  418. static const struct software_node asus_me176c_ug3105_node = {
  419. .properties = asus_me176c_ug3105_props,
  420. };
  421. static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = {
  422. {
  423. /* bq24297 battery charger */
  424. .board_info = {
  425. .type = "bq24190",
  426. .addr = 0x6b,
  427. .dev_name = "bq24297",
  428. .swnode = &asus_me176c_bq24190_node,
  429. .platform_data = &bq24190_pdata,
  430. },
  431. .adapter_path = "\\_SB_.I2C1",
  432. .irq_data = {
  433. .type = X86_ACPI_IRQ_TYPE_PMIC,
  434. .chip = "\\_SB_.I2C7.PMIC",
  435. .domain = DOMAIN_BUS_WAKEUP,
  436. .index = 0,
  437. },
  438. }, {
  439. /* ug3105 battery monitor */
  440. .board_info = {
  441. .type = "ug3105",
  442. .addr = 0x70,
  443. .dev_name = "ug3105",
  444. .swnode = &asus_me176c_ug3105_node,
  445. },
  446. .adapter_path = "\\_SB_.I2C1",
  447. }, {
  448. /* ak09911 compass */
  449. .board_info = {
  450. .type = "ak09911",
  451. .addr = 0x0c,
  452. .dev_name = "ak09911",
  453. },
  454. .adapter_path = "\\_SB_.I2C5",
  455. }, {
  456. /* kxtj21009 accel */
  457. .board_info = {
  458. .type = "kxtj21009",
  459. .addr = 0x0f,
  460. .dev_name = "kxtj21009",
  461. .swnode = &asus_me176c_accel_node,
  462. },
  463. .adapter_path = "\\_SB_.I2C5",
  464. .irq_data = {
  465. .type = X86_ACPI_IRQ_TYPE_APIC,
  466. .index = 0x44,
  467. .trigger = ACPI_EDGE_SENSITIVE,
  468. .polarity = ACPI_ACTIVE_LOW,
  469. },
  470. }, {
  471. /* goodix touchscreen */
  472. .board_info = {
  473. .type = "GDIX1001:00",
  474. .addr = 0x14,
  475. .dev_name = "goodix_ts",
  476. },
  477. .adapter_path = "\\_SB_.I2C6",
  478. .irq_data = {
  479. .type = X86_ACPI_IRQ_TYPE_APIC,
  480. .index = 0x45,
  481. .trigger = ACPI_EDGE_SENSITIVE,
  482. .polarity = ACPI_ACTIVE_LOW,
  483. },
  484. },
  485. };
  486. static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = {
  487. {
  488. .ctrl_hid = "80860F0A",
  489. .ctrl_uid = "2",
  490. .ctrl_devname = "serial0",
  491. .serdev_hid = "BCM2E3A",
  492. },
  493. };
  494. static struct gpiod_lookup_table asus_me176c_goodix_gpios = {
  495. .dev_id = "i2c-goodix_ts",
  496. .table = {
  497. GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_HIGH),
  498. GPIO_LOOKUP("INT33FC:02", 28, "irq", GPIO_ACTIVE_HIGH),
  499. { }
  500. },
  501. };
  502. static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
  503. &int3496_gpo2_pin22_gpios,
  504. &asus_me176c_goodix_gpios,
  505. NULL
  506. };
  507. static const struct x86_dev_info asus_me176c_info __initconst = {
  508. .i2c_client_info = asus_me176c_i2c_clients,
  509. .i2c_client_count = ARRAY_SIZE(asus_me176c_i2c_clients),
  510. .pdev_info = asus_me176c_tf103c_pdevs,
  511. .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
  512. .serdev_info = asus_me176c_serdevs,
  513. .serdev_count = ARRAY_SIZE(asus_me176c_serdevs),
  514. .gpiod_lookup_tables = asus_me176c_gpios,
  515. .bat_swnode = &generic_lipo_hv_4v35_battery_node,
  516. .modules = bq24190_modules,
  517. .invalid_aei_gpiochip = "INT33FC:02",
  518. .init = asus_me176c_tf103c_init,
  519. };
  520. /* Asus TF103C tablets have an Android factory img with everything hardcoded */
  521. static const char * const asus_tf103c_accel_mount_matrix[] = {
  522. "0", "-1", "0",
  523. "-1", "0", "0",
  524. "0", "0", "1"
  525. };
  526. static const struct property_entry asus_tf103c_accel_props[] = {
  527. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix),
  528. { }
  529. };
  530. static const struct software_node asus_tf103c_accel_node = {
  531. .properties = asus_tf103c_accel_props,
  532. };
  533. static const struct property_entry asus_tf103c_touchscreen_props[] = {
  534. PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"),
  535. { }
  536. };
  537. static const struct software_node asus_tf103c_touchscreen_node = {
  538. .properties = asus_tf103c_touchscreen_props,
  539. };
  540. static const struct property_entry asus_tf103c_battery_props[] = {
  541. PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
  542. PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion-polymer"),
  543. PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
  544. PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
  545. PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 2048000),
  546. PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4208000),
  547. PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
  548. { }
  549. };
  550. static const struct software_node asus_tf103c_battery_node = {
  551. .properties = asus_tf103c_battery_props,
  552. };
  553. static const struct property_entry asus_tf103c_bq24190_props[] = {
  554. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
  555. PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
  556. PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
  557. PROPERTY_ENTRY_BOOL("omit-battery-class"),
  558. PROPERTY_ENTRY_BOOL("disable-reset"),
  559. { }
  560. };
  561. static const struct software_node asus_tf103c_bq24190_node = {
  562. .properties = asus_tf103c_bq24190_props,
  563. };
  564. static const struct property_entry asus_tf103c_ug3105_props[] = {
  565. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
  566. PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
  567. PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000),
  568. { }
  569. };
  570. static const struct software_node asus_tf103c_ug3105_node = {
  571. .properties = asus_tf103c_ug3105_props,
  572. };
  573. static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = {
  574. {
  575. /* bq24297 battery charger */
  576. .board_info = {
  577. .type = "bq24190",
  578. .addr = 0x6b,
  579. .dev_name = "bq24297",
  580. .swnode = &asus_tf103c_bq24190_node,
  581. .platform_data = &bq24190_pdata,
  582. },
  583. .adapter_path = "\\_SB_.I2C1",
  584. .irq_data = {
  585. .type = X86_ACPI_IRQ_TYPE_PMIC,
  586. .chip = "\\_SB_.I2C7.PMIC",
  587. .domain = DOMAIN_BUS_WAKEUP,
  588. .index = 0,
  589. },
  590. }, {
  591. /* ug3105 battery monitor */
  592. .board_info = {
  593. .type = "ug3105",
  594. .addr = 0x70,
  595. .dev_name = "ug3105",
  596. .swnode = &asus_tf103c_ug3105_node,
  597. },
  598. .adapter_path = "\\_SB_.I2C1",
  599. }, {
  600. /* ak09911 compass */
  601. .board_info = {
  602. .type = "ak09911",
  603. .addr = 0x0c,
  604. .dev_name = "ak09911",
  605. },
  606. .adapter_path = "\\_SB_.I2C5",
  607. }, {
  608. /* kxtj21009 accel */
  609. .board_info = {
  610. .type = "kxtj21009",
  611. .addr = 0x0f,
  612. .dev_name = "kxtj21009",
  613. .swnode = &asus_tf103c_accel_node,
  614. },
  615. .adapter_path = "\\_SB_.I2C5",
  616. }, {
  617. /* atmel touchscreen */
  618. .board_info = {
  619. .type = "atmel_mxt_ts",
  620. .addr = 0x4a,
  621. .dev_name = "atmel_mxt_ts",
  622. .swnode = &asus_tf103c_touchscreen_node,
  623. },
  624. .adapter_path = "\\_SB_.I2C6",
  625. .irq_data = {
  626. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  627. .chip = "INT33FC:02",
  628. .index = 28,
  629. .trigger = ACPI_EDGE_SENSITIVE,
  630. .polarity = ACPI_ACTIVE_LOW,
  631. },
  632. },
  633. };
  634. static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
  635. &int3496_gpo2_pin22_gpios,
  636. NULL
  637. };
  638. static const struct x86_dev_info asus_tf103c_info __initconst = {
  639. .i2c_client_info = asus_tf103c_i2c_clients,
  640. .i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
  641. .pdev_info = asus_me176c_tf103c_pdevs,
  642. .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
  643. .gpiod_lookup_tables = asus_tf103c_gpios,
  644. .bat_swnode = &asus_tf103c_battery_node,
  645. .modules = bq24190_modules,
  646. .invalid_aei_gpiochip = "INT33FC:02",
  647. .init = asus_me176c_tf103c_init,
  648. };
  649. /*
  650. * When booted with the BIOS set to Android mode the Chuwi Hi8 (CWI509) DSDT
  651. * contains a whole bunch of bogus ACPI I2C devices and is missing entries
  652. * for the touchscreen and the accelerometer.
  653. */
  654. static const struct property_entry chuwi_hi8_gsl1680_props[] = {
  655. PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
  656. PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
  657. PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
  658. PROPERTY_ENTRY_BOOL("silead,home-button"),
  659. PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
  660. { }
  661. };
  662. static const struct software_node chuwi_hi8_gsl1680_node = {
  663. .properties = chuwi_hi8_gsl1680_props,
  664. };
  665. static const char * const chuwi_hi8_mount_matrix[] = {
  666. "1", "0", "0",
  667. "0", "-1", "0",
  668. "0", "0", "1"
  669. };
  670. static const struct property_entry chuwi_hi8_bma250e_props[] = {
  671. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix),
  672. { }
  673. };
  674. static const struct software_node chuwi_hi8_bma250e_node = {
  675. .properties = chuwi_hi8_bma250e_props,
  676. };
  677. static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = {
  678. {
  679. /* Silead touchscreen */
  680. .board_info = {
  681. .type = "gsl1680",
  682. .addr = 0x40,
  683. .swnode = &chuwi_hi8_gsl1680_node,
  684. },
  685. .adapter_path = "\\_SB_.I2C4",
  686. .irq_data = {
  687. .type = X86_ACPI_IRQ_TYPE_APIC,
  688. .index = 0x44,
  689. .trigger = ACPI_EDGE_SENSITIVE,
  690. .polarity = ACPI_ACTIVE_HIGH,
  691. },
  692. }, {
  693. /* BMA250E accelerometer */
  694. .board_info = {
  695. .type = "bma250e",
  696. .addr = 0x18,
  697. .swnode = &chuwi_hi8_bma250e_node,
  698. },
  699. .adapter_path = "\\_SB_.I2C3",
  700. .irq_data = {
  701. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  702. .chip = "INT33FC:02",
  703. .index = 23,
  704. .trigger = ACPI_LEVEL_SENSITIVE,
  705. .polarity = ACPI_ACTIVE_HIGH,
  706. },
  707. },
  708. };
  709. static int __init chuwi_hi8_init(void)
  710. {
  711. /*
  712. * Avoid the acpi_unregister_gsi() call in x86_acpi_irq_helper_get()
  713. * breaking the touchscreen + logging various errors when the Windows
  714. * BIOS is used.
  715. */
  716. if (acpi_dev_present("MSSL0001", NULL, 1))
  717. return -ENODEV;
  718. return 0;
  719. }
  720. static const struct x86_dev_info chuwi_hi8_info __initconst = {
  721. .i2c_client_info = chuwi_hi8_i2c_clients,
  722. .i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients),
  723. .init = chuwi_hi8_init,
  724. };
  725. #define CZC_EC_EXTRA_PORT 0x68
  726. #define CZC_EC_ANDROID_KEYS 0x63
  727. static int __init czc_p10t_init(void)
  728. {
  729. /*
  730. * The device boots up in "Windows 7" mode, when the home button sends a
  731. * Windows specific key sequence (Left Meta + D) and the second button
  732. * sends an unknown one while also toggling the Radio Kill Switch.
  733. * This is a surprising behavior when the second button is labeled "Back".
  734. *
  735. * The vendor-supplied Android-x86 build switches the device to a "Android"
  736. * mode by writing value 0x63 to the I/O port 0x68. This just seems to just
  737. * set bit 6 on address 0x96 in the EC region; switching the bit directly
  738. * seems to achieve the same result. It uses a "p10t_switcher" to do the
  739. * job. It doesn't seem to be able to do anything else, and no other use
  740. * of the port 0x68 is known.
  741. *
  742. * In the Android mode, the home button sends just a single scancode,
  743. * which can be handled in Linux userspace more reasonably and the back
  744. * button only sends a scancode without toggling the kill switch.
  745. * The scancode can then be mapped either to Back or RF Kill functionality
  746. * in userspace, depending on how the button is labeled on that particular
  747. * model.
  748. */
  749. outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT);
  750. return 0;
  751. }
  752. static const struct x86_dev_info czc_p10t __initconst = {
  753. .init = czc_p10t_init,
  754. };
  755. /* Lenovo Yoga Book X90F / X91F / X91L need manual instantiation of the fg client */
  756. static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __initconst = {
  757. {
  758. /* BQ27542 fuel-gauge */
  759. .board_info = {
  760. .type = "bq27542",
  761. .addr = 0x55,
  762. .dev_name = "bq27542",
  763. .swnode = &fg_bq25890_supply_node,
  764. },
  765. .adapter_path = "\\_SB_.PCI0.I2C1",
  766. },
  767. };
  768. static const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = {
  769. .i2c_client_info = lenovo_yogabook_x9x_i2c_clients,
  770. .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients),
  771. };
  772. /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
  773. static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
  774. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
  775. PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
  776. PROPERTY_ENTRY_BOOL("omit-battery-class"),
  777. PROPERTY_ENTRY_BOOL("disable-reset"),
  778. { }
  779. };
  780. static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
  781. .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
  782. };
  783. /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
  784. static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
  785. static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = {
  786. .device_control = 0x86,
  787. .initial_brightness = 128,
  788. };
  789. static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = {
  790. {
  791. /* bq24292i battery charger */
  792. .board_info = {
  793. .type = "bq24190",
  794. .addr = 0x6b,
  795. .dev_name = "bq24292i",
  796. .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
  797. .platform_data = &bq24190_pdata,
  798. },
  799. .adapter_path = "\\_SB_.I2C1",
  800. .irq_data = {
  801. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  802. .chip = "INT33FC:02",
  803. .index = 2,
  804. .trigger = ACPI_EDGE_SENSITIVE,
  805. .polarity = ACPI_ACTIVE_HIGH,
  806. },
  807. }, {
  808. /* BQ27541 fuel-gauge */
  809. .board_info = {
  810. .type = "bq27541",
  811. .addr = 0x55,
  812. .dev_name = "bq27541",
  813. .swnode = &fg_bq24190_supply_node,
  814. },
  815. .adapter_path = "\\_SB_.I2C1",
  816. }, {
  817. /* Synaptics RMI touchscreen */
  818. .board_info = {
  819. .type = "rmi4_i2c",
  820. .addr = 0x38,
  821. .dev_name = "rmi4_i2c",
  822. .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
  823. },
  824. .adapter_path = "\\_SB_.I2C6",
  825. .irq_data = {
  826. .type = X86_ACPI_IRQ_TYPE_APIC,
  827. .index = 0x45,
  828. .trigger = ACPI_EDGE_SENSITIVE,
  829. .polarity = ACPI_ACTIVE_HIGH,
  830. },
  831. }, {
  832. /* LP8557 Backlight controller */
  833. .board_info = {
  834. .type = "lp8557",
  835. .addr = 0x2c,
  836. .dev_name = "lp8557",
  837. .platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata,
  838. },
  839. .adapter_path = "\\_SB_.I2C3",
  840. },
  841. };
  842. static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
  843. .dev_id = "intel-int3496",
  844. .table = {
  845. GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
  846. GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
  847. { }
  848. },
  849. };
  850. #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
  851. static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
  852. .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
  853. .table = {
  854. GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
  855. GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
  856. GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
  857. GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
  858. { }
  859. },
  860. };
  861. static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
  862. &lenovo_yoga_tab2_830_1050_int3496_gpios,
  863. &lenovo_yoga_tab2_830_1050_codec_gpios,
  864. NULL
  865. };
  866. static int __init lenovo_yoga_tab2_830_1050_init(void);
  867. static void lenovo_yoga_tab2_830_1050_exit(void);
  868. static struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = {
  869. .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
  870. /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */
  871. .pdev_info = int3496_pdevs,
  872. .pdev_count = ARRAY_SIZE(int3496_pdevs),
  873. .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
  874. .bat_swnode = &generic_lipo_hv_4v35_battery_node,
  875. .modules = bq24190_modules,
  876. .invalid_aei_gpiochip = "INT33FC:02",
  877. .init = lenovo_yoga_tab2_830_1050_init,
  878. .exit = lenovo_yoga_tab2_830_1050_exit,
  879. };
  880. /*
  881. * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
  882. * mainboard, but they need some different treatment related to the display:
  883. * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring
  884. * the touchscreen driver to adjust the touch-coords to match the LCD.
  885. * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's
  886. * PWM input is connected to the PMIC's PWM output and everything works fine
  887. * with the defaults programmed into the LP8557 by the BIOS.
  888. * But on the 830 the LP8557's PWM input is connected to a PWM output coming
  889. * from the LCD panel's controller. The Android code has a hack in the i915
  890. * driver to write the non-standard DSI reg 0x9f with the desired backlight
  891. * level to set the duty-cycle of the LCD's PWM output.
  892. *
  893. * To avoid having to have a similar hack in the mainline kernel the LP8557
  894. * entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the
  895. * LP8557 to directly set the level, ignoring the PWM input. This means that
  896. * the LP8557 i2c_client should only be instantiated on the 830.
  897. */
  898. static int __init lenovo_yoga_tab2_830_1050_init_display(void)
  899. {
  900. struct gpio_desc *gpiod;
  901. int ret;
  902. /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
  903. ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
  904. if (ret)
  905. return ret;
  906. ret = gpiod_get_value_cansleep(gpiod);
  907. if (ret) {
  908. pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
  909. lenovo_yoga_tab2_830_1050_info.i2c_client_count =
  910. ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1;
  911. } else {
  912. pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
  913. lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
  914. lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
  915. lenovo_yoga_tab2_830_1050_info.i2c_client_count =
  916. ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients);
  917. }
  918. return 0;
  919. }
  920. /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
  921. static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
  922. PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
  923. "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
  924. static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
  925. static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
  926. static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
  927. {
  928. struct device *codec_dev;
  929. struct pinctrl *pinctrl;
  930. int ret;
  931. codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
  932. LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
  933. if (!codec_dev) {
  934. pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
  935. return -ENODEV;
  936. }
  937. ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
  938. if (ret)
  939. goto err_put_device;
  940. pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
  941. if (IS_ERR(pinctrl)) {
  942. ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
  943. goto err_unregister_mappings;
  944. }
  945. /* We're done with the codec_dev now */
  946. put_device(codec_dev);
  947. lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
  948. return 0;
  949. err_unregister_mappings:
  950. pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
  951. err_put_device:
  952. put_device(codec_dev);
  953. return ret;
  954. }
  955. /*
  956. * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
  957. * gets used as pm_power_off handler. This causes "poweroff" on these tablets
  958. * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
  959. * followed by a normal 3 second press to recover. Avoid this by doing an EFI
  960. * poweroff instead.
  961. */
  962. static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
  963. {
  964. efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
  965. return NOTIFY_DONE;
  966. }
  967. static int __init lenovo_yoga_tab2_830_1050_init(void)
  968. {
  969. int ret;
  970. ret = lenovo_yoga_tab2_830_1050_init_display();
  971. if (ret)
  972. return ret;
  973. ret = lenovo_yoga_tab2_830_1050_init_codec();
  974. if (ret)
  975. return ret;
  976. /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
  977. lenovo_yoga_tab2_830_1050_sys_off_handler =
  978. register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
  979. lenovo_yoga_tab2_830_1050_power_off, NULL);
  980. if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
  981. return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
  982. return 0;
  983. }
  984. static void lenovo_yoga_tab2_830_1050_exit(void)
  985. {
  986. unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
  987. if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
  988. pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
  989. pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
  990. }
  991. }
  992. /* Lenovo Yoga Tab 3 Pro YT3-X90F */
  993. /*
  994. * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
  995. * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
  996. */
  997. static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
  998. static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
  999. static const struct property_entry fg_bq25890_1_supply_props[] = {
  1000. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
  1001. { }
  1002. };
  1003. static const struct software_node fg_bq25890_1_supply_node = {
  1004. .properties = fg_bq25890_1_supply_props,
  1005. };
  1006. /* bq25892 charger settings for the flat lipo battery behind the screen */
  1007. static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
  1008. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
  1009. PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"),
  1010. PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
  1011. PROPERTY_ENTRY_BOOL("linux,skip-reset"),
  1012. /* Values taken from Android Factory Image */
  1013. PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
  1014. PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
  1015. PROPERTY_ENTRY_U32("ti,termination-current", 128000),
  1016. PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
  1017. PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
  1018. PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
  1019. PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
  1020. PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
  1021. { }
  1022. };
  1023. static const struct software_node lenovo_yt3_bq25892_0_node = {
  1024. .properties = lenovo_yt3_bq25892_0_props,
  1025. };
  1026. static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
  1027. {
  1028. /* bq27500 fuel-gauge for the flat lipo battery behind the screen */
  1029. .board_info = {
  1030. .type = "bq27500",
  1031. .addr = 0x55,
  1032. .dev_name = "bq27500_0",
  1033. .swnode = &fg_bq25890_supply_node,
  1034. },
  1035. .adapter_path = "\\_SB_.PCI0.I2C1",
  1036. }, {
  1037. /* bq25892 charger for the flat lipo battery behind the screen */
  1038. .board_info = {
  1039. .type = "bq25892",
  1040. .addr = 0x6b,
  1041. .dev_name = "bq25892_0",
  1042. .swnode = &lenovo_yt3_bq25892_0_node,
  1043. },
  1044. .adapter_path = "\\_SB_.PCI0.I2C1",
  1045. .irq_data = {
  1046. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  1047. .chip = "INT33FF:01",
  1048. .index = 5,
  1049. .trigger = ACPI_EDGE_SENSITIVE,
  1050. .polarity = ACPI_ACTIVE_LOW,
  1051. },
  1052. }, {
  1053. /* bq27500 fuel-gauge for the round li-ion cells in the hinge */
  1054. .board_info = {
  1055. .type = "bq27500",
  1056. .addr = 0x55,
  1057. .dev_name = "bq27500_1",
  1058. .swnode = &fg_bq25890_1_supply_node,
  1059. },
  1060. .adapter_path = "\\_SB_.PCI0.I2C2",
  1061. }
  1062. };
  1063. static int __init lenovo_yt3_init(void)
  1064. {
  1065. struct gpio_desc *gpiod;
  1066. int ret;
  1067. /*
  1068. * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
  1069. * connected to GPIOs, rather then having them hardwired to the correct
  1070. * values as is normally done.
  1071. *
  1072. * The bq25890_charger driver controls these through I2C, but this only
  1073. * works if not overridden by the pins. Set these pins here:
  1074. * 1. Set /CE to 0 to allow charging.
  1075. * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
  1076. * the main "bq25892_1" charger is used when necessary.
  1077. */
  1078. /* /CE pin */
  1079. ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod);
  1080. if (ret < 0)
  1081. return ret;
  1082. /*
  1083. * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw"
  1084. * gpio_desc, that is there is no way to pass lookup-flags like
  1085. * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since
  1086. * the /CE pin is active-low, but not marked as such in the gpio_desc.
  1087. */
  1088. gpiod_set_value(gpiod, 0);
  1089. /* OTG pin */
  1090. ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod);
  1091. if (ret < 0)
  1092. return ret;
  1093. gpiod_set_value(gpiod, 0);
  1094. return 0;
  1095. }
  1096. static const struct x86_dev_info lenovo_yt3_info __initconst = {
  1097. .i2c_client_info = lenovo_yt3_i2c_clients,
  1098. .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
  1099. .init = lenovo_yt3_init,
  1100. };
  1101. /* Medion Lifetab S10346 tablets have an Android factory img with everything hardcoded */
  1102. static const char * const medion_lifetab_s10346_accel_mount_matrix[] = {
  1103. "0", "1", "0",
  1104. "1", "0", "0",
  1105. "0", "0", "1"
  1106. };
  1107. static const struct property_entry medion_lifetab_s10346_accel_props[] = {
  1108. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", medion_lifetab_s10346_accel_mount_matrix),
  1109. { }
  1110. };
  1111. static const struct software_node medion_lifetab_s10346_accel_node = {
  1112. .properties = medion_lifetab_s10346_accel_props,
  1113. };
  1114. /* Note the LCD panel is mounted upside down, this is correctly indicated in the VBT */
  1115. static const struct property_entry medion_lifetab_s10346_touchscreen_props[] = {
  1116. PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
  1117. PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
  1118. { }
  1119. };
  1120. static const struct software_node medion_lifetab_s10346_touchscreen_node = {
  1121. .properties = medion_lifetab_s10346_touchscreen_props,
  1122. };
  1123. static const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __initconst = {
  1124. {
  1125. /* kxtj21009 accel */
  1126. .board_info = {
  1127. .type = "kxtj21009",
  1128. .addr = 0x0f,
  1129. .dev_name = "kxtj21009",
  1130. .swnode = &medion_lifetab_s10346_accel_node,
  1131. },
  1132. .adapter_path = "\\_SB_.I2C3",
  1133. .irq_data = {
  1134. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  1135. .chip = "INT33FC:02",
  1136. .index = 23,
  1137. .trigger = ACPI_EDGE_SENSITIVE,
  1138. .polarity = ACPI_ACTIVE_HIGH,
  1139. },
  1140. }, {
  1141. /* goodix touchscreen */
  1142. .board_info = {
  1143. .type = "GDIX1001:00",
  1144. .addr = 0x14,
  1145. .dev_name = "goodix_ts",
  1146. .swnode = &medion_lifetab_s10346_touchscreen_node,
  1147. },
  1148. .adapter_path = "\\_SB_.I2C4",
  1149. .irq_data = {
  1150. .type = X86_ACPI_IRQ_TYPE_APIC,
  1151. .index = 0x44,
  1152. .trigger = ACPI_EDGE_SENSITIVE,
  1153. .polarity = ACPI_ACTIVE_LOW,
  1154. },
  1155. },
  1156. };
  1157. static struct gpiod_lookup_table medion_lifetab_s10346_goodix_gpios = {
  1158. .dev_id = "i2c-goodix_ts",
  1159. .table = {
  1160. GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
  1161. GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
  1162. { }
  1163. },
  1164. };
  1165. static struct gpiod_lookup_table * const medion_lifetab_s10346_gpios[] = {
  1166. &medion_lifetab_s10346_goodix_gpios,
  1167. NULL
  1168. };
  1169. static const struct x86_dev_info medion_lifetab_s10346_info __initconst = {
  1170. .i2c_client_info = medion_lifetab_s10346_i2c_clients,
  1171. .i2c_client_count = ARRAY_SIZE(medion_lifetab_s10346_i2c_clients),
  1172. .gpiod_lookup_tables = medion_lifetab_s10346_gpios,
  1173. };
  1174. /* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */
  1175. static const char * const nextbook_ares8_accel_mount_matrix[] = {
  1176. "0", "-1", "0",
  1177. "-1", "0", "0",
  1178. "0", "0", "1"
  1179. };
  1180. static const struct property_entry nextbook_ares8_accel_props[] = {
  1181. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix),
  1182. { }
  1183. };
  1184. static const struct software_node nextbook_ares8_accel_node = {
  1185. .properties = nextbook_ares8_accel_props,
  1186. };
  1187. static const struct property_entry nextbook_ares8_touchscreen_props[] = {
  1188. PROPERTY_ENTRY_U32("touchscreen-size-x", 800),
  1189. PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
  1190. { }
  1191. };
  1192. static const struct software_node nextbook_ares8_touchscreen_node = {
  1193. .properties = nextbook_ares8_touchscreen_props,
  1194. };
  1195. static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = {
  1196. {
  1197. /* Freescale MMA8653FC accel */
  1198. .board_info = {
  1199. .type = "mma8653",
  1200. .addr = 0x1d,
  1201. .dev_name = "mma8653",
  1202. .swnode = &nextbook_ares8_accel_node,
  1203. },
  1204. .adapter_path = "\\_SB_.I2C3",
  1205. }, {
  1206. /* FT5416DQ9 touchscreen controller */
  1207. .board_info = {
  1208. .type = "edt-ft5x06",
  1209. .addr = 0x38,
  1210. .dev_name = "ft5416",
  1211. .swnode = &nextbook_ares8_touchscreen_node,
  1212. },
  1213. .adapter_path = "\\_SB_.I2C4",
  1214. .irq_data = {
  1215. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  1216. .chip = "INT33FC:02",
  1217. .index = 3,
  1218. .trigger = ACPI_EDGE_SENSITIVE,
  1219. .polarity = ACPI_ACTIVE_LOW,
  1220. },
  1221. },
  1222. };
  1223. static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = {
  1224. &int3496_reference_gpios,
  1225. NULL
  1226. };
  1227. static const struct x86_dev_info nextbook_ares8_info __initconst = {
  1228. .i2c_client_info = nextbook_ares8_i2c_clients,
  1229. .i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients),
  1230. .pdev_info = int3496_pdevs,
  1231. .pdev_count = ARRAY_SIZE(int3496_pdevs),
  1232. .gpiod_lookup_tables = nextbook_ares8_gpios,
  1233. .invalid_aei_gpiochip = "INT33FC:02",
  1234. };
  1235. /*
  1236. * Whitelabel (sold as various brands) TM800A550L tablets.
  1237. * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices
  1238. * (removed through acpi_quirk_skip_i2c_client_enumeration()) and
  1239. * the touchscreen fwnode has the wrong GPIOs.
  1240. */
  1241. static const char * const whitelabel_tm800a550l_accel_mount_matrix[] = {
  1242. "-1", "0", "0",
  1243. "0", "1", "0",
  1244. "0", "0", "1"
  1245. };
  1246. static const struct property_entry whitelabel_tm800a550l_accel_props[] = {
  1247. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix),
  1248. { }
  1249. };
  1250. static const struct software_node whitelabel_tm800a550l_accel_node = {
  1251. .properties = whitelabel_tm800a550l_accel_props,
  1252. };
  1253. static const struct property_entry whitelabel_tm800a550l_goodix_props[] = {
  1254. PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"),
  1255. PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"),
  1256. PROPERTY_ENTRY_U32("goodix,main-clk", 54),
  1257. { }
  1258. };
  1259. static const struct software_node whitelabel_tm800a550l_goodix_node = {
  1260. .properties = whitelabel_tm800a550l_goodix_props,
  1261. };
  1262. static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = {
  1263. {
  1264. /* goodix touchscreen */
  1265. .board_info = {
  1266. .type = "GDIX1001:00",
  1267. .addr = 0x14,
  1268. .dev_name = "goodix_ts",
  1269. .swnode = &whitelabel_tm800a550l_goodix_node,
  1270. },
  1271. .adapter_path = "\\_SB_.I2C2",
  1272. .irq_data = {
  1273. .type = X86_ACPI_IRQ_TYPE_APIC,
  1274. .index = 0x44,
  1275. .trigger = ACPI_EDGE_SENSITIVE,
  1276. .polarity = ACPI_ACTIVE_HIGH,
  1277. },
  1278. }, {
  1279. /* kxcj91008 accel */
  1280. .board_info = {
  1281. .type = "kxcj91008",
  1282. .addr = 0x0f,
  1283. .dev_name = "kxcj91008",
  1284. .swnode = &whitelabel_tm800a550l_accel_node,
  1285. },
  1286. .adapter_path = "\\_SB_.I2C3",
  1287. },
  1288. };
  1289. static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = {
  1290. .dev_id = "i2c-goodix_ts",
  1291. .table = {
  1292. GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
  1293. GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
  1294. { }
  1295. },
  1296. };
  1297. static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = {
  1298. &whitelabel_tm800a550l_goodix_gpios,
  1299. NULL
  1300. };
  1301. static const struct x86_dev_info whitelabel_tm800a550l_info __initconst = {
  1302. .i2c_client_info = whitelabel_tm800a550l_i2c_clients,
  1303. .i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients),
  1304. .gpiod_lookup_tables = whitelabel_tm800a550l_gpios,
  1305. };
  1306. /*
  1307. * If the EFI bootloader is not Xiaomi's own signed Android loader, then the
  1308. * Xiaomi Mi Pad 2 X86 tablet sets OSID in the DSDT to 1 (Windows), causing
  1309. * a bunch of devices to be hidden.
  1310. *
  1311. * This takes care of instantiating the hidden devices manually.
  1312. */
  1313. static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = {
  1314. {
  1315. /* BQ27520 fuel-gauge */
  1316. .board_info = {
  1317. .type = "bq27520",
  1318. .addr = 0x55,
  1319. .dev_name = "bq27520",
  1320. .swnode = &fg_bq25890_supply_node,
  1321. },
  1322. .adapter_path = "\\_SB_.PCI0.I2C1",
  1323. }, {
  1324. /* KTD2026 RGB notification LED controller */
  1325. .board_info = {
  1326. .type = "ktd2026",
  1327. .addr = 0x30,
  1328. .dev_name = "ktd2026",
  1329. },
  1330. .adapter_path = "\\_SB_.PCI0.I2C3",
  1331. },
  1332. };
  1333. static const struct x86_dev_info xiaomi_mipad2_info __initconst = {
  1334. .i2c_client_info = xiaomi_mipad2_i2c_clients,
  1335. .i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients),
  1336. };
  1337. static const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
  1338. {
  1339. /* Acer Iconia One 7 B1-750 */
  1340. .matches = {
  1341. DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
  1342. DMI_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
  1343. },
  1344. .driver_data = (void *)&acer_b1_750_info,
  1345. },
  1346. {
  1347. /* Advantech MICA-071 */
  1348. .matches = {
  1349. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
  1350. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
  1351. },
  1352. .driver_data = (void *)&advantech_mica_071_info,
  1353. },
  1354. {
  1355. /* Asus MeMO Pad 7 ME176C */
  1356. .matches = {
  1357. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
  1358. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
  1359. },
  1360. .driver_data = (void *)&asus_me176c_info,
  1361. },
  1362. {
  1363. /* Asus TF103C */
  1364. .matches = {
  1365. DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
  1366. DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
  1367. },
  1368. .driver_data = (void *)&asus_tf103c_info,
  1369. },
  1370. {
  1371. /* Chuwi Hi8 (CWI509) */
  1372. .matches = {
  1373. DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
  1374. DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
  1375. DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
  1376. DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
  1377. },
  1378. .driver_data = (void *)&chuwi_hi8_info,
  1379. },
  1380. {
  1381. /* CZC P10T */
  1382. .ident = "CZC ODEON TPC-10 (\"P10T\")",
  1383. .matches = {
  1384. DMI_MATCH(DMI_SYS_VENDOR, "CZC"),
  1385. DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"),
  1386. },
  1387. .driver_data = (void *)&czc_p10t,
  1388. },
  1389. {
  1390. /* CZC P10T variant */
  1391. .ident = "ViewSonic ViewPad 10",
  1392. .matches = {
  1393. DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"),
  1394. DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"),
  1395. },
  1396. .driver_data = (void *)&czc_p10t,
  1397. },
  1398. {
  1399. /* Lenovo Yoga Book X90F / X91F / X91L */
  1400. .matches = {
  1401. /* Non exact match to match all versions */
  1402. DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
  1403. },
  1404. .driver_data = (void *)&lenovo_yogabook_x9x_info,
  1405. },
  1406. {
  1407. /*
  1408. * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
  1409. * Lenovo Yoga Tablet 2 use the same mainboard)
  1410. */
  1411. .matches = {
  1412. DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
  1413. DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
  1414. DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
  1415. /* Partial match on beginning of BIOS version */
  1416. DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
  1417. },
  1418. .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info,
  1419. },
  1420. {
  1421. /* Lenovo Yoga Tab 3 Pro YT3-X90F */
  1422. .matches = {
  1423. DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
  1424. DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
  1425. DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
  1426. },
  1427. .driver_data = (void *)&lenovo_yt3_info,
  1428. },
  1429. {
  1430. /* Medion Lifetab S10346 */
  1431. .matches = {
  1432. DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
  1433. DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
  1434. /* Above strings are much too generic, also match on BIOS date */
  1435. DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
  1436. },
  1437. .driver_data = (void *)&medion_lifetab_s10346_info,
  1438. },
  1439. {
  1440. /* Nextbook Ares 8 */
  1441. .matches = {
  1442. DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
  1443. DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
  1444. },
  1445. .driver_data = (void *)&nextbook_ares8_info,
  1446. },
  1447. {
  1448. /* Whitelabel (sold as various brands) TM800A550L */
  1449. .matches = {
  1450. DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
  1451. DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
  1452. /* Above strings are too generic, also match on BIOS version */
  1453. DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
  1454. },
  1455. .driver_data = (void *)&whitelabel_tm800a550l_info,
  1456. },
  1457. {
  1458. /* Xiaomi Mi Pad 2 */
  1459. .matches = {
  1460. DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
  1461. DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
  1462. },
  1463. .driver_data = (void *)&xiaomi_mipad2_info,
  1464. },
  1465. { }
  1466. };
  1467. MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids);
  1468. static int i2c_client_count;
  1469. static int pdev_count;
  1470. static int serdev_count;
  1471. static struct i2c_client **i2c_clients;
  1472. static struct platform_device **pdevs;
  1473. static struct serdev_device **serdevs;
  1474. static struct gpiod_lookup_table * const *gpiod_lookup_tables;
  1475. static const struct software_node *bat_swnode;
  1476. static void (*exit_handler)(void);
  1477. static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
  1478. int idx)
  1479. {
  1480. const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx];
  1481. struct i2c_board_info board_info = client_info->board_info;
  1482. struct i2c_adapter *adap;
  1483. acpi_handle handle;
  1484. acpi_status status;
  1485. board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data);
  1486. if (board_info.irq < 0)
  1487. return board_info.irq;
  1488. status = acpi_get_handle(NULL, client_info->adapter_path, &handle);
  1489. if (ACPI_FAILURE(status)) {
  1490. pr_err("Error could not get %s handle\n", client_info->adapter_path);
  1491. return -ENODEV;
  1492. }
  1493. adap = i2c_acpi_find_adapter_by_handle(handle);
  1494. if (!adap) {
  1495. pr_err("error could not get %s adapter\n", client_info->adapter_path);
  1496. return -ENODEV;
  1497. }
  1498. i2c_clients[idx] = i2c_new_client_device(adap, &board_info);
  1499. put_device(&adap->dev);
  1500. if (IS_ERR(i2c_clients[idx]))
  1501. return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]),
  1502. "creating I2C-client %d\n", idx);
  1503. return 0;
  1504. }
  1505. static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx)
  1506. {
  1507. struct acpi_device *ctrl_adev, *serdev_adev;
  1508. struct serdev_device *serdev;
  1509. struct device *ctrl_dev;
  1510. int ret = -ENODEV;
  1511. ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1);
  1512. if (!ctrl_adev) {
  1513. pr_err("error could not get %s/%s ctrl adev\n",
  1514. info->ctrl_hid, info->ctrl_uid);
  1515. return -ENODEV;
  1516. }
  1517. serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1);
  1518. if (!serdev_adev) {
  1519. pr_err("error could not get %s serdev adev\n", info->serdev_hid);
  1520. goto put_ctrl_adev;
  1521. }
  1522. /* get_first_physical_node() returns a weak ref, no need to put() it */
  1523. ctrl_dev = acpi_get_first_physical_node(ctrl_adev);
  1524. if (!ctrl_dev) {
  1525. pr_err("error could not get %s/%s ctrl physical dev\n",
  1526. info->ctrl_hid, info->ctrl_uid);
  1527. goto put_serdev_adev;
  1528. }
  1529. /* ctrl_dev now points to the controller's parent, get the controller */
  1530. ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname);
  1531. if (!ctrl_dev) {
  1532. pr_err("error could not get %s/%s %s ctrl dev\n",
  1533. info->ctrl_hid, info->ctrl_uid, info->ctrl_devname);
  1534. goto put_serdev_adev;
  1535. }
  1536. serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
  1537. if (!serdev) {
  1538. ret = -ENOMEM;
  1539. goto put_serdev_adev;
  1540. }
  1541. ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
  1542. acpi_device_set_enumerated(serdev_adev);
  1543. ret = serdev_device_add(serdev);
  1544. if (ret) {
  1545. dev_err(&serdev->dev, "error %d adding serdev\n", ret);
  1546. serdev_device_put(serdev);
  1547. goto put_serdev_adev;
  1548. }
  1549. serdevs[idx] = serdev;
  1550. put_serdev_adev:
  1551. acpi_dev_put(serdev_adev);
  1552. put_ctrl_adev:
  1553. acpi_dev_put(ctrl_adev);
  1554. return ret;
  1555. }
  1556. static void x86_android_tablet_cleanup(void)
  1557. {
  1558. int i;
  1559. for (i = 0; i < serdev_count; i++) {
  1560. if (serdevs[i])
  1561. serdev_device_remove(serdevs[i]);
  1562. }
  1563. kfree(serdevs);
  1564. for (i = 0; i < pdev_count; i++)
  1565. platform_device_unregister(pdevs[i]);
  1566. kfree(pdevs);
  1567. for (i = 0; i < i2c_client_count; i++)
  1568. i2c_unregister_device(i2c_clients[i]);
  1569. kfree(i2c_clients);
  1570. if (exit_handler)
  1571. exit_handler();
  1572. for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
  1573. gpiod_remove_lookup_table(gpiod_lookup_tables[i]);
  1574. software_node_unregister(bat_swnode);
  1575. }
  1576. static __init int x86_android_tablet_init(void)
  1577. {
  1578. const struct x86_dev_info *dev_info;
  1579. const struct dmi_system_id *id;
  1580. struct gpio_chip *chip;
  1581. int i, ret = 0;
  1582. id = dmi_first_match(x86_android_tablet_ids);
  1583. if (!id)
  1584. return -ENODEV;
  1585. dev_info = id->driver_data;
  1586. /*
  1587. * The broken DSDTs on these devices often also include broken
  1588. * _AEI (ACPI Event Interrupt) handlers, disable these.
  1589. */
  1590. if (dev_info->invalid_aei_gpiochip) {
  1591. chip = gpiochip_find(dev_info->invalid_aei_gpiochip,
  1592. gpiochip_find_match_label);
  1593. if (!chip) {
  1594. pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip);
  1595. return -ENODEV;
  1596. }
  1597. acpi_gpiochip_free_interrupts(chip);
  1598. }
  1599. /*
  1600. * Since this runs from module_init() it cannot use -EPROBE_DEFER,
  1601. * instead pre-load any modules which are listed as requirements.
  1602. */
  1603. for (i = 0; dev_info->modules && dev_info->modules[i]; i++)
  1604. request_module(dev_info->modules[i]);
  1605. bat_swnode = dev_info->bat_swnode;
  1606. if (bat_swnode) {
  1607. ret = software_node_register(bat_swnode);
  1608. if (ret)
  1609. return ret;
  1610. }
  1611. gpiod_lookup_tables = dev_info->gpiod_lookup_tables;
  1612. for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
  1613. gpiod_add_lookup_table(gpiod_lookup_tables[i]);
  1614. if (dev_info->init) {
  1615. ret = dev_info->init();
  1616. if (ret < 0) {
  1617. x86_android_tablet_cleanup();
  1618. return ret;
  1619. }
  1620. exit_handler = dev_info->exit;
  1621. }
  1622. i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL);
  1623. if (!i2c_clients) {
  1624. x86_android_tablet_cleanup();
  1625. return -ENOMEM;
  1626. }
  1627. i2c_client_count = dev_info->i2c_client_count;
  1628. for (i = 0; i < i2c_client_count; i++) {
  1629. ret = x86_instantiate_i2c_client(dev_info, i);
  1630. if (ret < 0) {
  1631. x86_android_tablet_cleanup();
  1632. return ret;
  1633. }
  1634. }
  1635. pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL);
  1636. if (!pdevs) {
  1637. x86_android_tablet_cleanup();
  1638. return -ENOMEM;
  1639. }
  1640. pdev_count = dev_info->pdev_count;
  1641. for (i = 0; i < pdev_count; i++) {
  1642. pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]);
  1643. if (IS_ERR(pdevs[i])) {
  1644. x86_android_tablet_cleanup();
  1645. return PTR_ERR(pdevs[i]);
  1646. }
  1647. }
  1648. serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
  1649. if (!serdevs) {
  1650. x86_android_tablet_cleanup();
  1651. return -ENOMEM;
  1652. }
  1653. serdev_count = dev_info->serdev_count;
  1654. for (i = 0; i < serdev_count; i++) {
  1655. ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i);
  1656. if (ret < 0) {
  1657. x86_android_tablet_cleanup();
  1658. return ret;
  1659. }
  1660. }
  1661. return 0;
  1662. }
  1663. module_init(x86_android_tablet_init);
  1664. module_exit(x86_android_tablet_cleanup);
  1665. MODULE_AUTHOR("Hans de Goede <[email protected]>");
  1666. MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver");
  1667. MODULE_LICENSE("GPL");