lenovo.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Board info for Lenovo X86 tablets which ship with Android as the factory image
  4. * and which have broken DSDT tables. 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-2023 Hans de Goede <hansg@kernel.org>
  9. */
  10. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11. #include <linux/efi.h>
  12. #include <linux/gpio/machine.h>
  13. #include <linux/gpio/property.h>
  14. #include <linux/input-event-codes.h>
  15. #include <linux/mfd/arizona/pdata.h>
  16. #include <linux/mfd/arizona/registers.h>
  17. #include <linux/mfd/intel_soc_pmic.h>
  18. #include <linux/pinctrl/consumer.h>
  19. #include <linux/pinctrl/machine.h>
  20. #include <linux/platform_data/lp855x.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/power/bq24190_charger.h>
  23. #include <linux/reboot.h>
  24. #include <linux/rmi.h>
  25. #include <linux/spi/spi.h>
  26. #include "shared-psy-info.h"
  27. #include "x86-android-tablets.h"
  28. /*
  29. * Various Lenovo models use a TI LP8557 LED backlight controller with its PWM
  30. * input connected to a PWM output coming from the LCD panel's controller.
  31. * The Android kernels have a hack in the i915 driver to write a non-standard
  32. * panel specific DSI register to set the duty-cycle of the LCD's PWM output.
  33. *
  34. * To avoid having to have a similar hack in the mainline kernel program the
  35. * LP8557 to directly set the level and use the lp855x_bl driver for control.
  36. *
  37. * The LP8557 can either be configured to multiply its PWM input and
  38. * the I2C register set level (requiring both to be at 100% for 100% output);
  39. * or to only take the I2C register set level into account.
  40. *
  41. * Multiplying the 2 levels is useful because this will turn off the backlight
  42. * when the panel goes off and turns off its PWM output.
  43. *
  44. * But on some models the panel's PWM output defaults to a duty-cycle of
  45. * much less then 100%, severely limiting max brightness. In this case
  46. * the LP8557 should be configured to only take the I2C register into
  47. * account and the i915 driver must turn off the panel and the backlight
  48. * separately using e.g. VBT MIPI sequences to turn off the backlight.
  49. */
  50. static struct lp855x_platform_data lenovo_lp8557_pwm_and_reg_pdata = {
  51. .device_control = 0x86,
  52. .initial_brightness = 128,
  53. };
  54. static struct lp855x_platform_data lenovo_lp8557_reg_only_pdata = {
  55. .device_control = 0x85,
  56. .initial_brightness = 128,
  57. };
  58. static const struct software_node arizona_gpiochip_node = {
  59. .name = "arizona",
  60. };
  61. static const struct software_node crystalcove_gpiochip_node = {
  62. .name = "gpio_crystalcove",
  63. };
  64. /* Lenovo Yoga Book X90F / X90L's Android factory image has everything hardcoded */
  65. static const struct property_entry lenovo_yb1_x90_goodix_props[] = {
  66. PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[1], 53, GPIO_ACTIVE_HIGH),
  67. PROPERTY_ENTRY_GPIO("irq-gpios", &cherryview_gpiochip_nodes[1], 56, GPIO_ACTIVE_HIGH),
  68. { }
  69. };
  70. static const struct software_node lenovo_yb1_x90_goodix_node = {
  71. .properties = lenovo_yb1_x90_goodix_props,
  72. };
  73. static const struct property_entry lenovo_yb1_x90_wacom_props[] = {
  74. PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001),
  75. PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150),
  76. PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 82, GPIO_ACTIVE_LOW),
  77. { }
  78. };
  79. static const struct software_node lenovo_yb1_x90_wacom_node = {
  80. .properties = lenovo_yb1_x90_wacom_props,
  81. };
  82. /*
  83. * The HiDeep IST940E touchscreen comes up in I2C-HID mode. The native protocol
  84. * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID
  85. * mode, so using native mode is preferred.
  86. * It could alternatively be used in HID mode by changing the properties to:
  87. * PROPERTY_ENTRY_U32("hid-descr-addr", 0x0020),
  88. * PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
  89. * and changing board_info.type to "hid-over-i2c".
  90. */
  91. static const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = {
  92. PROPERTY_ENTRY_U32("touchscreen-size-x", 1200),
  93. PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
  94. PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384),
  95. PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"),
  96. PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 7, GPIO_ACTIVE_LOW),
  97. { }
  98. };
  99. static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
  100. .properties = lenovo_yb1_x90_hideep_ts_props,
  101. };
  102. static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
  103. {
  104. /* BQ27542 fuel-gauge */
  105. .board_info = {
  106. .type = "bq27542",
  107. .addr = 0x55,
  108. .dev_name = "bq27542",
  109. .swnode = &fg_bq25890_supply_node,
  110. },
  111. .adapter_path = "\\_SB_.PCI0.I2C1",
  112. }, {
  113. /* Goodix Touchscreen in keyboard half */
  114. .board_info = {
  115. .type = "GDIX1001:00",
  116. .addr = 0x14,
  117. .dev_name = "goodix_ts",
  118. .swnode = &lenovo_yb1_x90_goodix_node,
  119. },
  120. .adapter_path = "\\_SB_.PCI0.I2C2",
  121. .irq_data = {
  122. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  123. .chip = "INT33FF:01",
  124. .index = 56,
  125. .trigger = ACPI_EDGE_SENSITIVE,
  126. .polarity = ACPI_ACTIVE_LOW,
  127. .con_id = "goodix_ts_irq",
  128. .free_gpio = true,
  129. },
  130. }, {
  131. /* Wacom Digitizer in keyboard half */
  132. .board_info = {
  133. .type = "hid-over-i2c",
  134. .addr = 0x09,
  135. .dev_name = "wacom",
  136. .swnode = &lenovo_yb1_x90_wacom_node,
  137. },
  138. .adapter_path = "\\_SB_.PCI0.I2C4",
  139. .irq_data = {
  140. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  141. .chip = "INT33FF:01",
  142. .index = 49,
  143. .trigger = ACPI_LEVEL_SENSITIVE,
  144. .polarity = ACPI_ACTIVE_LOW,
  145. .con_id = "wacom_irq",
  146. },
  147. }, {
  148. /* LP8557 Backlight controller */
  149. .board_info = {
  150. .type = "lp8557",
  151. .addr = 0x2c,
  152. .dev_name = "lp8557",
  153. .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
  154. },
  155. .adapter_path = "\\_SB_.PCI0.I2C4",
  156. }, {
  157. /* HiDeep IST940E Touchscreen in display half */
  158. .board_info = {
  159. .type = "hideep_ts",
  160. .addr = 0x6c,
  161. .dev_name = "hideep_ts",
  162. .swnode = &lenovo_yb1_x90_hideep_ts_node,
  163. },
  164. .adapter_path = "\\_SB_.PCI0.I2C6",
  165. .irq_data = {
  166. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  167. .chip = "INT33FF:03",
  168. .index = 77,
  169. .trigger = ACPI_LEVEL_SENSITIVE,
  170. .polarity = ACPI_ACTIVE_LOW,
  171. .con_id = "hideep_ts_irq",
  172. },
  173. },
  174. };
  175. static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
  176. {
  177. .name = "yogabook-touch-kbd-digitizer-switch",
  178. .id = PLATFORM_DEVID_NONE,
  179. },
  180. };
  181. /*
  182. * DSDT says UART path is "\\_SB.PCIO.URT1" with a letter 'O' instead of
  183. * the number '0' add the link manually.
  184. */
  185. static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = {
  186. {
  187. .ctrl.acpi.hid = "8086228A",
  188. .ctrl.acpi.uid = "1",
  189. .ctrl_devname = "serial0",
  190. .serdev_hid = "BCM2E1A",
  191. },
  192. };
  193. /*
  194. * Software node attached to gpio-keys device representing the LID and
  195. * serving as a parent to software nodes representing individual keys/buttons
  196. * as required by the device tree binding.
  197. */
  198. static const struct software_node lenovo_lid_gpio_keys_node = {
  199. .name = "lid_sw",
  200. };
  201. static const struct property_entry lenovo_yb1_x90_lid_props[] = {
  202. PROPERTY_ENTRY_U32("linux,input-type", EV_SW),
  203. PROPERTY_ENTRY_U32("linux,code", SW_LID),
  204. PROPERTY_ENTRY_STRING("label", "lid_sw"),
  205. PROPERTY_ENTRY_GPIO("gpios", &cherryview_gpiochip_nodes[2], 19, GPIO_ACTIVE_LOW),
  206. PROPERTY_ENTRY_U32("debounce-interval", 50),
  207. PROPERTY_ENTRY_BOOL("wakeup-source"),
  208. { }
  209. };
  210. static const struct software_node lenovo_yb1_x90_lid_node = {
  211. .parent = &lenovo_lid_gpio_keys_node,
  212. .properties = lenovo_yb1_x90_lid_props,
  213. };
  214. static const struct software_node *lenovo_yb1_x90_lid_swnodes[] = {
  215. &lenovo_lid_gpio_keys_node,
  216. &lenovo_yb1_x90_lid_node,
  217. NULL
  218. };
  219. static int __init lenovo_yb1_x90_init(struct device *dev)
  220. {
  221. /* Enable the regulators used by the touchscreens */
  222. /* Vprog3B 3.0V used by the goodix touchscreen in the keyboard half */
  223. intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
  224. /* Vprog4D 3.0V used by the HiDeep touchscreen in the display half */
  225. intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9f, 0x02, 0xff);
  226. /* Vprog5A 1.8V used by the HiDeep touchscreen in the display half */
  227. intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
  228. /* Vprog5B 1.8V used by the goodix touchscreen in the keyboard half */
  229. intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa1, 0x02, 0xff);
  230. return 0;
  231. }
  232. const struct x86_dev_info lenovo_yogabook_x90_info __initconst = {
  233. .i2c_client_info = lenovo_yb1_x90_i2c_clients,
  234. .i2c_client_count = ARRAY_SIZE(lenovo_yb1_x90_i2c_clients),
  235. .pdev_info = lenovo_yb1_x90_pdevs,
  236. .pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs),
  237. .serdev_info = lenovo_yb1_x90_serdevs,
  238. .serdev_count = ARRAY_SIZE(lenovo_yb1_x90_serdevs),
  239. .gpio_button_swnodes = lenovo_yb1_x90_lid_swnodes,
  240. .gpiochip_type = X86_GPIOCHIP_CHERRYVIEW,
  241. .init = lenovo_yb1_x90_init,
  242. };
  243. /* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fuel-gauge client */
  244. static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
  245. {
  246. /* BQ27542 fuel-gauge */
  247. .board_info = {
  248. .type = "bq27542",
  249. .addr = 0x55,
  250. .dev_name = "bq27542",
  251. .swnode = &fg_bq25890_supply_node,
  252. },
  253. .adapter_path = "\\_SB_.PCI0.I2C1",
  254. },
  255. };
  256. const struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
  257. .i2c_client_info = lenovo_yogabook_x91_i2c_clients,
  258. .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
  259. };
  260. /* Lenovo Yoga Tablet 2 1050F/L's Android factory image has everything hardcoded */
  261. static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
  262. PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
  263. PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
  264. PROPERTY_ENTRY_BOOL("omit-battery-class"),
  265. PROPERTY_ENTRY_BOOL("disable-reset"),
  266. { }
  267. };
  268. static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
  269. .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
  270. };
  271. static const struct property_entry lenovo_yoga_tab2_830_1050_lid_props[] = {
  272. PROPERTY_ENTRY_U32("linux,input-type", EV_SW),
  273. PROPERTY_ENTRY_U32("linux,code", SW_LID),
  274. PROPERTY_ENTRY_STRING("label", "lid_sw"),
  275. PROPERTY_ENTRY_GPIO("gpios", &baytrail_gpiochip_nodes[2], 26, GPIO_ACTIVE_LOW),
  276. PROPERTY_ENTRY_U32("debounce-interval", 50),
  277. PROPERTY_ENTRY_BOOL("wakeup-source"),
  278. { }
  279. };
  280. static const struct software_node lenovo_yoga_tab2_830_1050_lid_node = {
  281. .parent = &lenovo_lid_gpio_keys_node,
  282. .properties = lenovo_yoga_tab2_830_1050_lid_props,
  283. };
  284. static const struct software_node *lenovo_yoga_tab2_830_1050_lid_swnodes[] = {
  285. &lenovo_lid_gpio_keys_node,
  286. &lenovo_yoga_tab2_830_1050_lid_node,
  287. NULL
  288. };
  289. /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
  290. static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
  291. static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
  292. {
  293. /*
  294. * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
  295. * may update its swnode. LSM303DA accelerometer + magnetometer.
  296. */
  297. .board_info = {
  298. .type = "lsm303d",
  299. .addr = 0x1d,
  300. .dev_name = "lsm303d",
  301. },
  302. .adapter_path = "\\_SB_.I2C5",
  303. }, {
  304. /* AL3320A ambient light sensor */
  305. .board_info = {
  306. .type = "al3320a",
  307. .addr = 0x1c,
  308. .dev_name = "al3320a",
  309. },
  310. .adapter_path = "\\_SB_.I2C5",
  311. }, {
  312. /* bq24292i battery charger */
  313. .board_info = {
  314. .type = "bq24190",
  315. .addr = 0x6b,
  316. .dev_name = "bq24292i",
  317. .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
  318. .platform_data = &bq24190_pdata,
  319. },
  320. .adapter_path = "\\_SB_.I2C1",
  321. .irq_data = {
  322. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  323. .chip = "INT33FC:02",
  324. .index = 2,
  325. .trigger = ACPI_EDGE_SENSITIVE,
  326. .polarity = ACPI_ACTIVE_HIGH,
  327. .con_id = "bq24292i_irq",
  328. },
  329. }, {
  330. /* BQ27541 fuel-gauge */
  331. .board_info = {
  332. .type = "bq27541",
  333. .addr = 0x55,
  334. .dev_name = "bq27541",
  335. .swnode = &fg_bq24190_supply_node,
  336. },
  337. .adapter_path = "\\_SB_.I2C1",
  338. }, {
  339. /* Synaptics RMI touchscreen */
  340. .board_info = {
  341. .type = "rmi4_i2c",
  342. .addr = 0x38,
  343. .dev_name = "rmi4_i2c",
  344. .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
  345. },
  346. .adapter_path = "\\_SB_.I2C6",
  347. .irq_data = {
  348. .type = X86_ACPI_IRQ_TYPE_APIC,
  349. .index = 0x45,
  350. .trigger = ACPI_EDGE_SENSITIVE,
  351. .polarity = ACPI_ACTIVE_HIGH,
  352. },
  353. }, {
  354. /* LP8557 Backlight controller */
  355. .board_info = {
  356. .type = "lp8557",
  357. .addr = 0x2c,
  358. .dev_name = "lp8557",
  359. .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
  360. },
  361. .adapter_path = "\\_SB_.I2C3",
  362. },
  363. };
  364. static const struct property_entry lenovo_yoga_tab2_830_1050_int3496_props[] __initconst = {
  365. PROPERTY_ENTRY_GPIO("mux-gpios", &baytrail_gpiochip_nodes[2], 1, GPIO_ACTIVE_LOW),
  366. PROPERTY_ENTRY_GPIO("id-gpios", &baytrail_gpiochip_nodes[2], 24, GPIO_ACTIVE_HIGH),
  367. { }
  368. };
  369. static const struct platform_device_info lenovo_yoga_tab2_830_1050_pdevs[] __initconst = {
  370. {
  371. /* For micro USB ID pin handling */
  372. .name = "intel-int3496",
  373. .id = PLATFORM_DEVID_NONE,
  374. .properties = lenovo_yoga_tab2_830_1050_int3496_props,
  375. },
  376. };
  377. #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
  378. static const struct property_entry lenovo_yoga_tab2_830_1050_wm1502_props[] = {
  379. PROPERTY_ENTRY_GPIO("reset-gpios",
  380. &crystalcove_gpiochip_node, 3, GPIO_ACTIVE_HIGH),
  381. PROPERTY_ENTRY_GPIO("wlf,ldoena-gpios",
  382. &baytrail_gpiochip_nodes[1], 23, GPIO_ACTIVE_HIGH),
  383. PROPERTY_ENTRY_GPIO("wlf,spkvdd-ena-gpios",
  384. &arizona_gpiochip_node, 2, GPIO_ACTIVE_HIGH),
  385. PROPERTY_ENTRY_GPIO("wlf,micd-pol-gpios",
  386. &arizona_gpiochip_node, 4, GPIO_ACTIVE_LOW),
  387. { }
  388. };
  389. static const struct software_node lenovo_yoga_tab2_830_1050_wm5102 = {
  390. .properties = lenovo_yoga_tab2_830_1050_wm1502_props,
  391. };
  392. static const struct software_node *lenovo_yoga_tab2_830_1050_swnodes[] = {
  393. &crystalcove_gpiochip_node,
  394. &arizona_gpiochip_node,
  395. &lenovo_yoga_tab2_830_1050_wm5102,
  396. &generic_lipo_hv_4v35_battery_node,
  397. NULL
  398. };
  399. static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev);
  400. static void lenovo_yoga_tab2_830_1050_exit(void);
  401. static const char * const lenovo_yoga_tab2_modules[] __initconst = {
  402. "spi_pxa2xx_platform", /* For the SPI codec device */
  403. "bq24190_charger", /* For the Vbus regulator for int3496/lc824206xa */
  404. NULL
  405. };
  406. const struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = {
  407. .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
  408. .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients),
  409. .pdev_info = lenovo_yoga_tab2_830_1050_pdevs,
  410. .pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_pdevs),
  411. .gpio_button_swnodes = lenovo_yoga_tab2_830_1050_lid_swnodes,
  412. .swnode_group = lenovo_yoga_tab2_830_1050_swnodes,
  413. .modules = lenovo_yoga_tab2_modules,
  414. .gpiochip_type = X86_GPIOCHIP_BAYTRAIL,
  415. .init = lenovo_yoga_tab2_830_1050_init,
  416. .exit = lenovo_yoga_tab2_830_1050_exit,
  417. };
  418. /*
  419. * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
  420. * mainboard, but the 830 uses a portrait LCD panel with a landscape touchscreen,
  421. * requiring the touchscreen driver to adjust the touch-coords to match the LCD.
  422. * And requiring the accelerometer to have a mount-matrix set to correct for
  423. * the 90° rotation of the LCD vs the frame.
  424. */
  425. static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
  426. "0", "1", "0",
  427. "-1", "0", "0",
  428. "0", "0", "1"
  429. };
  430. static const struct property_entry lenovo_yoga_tab2_830_lms303d_props[] = {
  431. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_830_lms303d_mount_matrix),
  432. { }
  433. };
  434. static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
  435. .properties = lenovo_yoga_tab2_830_lms303d_props,
  436. };
  437. static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
  438. {
  439. struct gpio_desc *gpiod;
  440. int ret;
  441. /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
  442. ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, "yoga_bootstrap",
  443. false, GPIOD_ASIS, &gpiod);
  444. if (ret)
  445. return ret;
  446. ret = gpiod_get_value_cansleep(gpiod);
  447. if (ret) {
  448. pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
  449. } else {
  450. pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
  451. lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
  452. lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
  453. lenovo_yoga_tab2_830_1050_i2c_clients[0].board_info.swnode =
  454. &lenovo_yoga_tab2_830_lms303d_node;
  455. }
  456. return 0;
  457. }
  458. /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
  459. static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
  460. PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
  461. "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
  462. static struct device *lenovo_yoga_tab2_830_1050_codec_dev;
  463. static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
  464. static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
  465. static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
  466. {
  467. struct device *codec_dev;
  468. struct pinctrl *pinctrl;
  469. int ret;
  470. codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
  471. LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
  472. if (!codec_dev) {
  473. pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
  474. return -ENODEV;
  475. }
  476. ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
  477. if (ret)
  478. goto err_put_device;
  479. pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
  480. if (IS_ERR(pinctrl)) {
  481. ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
  482. goto err_unregister_mappings;
  483. }
  484. ret = device_add_software_node(codec_dev, &lenovo_yoga_tab2_830_1050_wm5102);
  485. if (ret) {
  486. dev_err_probe(codec_dev, ret, "adding software node\n");
  487. goto err_put_pinctrl;
  488. }
  489. lenovo_yoga_tab2_830_1050_codec_dev = codec_dev;
  490. lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
  491. return 0;
  492. err_put_pinctrl:
  493. pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
  494. err_unregister_mappings:
  495. pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
  496. err_put_device:
  497. put_device(codec_dev);
  498. return ret;
  499. }
  500. /*
  501. * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off()
  502. * gets used as pm_power_off handler. This causes "poweroff" on these tablets
  503. * to hang hard. Requiring pressing the power button for 30 seconds *twice*
  504. * followed by a normal 3 second press to recover. Avoid this by doing an EFI
  505. * poweroff instead.
  506. */
  507. static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
  508. {
  509. efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
  510. return NOTIFY_DONE;
  511. }
  512. static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev)
  513. {
  514. int ret;
  515. ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
  516. if (ret)
  517. return ret;
  518. ret = lenovo_yoga_tab2_830_1050_init_codec();
  519. if (ret)
  520. return ret;
  521. /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off() */
  522. lenovo_yoga_tab2_830_1050_sys_off_handler =
  523. register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
  524. lenovo_yoga_tab2_830_1050_power_off, NULL);
  525. if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
  526. return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
  527. return 0;
  528. }
  529. static void lenovo_yoga_tab2_830_1050_exit(void)
  530. {
  531. unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
  532. device_remove_software_node(lenovo_yoga_tab2_830_1050_codec_dev);
  533. pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
  534. pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
  535. put_device(lenovo_yoga_tab2_830_1050_codec_dev);
  536. }
  537. /*
  538. * Lenovo Yoga Tablet 2 Pro 1380F/L
  539. *
  540. * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L
  541. * and the 1050F/L so this re-uses some of the handling for that from above.
  542. */
  543. static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" };
  544. static const struct property_entry lenovo_yoga_tab2_1380_bq24190_props[] = {
  545. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lc824206xa_chg_det_psy),
  546. PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
  547. PROPERTY_ENTRY_BOOL("omit-battery-class"),
  548. PROPERTY_ENTRY_BOOL("disable-reset"),
  549. { }
  550. };
  551. static const struct software_node lenovo_yoga_tab2_1380_bq24190_node = {
  552. .properties = lenovo_yoga_tab2_1380_bq24190_props,
  553. };
  554. /* For enabling the bq24190 5V boost based on id-pin */
  555. static struct regulator_consumer_supply lc824206xa_consumer = {
  556. .supply = "vbus",
  557. .dev_name = "i2c-lc824206xa",
  558. };
  559. static const struct regulator_init_data lenovo_yoga_tab2_1380_bq24190_vbus_init_data = {
  560. .constraints = {
  561. .name = "bq24190_vbus",
  562. .valid_ops_mask = REGULATOR_CHANGE_STATUS,
  563. },
  564. .consumer_supplies = &lc824206xa_consumer,
  565. .num_consumer_supplies = 1,
  566. };
  567. static struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = {
  568. .regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data,
  569. };
  570. static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = {
  571. PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"),
  572. { }
  573. };
  574. static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = {
  575. .properties = lenovo_yoga_tab2_1380_lc824206xa_props,
  576. };
  577. static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = {
  578. "0", "-1", "0",
  579. "-1", "0", "0",
  580. "0", "0", "1"
  581. };
  582. static const struct property_entry lenovo_yoga_tab2_1380_lms303d_props[] = {
  583. PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_1380_lms303d_mount_matrix),
  584. { }
  585. };
  586. static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = {
  587. .properties = lenovo_yoga_tab2_1380_lms303d_props,
  588. };
  589. static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __initconst = {
  590. {
  591. /* BQ27541 fuel-gauge */
  592. .board_info = {
  593. .type = "bq27541",
  594. .addr = 0x55,
  595. .dev_name = "bq27541",
  596. .swnode = &fg_bq24190_supply_node,
  597. },
  598. .adapter_path = "\\_SB_.I2C1",
  599. }, {
  600. /* bq24292i battery charger */
  601. .board_info = {
  602. .type = "bq24190",
  603. .addr = 0x6b,
  604. .dev_name = "bq24292i",
  605. .swnode = &lenovo_yoga_tab2_1380_bq24190_node,
  606. .platform_data = &lenovo_yoga_tab2_1380_bq24190_pdata,
  607. },
  608. .adapter_path = "\\_SB_.I2C1",
  609. .irq_data = {
  610. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  611. .chip = "INT33FC:02",
  612. .index = 2,
  613. .trigger = ACPI_EDGE_SENSITIVE,
  614. .polarity = ACPI_ACTIVE_HIGH,
  615. .con_id = "bq24292i_irq",
  616. },
  617. }, {
  618. /* LP8557 Backlight controller */
  619. .board_info = {
  620. .type = "lp8557",
  621. .addr = 0x2c,
  622. .dev_name = "lp8557",
  623. .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
  624. },
  625. .adapter_path = "\\_SB_.I2C3",
  626. }, {
  627. /* LC824206XA Micro USB Switch */
  628. .board_info = {
  629. .type = "lc824206xa",
  630. .addr = 0x48,
  631. .dev_name = "lc824206xa",
  632. .swnode = &lenovo_yoga_tab2_1380_lc824206xa_node,
  633. },
  634. .adapter_path = "\\_SB_.I2C3",
  635. .irq_data = {
  636. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  637. .chip = "INT33FC:02",
  638. .index = 1,
  639. .trigger = ACPI_LEVEL_SENSITIVE,
  640. .polarity = ACPI_ACTIVE_LOW,
  641. .con_id = "lc824206xa_irq",
  642. },
  643. }, {
  644. /* AL3320A ambient light sensor */
  645. .board_info = {
  646. .type = "al3320a",
  647. .addr = 0x1c,
  648. .dev_name = "al3320a",
  649. },
  650. .adapter_path = "\\_SB_.I2C5",
  651. }, {
  652. /* LSM303DA accelerometer + magnetometer */
  653. .board_info = {
  654. .type = "lsm303d",
  655. .addr = 0x1d,
  656. .dev_name = "lsm303d",
  657. .swnode = &lenovo_yoga_tab2_1380_lms303d_node,
  658. },
  659. .adapter_path = "\\_SB_.I2C5",
  660. }, {
  661. /* Synaptics RMI touchscreen */
  662. .board_info = {
  663. .type = "rmi4_i2c",
  664. .addr = 0x38,
  665. .dev_name = "rmi4_i2c",
  666. .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
  667. },
  668. .adapter_path = "\\_SB_.I2C6",
  669. .irq_data = {
  670. .type = X86_ACPI_IRQ_TYPE_APIC,
  671. .index = 0x45,
  672. .trigger = ACPI_EDGE_SENSITIVE,
  673. .polarity = ACPI_ACTIVE_HIGH,
  674. },
  675. }
  676. };
  677. static const struct property_entry lenovo_yoga_tab2_1380_fc_props[] __initconst = {
  678. PROPERTY_ENTRY_GPIO("uart3_txd-gpios", &baytrail_gpiochip_nodes[0], 57, GPIO_ACTIVE_HIGH),
  679. PROPERTY_ENTRY_GPIO("uart3_rxd-gpios", &baytrail_gpiochip_nodes[0], 61, GPIO_ACTIVE_HIGH),
  680. { }
  681. };
  682. static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = {
  683. {
  684. /* For the Tablet 2 Pro 1380's custom fast charging driver */
  685. .name = "lenovo-yoga-tab2-pro-1380-fastcharger",
  686. .id = PLATFORM_DEVID_NONE,
  687. .properties = lenovo_yoga_tab2_1380_fc_props,
  688. },
  689. };
  690. static int __init lenovo_yoga_tab2_1380_init(struct device *dev)
  691. {
  692. int ret;
  693. /* To verify that the DMI matching works vs the 830 / 1050 models */
  694. pr_info("detected Lenovo Yoga Tablet 2 Pro 1380F/L\n");
  695. ret = lenovo_yoga_tab2_830_1050_init_codec();
  696. if (ret)
  697. return ret;
  698. /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off() */
  699. lenovo_yoga_tab2_830_1050_sys_off_handler =
  700. register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
  701. lenovo_yoga_tab2_830_1050_power_off, NULL);
  702. if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
  703. return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
  704. return 0;
  705. }
  706. const struct x86_dev_info lenovo_yoga_tab2_1380_info __initconst = {
  707. .i2c_client_info = lenovo_yoga_tab2_1380_i2c_clients,
  708. .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_i2c_clients),
  709. .pdev_info = lenovo_yoga_tab2_1380_pdevs,
  710. .pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_pdevs),
  711. .gpio_button_swnodes = lenovo_yoga_tab2_830_1050_lid_swnodes,
  712. .swnode_group = lenovo_yoga_tab2_830_1050_swnodes,
  713. .modules = lenovo_yoga_tab2_modules,
  714. .gpiochip_type = X86_GPIOCHIP_BAYTRAIL,
  715. .init = lenovo_yoga_tab2_1380_init,
  716. .exit = lenovo_yoga_tab2_830_1050_exit,
  717. };
  718. /* Lenovo Yoga Tab 3 Pro YT3-X90F */
  719. /*
  720. * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
  721. * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
  722. */
  723. static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
  724. static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
  725. static const struct property_entry fg_bq25890_1_supply_props[] = {
  726. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
  727. { }
  728. };
  729. static const struct software_node fg_bq25890_1_supply_node = {
  730. .properties = fg_bq25890_1_supply_props,
  731. };
  732. /* bq25892 charger settings for the flat LiPo battery behind the screen */
  733. static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
  734. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
  735. PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
  736. PROPERTY_ENTRY_BOOL("linux,skip-reset"),
  737. /* Values taken from Android Factory Image */
  738. PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
  739. PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
  740. PROPERTY_ENTRY_U32("ti,termination-current", 128000),
  741. PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
  742. PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
  743. PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
  744. PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
  745. PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
  746. { }
  747. };
  748. static const struct software_node lenovo_yt3_bq25892_0_node = {
  749. .properties = lenovo_yt3_bq25892_0_props,
  750. };
  751. static const struct property_entry lenovo_yt3_hideep_ts_props[] = {
  752. PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
  753. PROPERTY_ENTRY_U32("touchscreen-size-y", 2560),
  754. PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255),
  755. PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 7, GPIO_ACTIVE_LOW),
  756. { }
  757. };
  758. static const struct software_node lenovo_yt3_hideep_ts_node = {
  759. .properties = lenovo_yt3_hideep_ts_props,
  760. };
  761. static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
  762. {
  763. /* bq27500 fuel-gauge for the flat LiPo battery behind the screen */
  764. .board_info = {
  765. .type = "bq27500",
  766. .addr = 0x55,
  767. .dev_name = "bq27500_0",
  768. .swnode = &fg_bq25890_supply_node,
  769. },
  770. .adapter_path = "\\_SB_.PCI0.I2C1",
  771. }, {
  772. /* bq25892 charger for the flat LiPo battery behind the screen */
  773. .board_info = {
  774. .type = "bq25892",
  775. .addr = 0x6b,
  776. .dev_name = "bq25892_0",
  777. .swnode = &lenovo_yt3_bq25892_0_node,
  778. },
  779. .adapter_path = "\\_SB_.PCI0.I2C1",
  780. .irq_data = {
  781. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  782. .chip = "INT33FF:01",
  783. .index = 5,
  784. .trigger = ACPI_EDGE_SENSITIVE,
  785. .polarity = ACPI_ACTIVE_LOW,
  786. .con_id = "bq25892_0_irq",
  787. },
  788. }, {
  789. /* bq27500 fuel-gauge for the round Li-ion cells in the hinge */
  790. .board_info = {
  791. .type = "bq27500",
  792. .addr = 0x55,
  793. .dev_name = "bq27500_1",
  794. .swnode = &fg_bq25890_1_supply_node,
  795. },
  796. .adapter_path = "\\_SB_.PCI0.I2C2",
  797. }, {
  798. /* HiDeep IST520E Touchscreen */
  799. .board_info = {
  800. .type = "hideep_ts",
  801. .addr = 0x6c,
  802. .dev_name = "hideep_ts",
  803. .swnode = &lenovo_yt3_hideep_ts_node,
  804. },
  805. .adapter_path = "\\_SB_.PCI0.I2C6",
  806. .irq_data = {
  807. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  808. .chip = "INT33FF:03",
  809. .index = 77,
  810. .trigger = ACPI_LEVEL_SENSITIVE,
  811. .polarity = ACPI_ACTIVE_LOW,
  812. .con_id = "hideep_ts_irq",
  813. },
  814. }, {
  815. /* LP8557 Backlight controller */
  816. .board_info = {
  817. .type = "lp8557",
  818. .addr = 0x2c,
  819. .dev_name = "lp8557",
  820. .platform_data = &lenovo_lp8557_reg_only_pdata,
  821. },
  822. .adapter_path = "\\_SB_.PCI0.I2C1",
  823. }
  824. };
  825. /*
  826. * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
  827. * Function A Play/Pause: 0 ohm
  828. * Function D Voice assistant: 135 ohm
  829. * Function B Volume Up 240 ohm
  830. * Function C Volume Down 470 ohm
  831. * Minimum Mic DC resistance 1000 ohm
  832. * Minimum Ear speaker impedance 16 ohm
  833. * Note the first max value below must be less then the min. speaker impedance,
  834. * to allow CTIA/OMTP detection to work. The other max values are the closest
  835. * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
  836. */
  837. static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
  838. { .max = 11, .key = KEY_PLAYPAUSE },
  839. { .max = 186, .key = KEY_VOICECOMMAND },
  840. { .max = 348, .key = KEY_VOLUMEUP },
  841. { .max = 752, .key = KEY_VOLUMEDOWN },
  842. };
  843. /* YT3 WM5102 arizona_micd_config comes from Android kernel sources */
  844. static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[] = {
  845. { 0, 1, 0 },
  846. { ARIZONA_ACCDET_SRC, 2, 1 },
  847. };
  848. static struct arizona_pdata lenovo_yt3_wm5102_pdata = {
  849. .irq_flags = IRQF_TRIGGER_LOW,
  850. .micd_detect_debounce = 200,
  851. .micd_ranges = arizona_micd_aosp_ranges,
  852. .num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges),
  853. .hpdet_channel = ARIZONA_ACCDET_MODE_HPL,
  854. /* Below settings come from Android kernel sources */
  855. .micd_bias_start_time = 1,
  856. .micd_rate = 6,
  857. .micd_configs = lenovo_yt3_wm5102_micd_config,
  858. .num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config),
  859. .micbias = {
  860. [0] = { /* MICBIAS1 */
  861. .mV = 2800,
  862. .ext_cap = 1,
  863. .discharge = 1,
  864. .soft_start = 0,
  865. .bypass = 0,
  866. },
  867. [1] = { /* MICBIAS2 */
  868. .mV = 2800,
  869. .ext_cap = 1,
  870. .discharge = 1,
  871. .soft_start = 0,
  872. .bypass = 0,
  873. },
  874. [2] = { /* MICBIAS2 */
  875. .mV = 2800,
  876. .ext_cap = 1,
  877. .discharge = 1,
  878. .soft_start = 0,
  879. .bypass = 0,
  880. },
  881. },
  882. };
  883. static const struct property_entry lenovo_yt3_wm1502_props[] = {
  884. PROPERTY_ENTRY_GPIO("wlf,spkvdd-ena-gpios",
  885. &cherryview_gpiochip_nodes[0], 75, GPIO_ACTIVE_HIGH),
  886. PROPERTY_ENTRY_GPIO("wlf,ldoena-gpios",
  887. &cherryview_gpiochip_nodes[0], 81, GPIO_ACTIVE_HIGH),
  888. PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 82, GPIO_ACTIVE_HIGH),
  889. PROPERTY_ENTRY_GPIO("wlf,micd-pol-gpios", &arizona_gpiochip_node, 2, GPIO_ACTIVE_HIGH),
  890. { }
  891. };
  892. static const struct software_node lenovo_yt3_wm5102 = {
  893. .properties = lenovo_yt3_wm1502_props,
  894. .name = "wm5102",
  895. };
  896. static const struct software_node *lenovo_yt3_swnodes[] = {
  897. &arizona_gpiochip_node,
  898. &lenovo_yt3_wm5102,
  899. NULL
  900. };
  901. static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = {
  902. {
  903. /* WM5102 codec */
  904. .board_info = {
  905. .modalias = "wm5102",
  906. .platform_data = &lenovo_yt3_wm5102_pdata,
  907. .swnode = &lenovo_yt3_wm5102,
  908. .max_speed_hz = 5000000,
  909. },
  910. .ctrl_path = "\\_SB_.PCI0.SPI1",
  911. .irq_data = {
  912. .type = X86_ACPI_IRQ_TYPE_GPIOINT,
  913. .chip = "INT33FF:00",
  914. .index = 91,
  915. .trigger = ACPI_LEVEL_SENSITIVE,
  916. .polarity = ACPI_ACTIVE_LOW,
  917. .con_id = "wm5102_irq",
  918. },
  919. }
  920. };
  921. static int __init lenovo_yt3_init(struct device *dev)
  922. {
  923. int ret;
  924. /*
  925. * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
  926. * connected to GPIOs, rather then having them hardwired to the correct
  927. * values as is normally done.
  928. *
  929. * The bq25890_charger driver controls these through I2C, but this only
  930. * works if not overridden by the pins. Set these pins here:
  931. * 1. Set /CE to 1 to allow charging.
  932. * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
  933. * the main "bq25892_1" charger is used when necessary.
  934. */
  935. /* /CE pin */
  936. ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, "bq25892_0_ce",
  937. true, GPIOD_OUT_HIGH, NULL);
  938. if (ret < 0)
  939. return ret;
  940. /* OTG pin */
  941. ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, "bq25892_0_otg",
  942. false, GPIOD_OUT_LOW, NULL);
  943. if (ret < 0)
  944. return ret;
  945. /* Enable the regulators used by the touchscreen */
  946. intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
  947. intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
  948. return 0;
  949. }
  950. static const char * const lenovo_yt3_modules[] __initconst = {
  951. "spi_pxa2xx_platform", /* For the SPI codec device */
  952. NULL
  953. };
  954. const struct x86_dev_info lenovo_yt3_info __initconst = {
  955. .i2c_client_info = lenovo_yt3_i2c_clients,
  956. .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
  957. .spi_dev_info = lenovo_yt3_spi_devs,
  958. .spi_dev_count = ARRAY_SIZE(lenovo_yt3_spi_devs),
  959. .swnode_group = lenovo_yt3_swnodes,
  960. .modules = lenovo_yt3_modules,
  961. .gpiochip_type = X86_GPIOCHIP_CHERRYVIEW,
  962. .init = lenovo_yt3_init,
  963. };