Commit f1a58250 authored by Hans de Goede's avatar Hans de Goede

platform/x86: int3472: discrete: Add support for 1 GPIO regulator shared between 2 sensors

On the Lenovo Miix 510-12IKB there is 1 GPIO regulator, with its GPIO
listed in the INT3472 device belonging to the OV5648 back sensor.
But this regulator also needs to be enabled for the OV2680 front sensor
to work.

Add support to skl_int3472_register_regulator() to add supply map entries
pointing to both sensors based on a DMI quirk table which gives the
dev_name part of the supply map for the second sensor (the sensor without
the GPIO listed in its matching INT3472 ACPI device).
Tested-by: default avatarHao Yao <hao.yao@intel.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20230616172132.37859-4-hdegoede@redhat.com
parent d4381dcf
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/dmi.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -250,22 +251,54 @@ static const char * const skl_int3472_regulator_map_supplies[] = { ...@@ -250,22 +251,54 @@ static const char * const skl_int3472_regulator_map_supplies[] = {
static_assert(ARRAY_SIZE(skl_int3472_regulator_map_supplies) == static_assert(ARRAY_SIZE(skl_int3472_regulator_map_supplies) ==
GPIO_REGULATOR_SUPPLY_MAP_COUNT); 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.
*/
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, int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
struct acpi_resource_gpio *agpio) struct acpi_resource_gpio *agpio)
{ {
char *path = agpio->resource_source.string_ptr; char *path = agpio->resource_source.string_ptr;
struct regulator_init_data init_data = { }; struct regulator_init_data init_data = { };
struct regulator_config cfg = { }; struct regulator_config cfg = { };
int i, ret; const char *second_sensor = NULL;
const struct dmi_system_id *id;
for (i = 0; i < ARRAY_SIZE(skl_int3472_regulator_map_supplies); i++) { int i, j, ret;
int3472->regulator.supply_map[i].supply = skl_int3472_regulator_map_supplies[i];
int3472->regulator.supply_map[i].dev_name = int3472->sensor_name; 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;
j++;
if (second_sensor) {
int3472->regulator.supply_map[j].supply =
skl_int3472_regulator_map_supplies[i];
int3472->regulator.supply_map[j].dev_name = second_sensor;
j++;
}
} }
init_data.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS; init_data.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
init_data.consumer_supplies = int3472->regulator.supply_map; init_data.consumer_supplies = int3472->regulator.supply_map;
init_data.num_consumer_supplies = GPIO_REGULATOR_SUPPLY_MAP_COUNT; init_data.num_consumer_supplies = j;
snprintf(int3472->regulator.regulator_name, snprintf(int3472->regulator.regulator_name,
sizeof(int3472->regulator.regulator_name), "%s-regulator", sizeof(int3472->regulator.regulator_name), "%s-regulator",
......
...@@ -79,7 +79,8 @@ struct int3472_discrete_device { ...@@ -79,7 +79,8 @@ struct int3472_discrete_device {
const struct int3472_sensor_config *sensor_config; const struct int3472_sensor_config *sensor_config;
struct int3472_gpio_regulator { struct int3472_gpio_regulator {
struct regulator_consumer_supply supply_map[GPIO_REGULATOR_SUPPLY_MAP_COUNT]; /* SUPPLY_MAP_COUNT * 2 to make room for second sensor mappings */
struct regulator_consumer_supply supply_map[GPIO_REGULATOR_SUPPLY_MAP_COUNT * 2];
char regulator_name[GPIO_REGULATOR_NAME_LENGTH]; char regulator_name[GPIO_REGULATOR_NAME_LENGTH];
char supply_name[GPIO_REGULATOR_SUPPLY_NAME_LENGTH]; char supply_name[GPIO_REGULATOR_SUPPLY_NAME_LENGTH];
struct gpio_desc *gpio; struct gpio_desc *gpio;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment