platform/x86: int3472: Rework AVDD second sensor quirk handling

Rework the discrete quirk handling to use a quirks struct which is
pointed to by a dmi_system_id table, rather then having a dmi_system_id
table per type of quirk.

This is a preparation patch for adding support for multiple regulators,
where not all regulators might be shared between sensors.

Reviewed-by: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: David Heidelberg <david@ixit.cz>  # Dell Latitude 9440
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Link: https://lore.kernel.org/r/20250417111337.38142-5-hdegoede@redhat.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
This commit is contained in:
Hans de Goede 2025-04-17 13:13:32 +02:00 committed by Ilpo Järvinen
parent b6d3d739b7
commit 38ff83a374
No known key found for this signature in database
GPG Key ID: 59AC4F6153E5CE31
5 changed files with 50 additions and 29 deletions

View File

@ -1,7 +1,8 @@
obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472_discrete.o \
intel_skl_int3472_tps68470.o \
intel_skl_int3472_common.o
intel_skl_int3472_discrete-y := discrete.o clk_and_regulator.o led.o
intel_skl_int3472_discrete-y := discrete.o discrete_quirks.o \
clk_and_regulator.o led.o
intel_skl_int3472_tps68470-y := tps68470.o tps68470_board_data.o
intel_skl_int3472_common-y += common.o

View File

@ -5,7 +5,6 @@
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/slab.h>
@ -205,37 +204,14 @@ static const char * const skl_int3472_regulator_map_supplies[] = {
static_assert(ARRAY_SIZE(skl_int3472_regulator_map_supplies) ==
GPIO_REGULATOR_SUPPLY_MAP_COUNT);
/*
* On some models there is a single GPIO regulator which is shared between
* sensors and only listed in the ACPI resources of one sensor.
* This DMI table contains the name of the second sensor. This is used to add
* entries for the second sensor to the supply_map.
*/
static const struct dmi_system_id skl_int3472_regulator_second_sensor[] = {
{
/* Lenovo Miix 510-12IKB */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 510-12IKB"),
},
.driver_data = "i2c-OVTI2680:00",
},
{ }
};
int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
struct gpio_desc *gpio)
struct gpio_desc *gpio,
const char *second_sensor)
{
struct regulator_init_data init_data = { };
struct regulator_config cfg = { };
const char *second_sensor = NULL;
const struct dmi_system_id *id;
int i, j;
id = dmi_first_match(skl_int3472_regulator_second_sensor);
if (id)
second_sensor = id->driver_data;
for (i = 0, j = 0; i < ARRAY_SIZE(skl_int3472_regulator_map_supplies); i++) {
int3472->regulator.supply_map[j].supply = skl_int3472_regulator_map_supplies[i];
int3472->regulator.supply_map[j].dev_name = int3472->sensor_name;

View File

@ -48,6 +48,7 @@
container_of(clk, struct int3472_discrete_device, clock)
struct acpi_device;
struct dmi_system_id;
struct i2c_client;
struct platform_device;
@ -68,6 +69,11 @@ struct int3472_cldb {
u8 reserved2[17];
};
struct int3472_discrete_quirks {
/* For models where AVDD GPIO is shared between sensors */
const char *avdd_second_sensor;
};
struct int3472_discrete_device {
struct acpi_device *adev;
struct device *dev;
@ -100,11 +106,15 @@ struct int3472_discrete_device {
struct gpio_desc *gpio;
} pled;
struct int3472_discrete_quirks quirks;
unsigned int ngpios; /* how many GPIOs have we seen */
unsigned int n_sensor_gpios; /* how many have we mapped to sensor */
struct gpiod_lookup_table gpios;
};
extern const struct dmi_system_id skl_int3472_discrete_quirks[];
union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
char *id);
int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
@ -118,7 +128,8 @@ int skl_int3472_register_dsm_clock(struct int3472_discrete_device *int3472);
void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
struct gpio_desc *gpio);
struct gpio_desc *gpio,
const char *second_sensor);
void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472);
int skl_int3472_register_pled(struct int3472_discrete_device *int3472, struct gpio_desc *gpio);

View File

@ -5,6 +5,7 @@
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/i2c.h>
@ -310,7 +311,8 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
break;
case INT3472_GPIO_TYPE_POWER_ENABLE:
ret = skl_int3472_register_regulator(int3472, gpio);
ret = skl_int3472_register_regulator(int3472, gpio,
int3472->quirks.avdd_second_sensor);
if (ret)
err_msg = "Failed to map regulator to sensor\n";
@ -378,13 +380,19 @@ static void skl_int3472_discrete_remove(struct platform_device *pdev)
static int skl_int3472_discrete_probe(struct platform_device *pdev)
{
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
const struct int3472_discrete_quirks *quirks = NULL;
struct int3472_discrete_device *int3472;
const struct dmi_system_id *id;
struct int3472_cldb cldb;
int ret;
if (!adev)
return -ENODEV;
id = dmi_first_match(skl_int3472_discrete_quirks);
if (id)
quirks = id->driver_data;
ret = skl_int3472_fill_cldb(adev, &cldb);
if (ret) {
dev_err(&pdev->dev, "Couldn't fill CLDB structure\n");
@ -408,6 +416,9 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, int3472);
int3472->clock.imgclk_index = cldb.clock_source;
if (quirks)
int3472->quirks = *quirks;
ret = skl_int3472_get_sensor_adev_and_name(&pdev->dev, &int3472->sensor,
&int3472->sensor_name);
if (ret)

View File

@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-2.0
/* Author: Hans de Goede <hansg@kernel.org> */
#include <linux/dmi.h>
#include "common.h"
static const struct int3472_discrete_quirks lenovo_miix_510_quirks = {
.avdd_second_sensor = "i2c-OVTI2680:00",
};
const struct dmi_system_id skl_int3472_discrete_quirks[] = {
{
/* Lenovo Miix 510-12IKB */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 510-12IKB"),
},
.driver_data = (void *)&lenovo_miix_510_quirks,
},
{ }
};