| 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | /* |
| 3 | * Board info for Asus 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 | |
| 11 | #include <linux/gpio/machine.h> |
| 12 | #include <linux/gpio/property.h> |
| 13 | #include <linux/input-event-codes.h> |
| 14 | #include <linux/platform_device.h> |
| 15 | |
| 16 | #include "shared-psy-info.h" |
| 17 | #include "x86-android-tablets.h" |
| 18 | |
| 19 | /* Asus ME176C and TF103C tablets shared data */ |
| 20 | static const struct property_entry asus_me176c_tf103c_int3496_props[] __initconst = { |
| 21 | PROPERTY_ENTRY_GPIO("id-gpios" , &baytrail_gpiochip_nodes[2], 22, GPIO_ACTIVE_HIGH), |
| 22 | { } |
| 23 | }; |
| 24 | |
| 25 | static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = { |
| 26 | { |
| 27 | /* For micro USB ID pin handling */ |
| 28 | .name = "intel-int3496" , |
| 29 | .id = PLATFORM_DEVID_NONE, |
| 30 | .properties = asus_me176c_tf103c_int3496_props, |
| 31 | }, |
| 32 | }; |
| 33 | |
| 34 | static const struct software_node asus_me176c_tf103c_gpio_keys_node = { |
| 35 | .name = "lid_sw" , |
| 36 | }; |
| 37 | |
| 38 | static const struct property_entry asus_me176c_tf103c_lid_props[] = { |
| 39 | PROPERTY_ENTRY_U32("linux,input-type" , EV_SW), |
| 40 | PROPERTY_ENTRY_U32("linux,code" , SW_LID), |
| 41 | PROPERTY_ENTRY_STRING("label" , "lid_sw" ), |
| 42 | PROPERTY_ENTRY_GPIO("gpios" , &baytrail_gpiochip_nodes[2], 12, GPIO_ACTIVE_LOW), |
| 43 | PROPERTY_ENTRY_U32("debounce-interval" , 50), |
| 44 | PROPERTY_ENTRY_BOOL("wakeup-source" ), |
| 45 | { } |
| 46 | }; |
| 47 | |
| 48 | static const struct software_node asus_me176c_tf103c_lid_node = { |
| 49 | .parent = &asus_me176c_tf103c_gpio_keys_node, |
| 50 | .properties = asus_me176c_tf103c_lid_props, |
| 51 | }; |
| 52 | |
| 53 | static const struct software_node *asus_me176c_tf103c_lid_swnodes[] = { |
| 54 | &asus_me176c_tf103c_gpio_keys_node, |
| 55 | &asus_me176c_tf103c_lid_node, |
| 56 | NULL |
| 57 | }; |
| 58 | |
| 59 | /* Asus ME176C tablets have an Android factory image with everything hardcoded */ |
| 60 | static const char * const asus_me176c_accel_mount_matrix[] = { |
| 61 | "-1" , "0" , "0" , |
| 62 | "0" , "1" , "0" , |
| 63 | "0" , "0" , "1" |
| 64 | }; |
| 65 | |
| 66 | static const struct property_entry asus_me176c_accel_props[] = { |
| 67 | PROPERTY_ENTRY_STRING_ARRAY("mount-matrix" , asus_me176c_accel_mount_matrix), |
| 68 | { } |
| 69 | }; |
| 70 | |
| 71 | static const struct software_node asus_me176c_accel_node = { |
| 72 | .properties = asus_me176c_accel_props, |
| 73 | }; |
| 74 | |
| 75 | static const struct property_entry asus_me176c_bq24190_props[] = { |
| 76 | PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from" , tusb1211_chg_det_psy, 1), |
| 77 | PROPERTY_ENTRY_REF("monitored-battery" , &generic_lipo_hv_4v35_battery_node), |
| 78 | PROPERTY_ENTRY_U32("ti,system-minimum-microvolt" , 3600000), |
| 79 | PROPERTY_ENTRY_BOOL("omit-battery-class" ), |
| 80 | PROPERTY_ENTRY_BOOL("disable-reset" ), |
| 81 | { } |
| 82 | }; |
| 83 | |
| 84 | static const struct software_node asus_me176c_bq24190_node = { |
| 85 | .properties = asus_me176c_bq24190_props, |
| 86 | }; |
| 87 | |
| 88 | static const struct property_entry asus_me176c_ug3105_props[] = { |
| 89 | PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from" , bq24190_psy, 1), |
| 90 | PROPERTY_ENTRY_REF("monitored-battery" , &generic_lipo_hv_4v35_battery_node), |
| 91 | PROPERTY_ENTRY_U32("upisemi,rsns-microohm" , 10000), |
| 92 | { } |
| 93 | }; |
| 94 | |
| 95 | static const struct software_node asus_me176c_ug3105_node = { |
| 96 | .properties = asus_me176c_ug3105_props, |
| 97 | }; |
| 98 | |
| 99 | static const struct property_entry asus_me176c_touchscreen_props[] = { |
| 100 | PROPERTY_ENTRY_GPIO("reset-gpios" , &baytrail_gpiochip_nodes[0], 60, GPIO_ACTIVE_HIGH), |
| 101 | PROPERTY_ENTRY_GPIO("irq-gpios" , &baytrail_gpiochip_nodes[2], 28, GPIO_ACTIVE_HIGH), |
| 102 | { } |
| 103 | }; |
| 104 | |
| 105 | static const struct software_node asus_me176c_touchscreen_node = { |
| 106 | .properties = asus_me176c_touchscreen_props, |
| 107 | }; |
| 108 | |
| 109 | static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = { |
| 110 | { |
| 111 | /* bq24297 battery charger */ |
| 112 | .board_info = { |
| 113 | .type = "bq24190" , |
| 114 | .addr = 0x6b, |
| 115 | .dev_name = "bq24297" , |
| 116 | .swnode = &asus_me176c_bq24190_node, |
| 117 | .platform_data = &bq24190_pdata, |
| 118 | }, |
| 119 | .adapter_path = "\\_SB_.I2C1" , |
| 120 | .irq_data = { |
| 121 | .type = X86_ACPI_IRQ_TYPE_PMIC, |
| 122 | .chip = "\\_SB_.I2C7.PMIC" , |
| 123 | .domain = DOMAIN_BUS_WAKEUP, |
| 124 | .index = 0, |
| 125 | }, |
| 126 | }, { |
| 127 | /* ug3105 battery monitor */ |
| 128 | .board_info = { |
| 129 | .type = "ug3105" , |
| 130 | .addr = 0x70, |
| 131 | .dev_name = "ug3105" , |
| 132 | .swnode = &asus_me176c_ug3105_node, |
| 133 | }, |
| 134 | .adapter_path = "\\_SB_.I2C1" , |
| 135 | }, { |
| 136 | /* ak09911 compass */ |
| 137 | .board_info = { |
| 138 | .type = "ak09911" , |
| 139 | .addr = 0x0c, |
| 140 | .dev_name = "ak09911" , |
| 141 | }, |
| 142 | .adapter_path = "\\_SB_.I2C5" , |
| 143 | }, { |
| 144 | /* kxtj21009 accelerometer */ |
| 145 | .board_info = { |
| 146 | .type = "kxtj21009" , |
| 147 | .addr = 0x0f, |
| 148 | .dev_name = "kxtj21009" , |
| 149 | .swnode = &asus_me176c_accel_node, |
| 150 | }, |
| 151 | .adapter_path = "\\_SB_.I2C5" , |
| 152 | .irq_data = { |
| 153 | .type = X86_ACPI_IRQ_TYPE_APIC, |
| 154 | .index = 0x44, |
| 155 | .trigger = ACPI_EDGE_SENSITIVE, |
| 156 | .polarity = ACPI_ACTIVE_LOW, |
| 157 | }, |
| 158 | }, { |
| 159 | /* goodix touchscreen */ |
| 160 | .board_info = { |
| 161 | .type = "GDIX1001:00" , |
| 162 | .addr = 0x14, |
| 163 | .dev_name = "goodix_ts" , |
| 164 | .swnode = &asus_me176c_touchscreen_node, |
| 165 | }, |
| 166 | .adapter_path = "\\_SB_.I2C6" , |
| 167 | .irq_data = { |
| 168 | .type = X86_ACPI_IRQ_TYPE_APIC, |
| 169 | .index = 0x45, |
| 170 | .trigger = ACPI_EDGE_SENSITIVE, |
| 171 | .polarity = ACPI_ACTIVE_LOW, |
| 172 | }, |
| 173 | }, |
| 174 | }; |
| 175 | |
| 176 | static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = { |
| 177 | { |
| 178 | .ctrl.acpi.hid = "80860F0A" , |
| 179 | .ctrl.acpi.uid = "2" , |
| 180 | .ctrl_devname = "serial0" , |
| 181 | .serdev_hid = "BCM2E3A" , |
| 182 | }, |
| 183 | }; |
| 184 | |
| 185 | const struct x86_dev_info asus_me176c_info __initconst = { |
| 186 | .i2c_client_info = asus_me176c_i2c_clients, |
| 187 | .i2c_client_count = ARRAY_SIZE(asus_me176c_i2c_clients), |
| 188 | .pdev_info = asus_me176c_tf103c_pdevs, |
| 189 | .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), |
| 190 | .serdev_info = asus_me176c_serdevs, |
| 191 | .serdev_count = ARRAY_SIZE(asus_me176c_serdevs), |
| 192 | .gpio_button_swnodes = asus_me176c_tf103c_lid_swnodes, |
| 193 | .swnode_group = generic_lipo_hv_4v35_battery_swnodes, |
| 194 | .modules = bq24190_modules, |
| 195 | .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, |
| 196 | }; |
| 197 | |
| 198 | /* Asus TF103C tablets have an Android factory image with everything hardcoded */ |
| 199 | static const char * const asus_tf103c_accel_mount_matrix[] = { |
| 200 | "0" , "-1" , "0" , |
| 201 | "-1" , "0" , "0" , |
| 202 | "0" , "0" , "1" |
| 203 | }; |
| 204 | |
| 205 | static const struct property_entry asus_tf103c_accel_props[] = { |
| 206 | PROPERTY_ENTRY_STRING_ARRAY("mount-matrix" , asus_tf103c_accel_mount_matrix), |
| 207 | { } |
| 208 | }; |
| 209 | |
| 210 | static const struct software_node asus_tf103c_accel_node = { |
| 211 | .properties = asus_tf103c_accel_props, |
| 212 | }; |
| 213 | |
| 214 | static const struct property_entry asus_tf103c_touchscreen_props[] = { |
| 215 | PROPERTY_ENTRY_STRING("compatible" , "atmel,atmel_mxt_ts" ), |
| 216 | { } |
| 217 | }; |
| 218 | |
| 219 | static const struct software_node asus_tf103c_touchscreen_node = { |
| 220 | .properties = asus_tf103c_touchscreen_props, |
| 221 | }; |
| 222 | |
| 223 | static const struct property_entry asus_tf103c_bq24190_props[] = { |
| 224 | PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from" , tusb1211_chg_det_psy, 1), |
| 225 | PROPERTY_ENTRY_REF("monitored-battery" , &generic_lipo_4v2_battery_node), |
| 226 | PROPERTY_ENTRY_U32("ti,system-minimum-microvolt" , 3600000), |
| 227 | PROPERTY_ENTRY_BOOL("omit-battery-class" ), |
| 228 | PROPERTY_ENTRY_BOOL("disable-reset" ), |
| 229 | { } |
| 230 | }; |
| 231 | |
| 232 | static const struct software_node asus_tf103c_bq24190_node = { |
| 233 | .properties = asus_tf103c_bq24190_props, |
| 234 | }; |
| 235 | |
| 236 | static const struct property_entry asus_tf103c_ug3105_props[] = { |
| 237 | PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from" , bq24190_psy, 1), |
| 238 | PROPERTY_ENTRY_REF("monitored-battery" , &generic_lipo_4v2_battery_node), |
| 239 | PROPERTY_ENTRY_U32("upisemi,rsns-microohm" , 5000), |
| 240 | { } |
| 241 | }; |
| 242 | |
| 243 | static const struct software_node asus_tf103c_ug3105_node = { |
| 244 | .properties = asus_tf103c_ug3105_props, |
| 245 | }; |
| 246 | |
| 247 | static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = { |
| 248 | { |
| 249 | /* bq24297 battery charger */ |
| 250 | .board_info = { |
| 251 | .type = "bq24190" , |
| 252 | .addr = 0x6b, |
| 253 | .dev_name = "bq24297" , |
| 254 | .swnode = &asus_tf103c_bq24190_node, |
| 255 | .platform_data = &bq24190_pdata, |
| 256 | }, |
| 257 | .adapter_path = "\\_SB_.I2C1" , |
| 258 | .irq_data = { |
| 259 | .type = X86_ACPI_IRQ_TYPE_PMIC, |
| 260 | .chip = "\\_SB_.I2C7.PMIC" , |
| 261 | .domain = DOMAIN_BUS_WAKEUP, |
| 262 | .index = 0, |
| 263 | }, |
| 264 | }, { |
| 265 | /* ug3105 battery monitor */ |
| 266 | .board_info = { |
| 267 | .type = "ug3105" , |
| 268 | .addr = 0x70, |
| 269 | .dev_name = "ug3105" , |
| 270 | .swnode = &asus_tf103c_ug3105_node, |
| 271 | }, |
| 272 | .adapter_path = "\\_SB_.I2C1" , |
| 273 | }, { |
| 274 | /* ak09911 compass */ |
| 275 | .board_info = { |
| 276 | .type = "ak09911" , |
| 277 | .addr = 0x0c, |
| 278 | .dev_name = "ak09911" , |
| 279 | }, |
| 280 | .adapter_path = "\\_SB_.I2C5" , |
| 281 | }, { |
| 282 | /* kxtj21009 accelerometer */ |
| 283 | .board_info = { |
| 284 | .type = "kxtj21009" , |
| 285 | .addr = 0x0f, |
| 286 | .dev_name = "kxtj21009" , |
| 287 | .swnode = &asus_tf103c_accel_node, |
| 288 | }, |
| 289 | .adapter_path = "\\_SB_.I2C5" , |
| 290 | }, { |
| 291 | /* atmel touchscreen */ |
| 292 | .board_info = { |
| 293 | .type = "atmel_mxt_ts" , |
| 294 | .addr = 0x4a, |
| 295 | .dev_name = "atmel_mxt_ts" , |
| 296 | .swnode = &asus_tf103c_touchscreen_node, |
| 297 | }, |
| 298 | .adapter_path = "\\_SB_.I2C6" , |
| 299 | .irq_data = { |
| 300 | .type = X86_ACPI_IRQ_TYPE_GPIOINT, |
| 301 | .chip = "INT33FC:02" , |
| 302 | .index = 28, |
| 303 | .trigger = ACPI_EDGE_SENSITIVE, |
| 304 | .polarity = ACPI_ACTIVE_LOW, |
| 305 | .con_id = "atmel_mxt_ts_irq" , |
| 306 | }, |
| 307 | }, |
| 308 | }; |
| 309 | |
| 310 | const struct x86_dev_info asus_tf103c_info __initconst = { |
| 311 | .i2c_client_info = asus_tf103c_i2c_clients, |
| 312 | .i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients), |
| 313 | .pdev_info = asus_me176c_tf103c_pdevs, |
| 314 | .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), |
| 315 | .gpio_button_swnodes = asus_me176c_tf103c_lid_swnodes, |
| 316 | .swnode_group = generic_lipo_4v2_battery_swnodes, |
| 317 | .modules = bq24190_modules, |
| 318 | .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, |
| 319 | }; |
| 320 | |