I am currently adapting the GC5035 camera on an x86 Intel platform running Ubuntu 24.04 with kernel version 6.8.0-45. I attempted to use the driver from the repository ipu6-drivers without success.
diff a/drivers/platform/x86/intel/int3472/common.h b/drivers/platform/x86/intel/int3472/common.h (rejected hunks)
@@ -23,7 +23,7 @@
#define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d
#define INT3472_PDEV_MAX_NAME_LEN 23
-#define INT3472_MAX_SENSOR_GPIOS 3
+#define INT3472_MAX_SENSOR_GPIOS 4
#define GPIO_REGULATOR_NAME_LENGTH 21
#define GPIO_REGULATOR_SUPPLY_NAME_LENGTH 9
@@ -73,6 +73,7 @@ struct int3472_sensor_config {
const char *sensor_module_name;
struct regulator_consumer_supply supply_map;
const struct int3472_gpio_function_remap *function_maps;
+ const bool use_independent_gpio;
};
struct int3472_discrete_device {
diff a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c (rejected hunks)
@@ -57,11 +57,25 @@ static const struct int3472_gpio_function_remap ov2680_gpio_function_remaps[] =
static const struct int3472_sensor_config int3472_sensor_configs[] = {
/* Lenovo Miix 510-12ISK - OV2680, Front */
- { "GNDF140809R", { 0 }, ov2680_gpio_function_remaps },
+ { "GNDF140809R", { 0 }, ov2680_gpio_function_remaps, false },
/* Lenovo Miix 510-12ISK - OV5648, Rear */
- { "GEFF150023R", REGULATOR_SUPPLY("avdd", NULL), NULL },
+ { "GEFF150023R", REGULATOR_SUPPLY("avdd", NULL), NULL, false },
/* Surface Go 1&2 - OV5693, Front */
- { "YHCU", REGULATOR_SUPPLY("avdd", NULL), NULL },
+ { "YHCU", REGULATOR_SUPPLY("avdd", NULL), NULL, false },
+ /* Dell Latitude 9420 - OV01A1S, Front */
+ { "0BF111N3", { 0 }, NULL, true },
+ /* Dell Latitude 9420 - HM11B1, Front */
+ { "9BF123N3", { 0 }, NULL, true },
+ /* Lenovo X1 Yoga - OV2740, Front */
+ { "CJFLE23", { 0 }, NULL, true },
+ /* OV13B10 */
+ { "09B13", { 0 }, NULL, true },
+ /* HIMX1092 */
+ { "KPFB297", { 0 }, NULL, true },
+ /* GC5035 */
+ { "CJAK519", { 0 }, NULL, true },
+ /* S5K3L6 */
+ { "KBAG296", { 0 }, NULL, true },
};
static const struct int3472_sensor_config *
@@ -229,6 +243,8 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
const char *err_msg;
int ret;
u8 type;
+ u8 active_value;
+ u32 polarity = GPIO_LOOKUP_FLAGS_DEFAULT;
if (!acpi_gpio_get_io_resource(ares, &agpio))
return 1;
@@ -249,30 +265,60 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
}
type = obj->integer.value & 0xff;
+ active_value = obj->integer.value >> 24;
+ if (!active_value)
+ polarity = GPIO_ACTIVE_LOW;
switch (type) {
case INT3472_GPIO_TYPE_RESET:
ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "reset",
- GPIO_ACTIVE_LOW);
+ polarity);
if (ret)
err_msg = "Failed to map reset pin to sensor\n";
break;
case INT3472_GPIO_TYPE_POWERDOWN:
ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "powerdown",
- GPIO_ACTIVE_LOW);
+ polarity);
if (ret)
err_msg = "Failed to map powerdown pin to sensor\n";
break;
case INT3472_GPIO_TYPE_CLK_ENABLE:
+ if (!IS_ERR(int3472->sensor_config) &&
+ int3472->sensor_config->use_independent_gpio) {
+ ret = skl_int3472_map_gpio_to_sensor(int3472, agpio,
+ "clken", polarity);
+ if (ret)
+ err_msg = "Failed to map clken pin to sensor\n";
+
+ break;
+ }
case INT3472_GPIO_TYPE_PRIVACY_LED:
+ if (!IS_ERR(int3472->sensor_config) &&
+ int3472->sensor_config->use_independent_gpio) {
+ ret = skl_int3472_map_gpio_to_sensor(int3472, agpio,
+ "pled", polarity);
+ if (ret)
+ err_msg = "Failed to map pled pin to sensor\n";
+
+ break;
+ }
ret = skl_int3472_map_gpio_to_clk(int3472, agpio, type);
if (ret)
err_msg = "Failed to map GPIO to clock\n";
break;
case INT3472_GPIO_TYPE_POWER_ENABLE:
+ if (!IS_ERR(int3472->sensor_config) &&
+ int3472->sensor_config->use_independent_gpio) {
+ ret = skl_int3472_map_gpio_to_sensor(int3472, agpio,
+ "pwren", polarity);
+ if (ret)
+ err_msg = "Failed to map clken pin to sensor\n";
+
+ break;
+ }
ret = skl_int3472_register_regulator(int3472, agpio);
if (ret)
err_msg = "Failed to map regulator to sensor\n";
drivers/media/i2c/gc5035.c: At top level:
drivers/media/i2c/gc5035.c:1717:3: error: ‘const struct v4l2_subdev_pad_ops’ has no member named ‘init_cfg’
1717 | .init_cfg = gc5035_entity_init_cfg,
It seems that in kernel 6.8.0-45, the structure v4l2_subdev_pad_ops no longer contains the .init_cfg member.
[ 4.769113] gc5035 i2c-GCTI5035:00: mclk rate set to 0 instead of requested 192000000
[ 4.769125] gc5035 i2c-GCTI5035:00: supply iovdd not found, using dummy regulator
[ 4.784858] gc5035 i2c-GCTI5035:00: supply dvdd12 not found, using dummy regulator
[ 4.786139] gc5035 i2c-GCTI5035:00: supply avdd21 not found, using dummy regulator
[ 4.786421] gc5035 i2c-GCTI5035:00: error -EREMOTEIO: Sensor ID check failed
...
The log indicates that the power supplies (iovdd, dvdd12, avdd21) are not found, and dummy regulators are being used. Additionally, the sensor ID check fails with error -EREMOTEIO.
Do I need to configure the VDD and clock settings in the BIOS, or is there another way to resolve this issue?