File Index
Files and directories
Sign in
FILE

acer.c

File preview with syntax highlighting.

linux-6.19.14/drivers/platform/x86/x86-android-tablets/acer.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Board info for Acer 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-2025 Hans de Goede <hansg@kernel.org>
  9 */
 10
 11#include <linux/gpio/machine.h>
 12#include <linux/gpio/property.h>
 13#include <linux/platform_device.h>
 14#include <linux/property.h>
 15
 16#include "shared-psy-info.h"
 17#include "x86-android-tablets.h"
 18
 19/* Acer Iconia One 8 A1-840 (non FHD version) */
 20static const struct property_entry acer_a1_840_bq24190_props[] = {
 21	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_4v2_battery_node),
 22	PROPERTY_ENTRY_BOOL("omit-battery-class"),
 23	PROPERTY_ENTRY_BOOL("disable-reset"),
 24	{ }
 25};
 26
 27static const struct software_node acer_a1_840_bq24190_node = {
 28	.properties = acer_a1_840_bq24190_props,
 29};
 30
 31static const struct property_entry acer_a1_840_touchscreen_props[] = {
 32	PROPERTY_ENTRY_U32("touchscreen-size-x", 800),
 33	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
 34	PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[1], 26, GPIO_ACTIVE_LOW),
 35	{ }
 36};
 37
 38static const struct software_node acer_a1_840_touchscreen_node = {
 39	.properties = acer_a1_840_touchscreen_props,
 40};
 41
 42static const struct x86_i2c_client_info acer_a1_840_i2c_clients[] __initconst = {
 43	{
 44		/* BQ24297 charger IC */
 45		.board_info = {
 46			.type = "bq24297",
 47			.addr = 0x6b,
 48			.dev_name = "bq24297",
 49			.swnode = &acer_a1_840_bq24190_node,
 50			.platform_data = &bq24190_pdata,
 51		},
 52		.adapter_path = "\\_SB_.I2C1",
 53		.irq_data = {
 54			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 55			.chip = "INT33FC:02",
 56			.index = 2,
 57			.trigger = ACPI_EDGE_SENSITIVE,
 58			.polarity = ACPI_ACTIVE_LOW,
 59			.con_id = "bq24297_irq",
 60		},
 61	}, {
 62		/* MPU6515 sensors */
 63		.board_info = {
 64			.type = "mpu6515",
 65			.addr = 0x69,
 66			.dev_name = "mpu6515",
 67		},
 68		.adapter_path = "\\_SB_.I2C3",
 69		.irq_data = {
 70			.type = X86_ACPI_IRQ_TYPE_APIC,
 71			.index = 0x47,
 72			.trigger = ACPI_EDGE_SENSITIVE,
 73			.polarity = ACPI_ACTIVE_HIGH,
 74		},
 75	}, {
 76		/* FT5416 touchscreen controller */
 77		.board_info = {
 78			.type = "edt-ft5x06",
 79			.addr = 0x38,
 80			.dev_name = "ft5416",
 81			.swnode = &acer_a1_840_touchscreen_node,
 82		},
 83		.adapter_path = "\\_SB_.I2C4",
 84		.irq_data = {
 85			.type = X86_ACPI_IRQ_TYPE_APIC,
 86			.index = 0x45,
 87			.trigger = ACPI_EDGE_SENSITIVE,
 88			.polarity = ACPI_ACTIVE_HIGH,
 89		},
 90	}
 91};
 92
 93static const struct property_entry acer_a1_840_int3496_props[] __initconst = {
 94	PROPERTY_ENTRY_GPIO("mux-gpios", &baytrail_gpiochip_nodes[2], 1, GPIO_ACTIVE_HIGH),
 95	PROPERTY_ENTRY_GPIO("id-gpios", &baytrail_gpiochip_nodes[2], 18, GPIO_ACTIVE_HIGH),
 96	{ }
 97};
 98
 99static const struct platform_device_info acer_a1_840_pdevs[] __initconst = {
100	{
101		/* For micro USB ID pin handling */
102		.name = "intel-int3496",
103		.id = PLATFORM_DEVID_NONE,
104		.properties = acer_a1_840_int3496_props,
105	},
106};
107
108/* Properties for the Dollar Cove TI PMIC battery MFD child used as fuel-gauge */
109static const struct property_entry acer_a1_840_fg_props[] = {
110	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_4v2_battery_node),
111	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1),
112	PROPERTY_ENTRY_GPIO("charged-gpios", &baytrail_gpiochip_nodes[2], 10, GPIO_ACTIVE_HIGH),
113	{ }
114};
115
116static struct device *acer_a1_840_fg_dev;
117static struct fwnode_handle *acer_a1_840_fg_node;
118
119static int __init acer_a1_840_init(struct device *dev)
120{
121	int ret;
122
123	acer_a1_840_fg_dev = bus_find_device_by_name(&platform_bus_type, NULL, "chtdc_ti_battery");
124	if (!acer_a1_840_fg_dev)
125		return dev_err_probe(dev, -EPROBE_DEFER, "getting chtdc_ti_battery dev\n");
126
127	acer_a1_840_fg_node = fwnode_create_software_node(acer_a1_840_fg_props, NULL);
128	if (IS_ERR(acer_a1_840_fg_node)) {
129		ret = PTR_ERR(acer_a1_840_fg_node);
130		goto err_put;
131	}
132
133	ret = device_add_software_node(acer_a1_840_fg_dev,
134				       to_software_node(acer_a1_840_fg_node));
135	if (ret)
136		goto err_put;
137
138	return 0;
139
140err_put:
141	fwnode_handle_put(acer_a1_840_fg_node);
142	acer_a1_840_fg_node = NULL;
143	put_device(acer_a1_840_fg_dev);
144	acer_a1_840_fg_dev = NULL;
145	return ret;
146}
147
148static void acer_a1_840_exit(void)
149{
150	device_remove_software_node(acer_a1_840_fg_dev);
151	/*
152	 * Skip fwnode_handle_put(acer_a1_840_fg_node), instead leak the node.
153	 * The intel_dc_ti_battery driver may still reference the strdup-ed
154	 * "supplied-from" string. This string will be free-ed if the node
155	 * is released.
156	 */
157	acer_a1_840_fg_node = NULL;
158	put_device(acer_a1_840_fg_dev);
159	acer_a1_840_fg_dev = NULL;
160}
161
162static const char * const acer_a1_840_modules[] __initconst = {
163	"bq24190_charger",	/* For the Vbus regulator for intel-int3496 */
164	NULL
165};
166
167const struct x86_dev_info acer_a1_840_info __initconst = {
168	.i2c_client_info = acer_a1_840_i2c_clients,
169	.i2c_client_count = ARRAY_SIZE(acer_a1_840_i2c_clients),
170	.pdev_info = acer_a1_840_pdevs,
171	.pdev_count = ARRAY_SIZE(acer_a1_840_pdevs),
172	.gpiochip_type = X86_GPIOCHIP_BAYTRAIL,
173	.swnode_group = generic_lipo_4v2_battery_swnodes,
174	.modules = acer_a1_840_modules,
175	.init = acer_a1_840_init,
176	.exit = acer_a1_840_exit,
177};
178
179/* Acer Iconia One 7 B1-750 has an Android factory image with everything hardcoded */
180static const char * const acer_b1_750_mount_matrix[] = {
181	"-1", "0", "0",
182	"0", "1", "0",
183	"0", "0", "1"
184};
185
186static const struct property_entry acer_b1_750_bma250e_props[] = {
187	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", acer_b1_750_mount_matrix),
188	{ }
189};
190
191static const struct software_node acer_b1_750_bma250e_node = {
192	.properties = acer_b1_750_bma250e_props,
193};
194
195static const struct property_entry acer_b1_750_novatek_props[] = {
196	PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[1], 26, GPIO_ACTIVE_LOW),
197	{ }
198};
199
200static const struct software_node acer_b1_750_novatek_node = {
201	.properties = acer_b1_750_novatek_props,
202};
203
204static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = {
205	{
206		/* Novatek NVT-ts touchscreen */
207		.board_info = {
208			.type = "nt11205-ts",
209			.addr = 0x34,
210			.dev_name = "NVT-ts",
211			.swnode = &acer_b1_750_novatek_node,
212		},
213		.adapter_path = "\\_SB_.I2C4",
214		.irq_data = {
215			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
216			.chip = "INT33FC:02",
217			.index = 3,
218			.trigger = ACPI_EDGE_SENSITIVE,
219			.polarity = ACPI_ACTIVE_LOW,
220			.con_id = "NVT-ts_irq",
221		},
222	}, {
223		/* BMA250E accelerometer */
224		.board_info = {
225			.type = "bma250e",
226			.addr = 0x18,
227			.swnode = &acer_b1_750_bma250e_node,
228		},
229		.adapter_path = "\\_SB_.I2C3",
230		.irq_data = {
231			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
232			.chip = "INT33FC:02",
233			.index = 25,
234			.trigger = ACPI_LEVEL_SENSITIVE,
235			.polarity = ACPI_ACTIVE_HIGH,
236			.con_id = "bma250e_irq",
237		},
238	},
239};
240
241const struct x86_dev_info acer_b1_750_info __initconst = {
242	.i2c_client_info = acer_b1_750_i2c_clients,
243	.i2c_client_count = ARRAY_SIZE(acer_b1_750_i2c_clients),
244	.pdev_info = int3496_pdevs,
245	.pdev_count = 1,
246	.gpiochip_type = X86_GPIOCHIP_BAYTRAIL,
247};
~/ Read-only file preview.