[PATCH 28/30][SRU][Jammy] UBUNTU: SAUCE: mei_vsc: distinguish platform with different camera sensor
You-Sheng Yang
vicamo.yang at canonical.com
Mon Jan 17 15:19:26 UTC 2022
From: Ye Xiang <xiang.ye at intel.com>
BugLink: https://bugs.launchpad.net/bugs/1955383
Distinguish platform with different camera sensor by
camera model name from acpi. Then we could download
different FW to VSC according to the camera model.
Signed-off-by: Ye Xiang <xiang.ye at intel.com>
(cherry picked from commit 85cac41780cd4a1f5d84bd7e64aa9b1036cf877e github.com/intel/ivsc-driver)
Signed-off-by: You-Sheng Yang <vicamo.yang at canonical.com>
---
drivers/misc/mei/hw-vsc.c | 35 +++++++++++------
drivers/misc/mei/hw-vsc.h | 7 ++--
drivers/misc/mei/spi-vsc.c | 77 +++++++++++++++++++++++++++++++++++++-
3 files changed, 104 insertions(+), 15 deletions(-)
diff --git a/drivers/misc/mei/hw-vsc.c b/drivers/misc/mei/hw-vsc.c
index d9a22de48532..818d03b0d5dc 100644
--- a/drivers/misc/mei/hw-vsc.c
+++ b/drivers/misc/mei/hw-vsc.c
@@ -339,16 +339,17 @@ static int vsc_reset(struct mei_device *dev)
return 0;
}
-static char *fw_name[][3] = {
+/* %s is sensor name, need to be get and format in runtime */
+static char *fw_name_template[][3] = {
{
"vsc/soc_a1/ivsc_fw_a1.bin",
- "vsc/soc_a1/ivsc_pkg_ovti01as_0_a1.bin",
- "vsc/soc_a1/ivsc_skucfg_ovti01as_0_1_a1.bin",
+ "vsc/soc_a1/ivsc_pkg_%s_0_a1.bin",
+ "vsc/soc_a1/ivsc_skucfg_%s_0_1_a1.bin",
},
{
"vsc/soc_a1_prod/ivsc_fw_a1_prod.bin",
- "vsc/soc_a1_prod/ivsc_pkg_ovti01as_0_a1_prod.bin",
- "vsc/soc_a1_prod/ivsc_skucfg_ovti01as_0_1_a1_prod.bin",
+ "vsc/soc_a1_prod/ivsc_pkg_%s_0_a1_prod.bin",
+ "vsc/soc_a1_prod/ivsc_skucfg_%s_0_1_a1_prod.bin",
},
};
@@ -452,13 +453,25 @@ static int check_silicon(struct mei_device *dev)
hw->fw.key_src == SI_STRAP_KEY_SRC_DEBUG ? "" : "-prod");
if (hw->fw.sub_ver == SI_SUBSTEPPING_VERSION_1) {
if (hw->fw.key_src == SI_STRAP_KEY_SRC_DEBUG) {
- hw->fw.fw_file_name = fw_name[0][0];
- hw->fw.sensor_file_name = fw_name[0][1];
- hw->fw.sku_cnf_file_name = fw_name[0][2];
+ snprintf(hw->fw.fw_file_name,
+ sizeof(hw->fw.fw_file_name),
+ fw_name_template[0][0]);
+ snprintf(hw->fw.sensor_file_name,
+ sizeof(hw->fw.sensor_file_name),
+ fw_name_template[0][1], hw->cam_sensor_name);
+ snprintf(hw->fw.sku_cnf_file_name,
+ sizeof(hw->fw.sku_cnf_file_name),
+ fw_name_template[0][2], hw->cam_sensor_name);
} else {
- hw->fw.fw_file_name = fw_name[1][0];
- hw->fw.sensor_file_name = fw_name[1][1];
- hw->fw.sku_cnf_file_name = fw_name[1][2];
+ snprintf(hw->fw.fw_file_name,
+ sizeof(hw->fw.fw_file_name),
+ fw_name_template[1][0]);
+ snprintf(hw->fw.sensor_file_name,
+ sizeof(hw->fw.sensor_file_name),
+ fw_name_template[1][1], hw->cam_sensor_name);
+ snprintf(hw->fw.sku_cnf_file_name,
+ sizeof(hw->fw.sku_cnf_file_name),
+ fw_name_template[1][2], hw->cam_sensor_name);
}
}
diff --git a/drivers/misc/mei/hw-vsc.h b/drivers/misc/mei/hw-vsc.h
index 228edb77fab3..0bdc879e5ca4 100644
--- a/drivers/misc/mei/hw-vsc.h
+++ b/drivers/misc/mei/hw-vsc.h
@@ -332,11 +332,11 @@ struct vsc_boot_fw {
u8 rx_buf[FW_SPI_PKG_SIZE];
/* FirmwareBootFile */
- char *fw_file_name;
+ char fw_file_name[256];
/* PkgBootFile */
- char *sensor_file_name;
+ char sensor_file_name[256];
/* SkuConfigBootFile */
- char *sku_cnf_file_name;
+ char sku_cnf_file_name[256];
u32 fw_option;
u32 fw_cnt;
@@ -370,6 +370,7 @@ struct mei_vsc_hw {
atomic_t lock_cnt;
int write_lock_cnt;
wait_queue_head_t xfer_wait;
+ char cam_sensor_name[32];
};
#define to_vsc_hw(dev) ((struct mei_vsc_hw *)((dev)->hw))
diff --git a/drivers/misc/mei/spi-vsc.c b/drivers/misc/mei/spi-vsc.c
index a39329b0b1a8..f759006179af 100644
--- a/drivers/misc/mei/spi-vsc.c
+++ b/drivers/misc/mei/spi-vsc.c
@@ -17,7 +17,12 @@
#include "hw-vsc.h"
#include "mei_dev.h"
-/* gpio resources*/
+#define CVFD_ACPI_ID_TGL "INTC1059"
+#define CVFD_ACPI_ID_ADL "INTC1095"
+#define LINK_NUMBER (1)
+#define METHOD_NAME_SID "SID"
+
+/* gpio resources */
static const struct acpi_gpio_params wakeuphost_gpio = { 0, 0, false };
static const struct acpi_gpio_params wakeuphostint_gpio = { 1, 0, false };
static const struct acpi_gpio_params resetfw_gpio = { 2, 0, false };
@@ -30,6 +35,72 @@ static const struct acpi_gpio_mapping mei_vsc_acpi_gpios[] = {
{}
};
+static struct acpi_device *find_cvfd_child_adev(struct acpi_device *parent)
+{
+ struct acpi_device *adev;
+
+ if (!parent)
+ return NULL;
+
+ list_for_each_entry (adev, &parent->children, node) {
+ if (!strcmp(CVFD_ACPI_ID_TGL, acpi_device_hid(adev)) ||
+ !strcmp(CVFD_ACPI_ID_ADL, acpi_device_hid(adev)))
+ return adev;
+ }
+
+ return NULL;
+}
+
+static int get_sensor_name(struct mei_device *dev)
+{
+ struct mei_vsc_hw *hw = to_vsc_hw(dev);
+ struct spi_device *spi = hw->spi;
+ struct acpi_device *adev;
+ union acpi_object obj = { .type = ACPI_TYPE_INTEGER };
+ union acpi_object *ret_obj;
+ struct acpi_object_list arg_list = {
+ .count = 1,
+ .pointer = &obj,
+ };
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_status status;
+ char *c;
+
+ adev = find_cvfd_child_adev(ACPI_COMPANION(&spi->dev));
+ if (!adev) {
+ dev_err(&spi->dev, "ACPI not found CVFD device\n");
+ return -ENODEV;
+ }
+
+ obj.integer.value = LINK_NUMBER;
+ status = acpi_evaluate_object(adev->handle, METHOD_NAME_SID, &arg_list,
+ &buffer);
+ if (ACPI_FAILURE(status)) {
+ dev_err(&spi->dev, "can't evaluate SID method: %d\n", status);
+ return -ENODEV;
+ }
+
+ ret_obj = buffer.pointer;
+ dev_dbg(&spi->dev, "SID status %d %lld %d - %d %s %d\n", status,
+ buffer.length, ret_obj->type, ret_obj->string.length,
+ ret_obj->string.pointer,
+ acpi_has_method(adev->handle, METHOD_NAME_SID));
+
+ if (ret_obj->string.length > sizeof(hw->cam_sensor_name)) {
+ ACPI_FREE(buffer.pointer);
+ return -EINVAL;
+ }
+ memcpy(hw->cam_sensor_name, ret_obj->string.pointer,
+ ret_obj->string.length);
+
+ /* camera sensor name are all in lower case */
+ for (c = hw->cam_sensor_name; *c != '\0'; c++)
+ *c = tolower(*c);
+
+ ACPI_FREE(buffer.pointer);
+ return 0;
+}
+
static int mei_vsc_probe(struct spi_device *spi)
{
struct mei_vsc_hw *hw;
@@ -46,6 +117,10 @@ static int mei_vsc_probe(struct spi_device *spi)
hw->spi = spi;
spi_set_drvdata(spi, dev);
+ ret = get_sensor_name(dev);
+ if (ret)
+ return ret;
+
ret = devm_acpi_dev_add_driver_gpios(&spi->dev, mei_vsc_acpi_gpios);
if (ret) {
dev_err(&spi->dev, "%s: fail to add gpio\n", __func__);
--
2.33.1
More information about the kernel-team
mailing list