drivers/intel/mipi_camera: Handle acpi_name and common code
This change updates the mipi_camera driver to handle acpi_name based on device_type, if acpi_name is not set in the devicetree and moves some of the common code to separate methods. Change-Id: I15979f345fb823df2560db269e902a1ea650b69e Signed-off-by: Sugnan Prabhu S <sugnan.prabhu.s@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41607 Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: Rizwan Qureshi <rizwan.qureshi@intel.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
c01fa5ad5d
commit
7d00293af8
2 changed files with 130 additions and 24 deletions
|
@ -7,12 +7,27 @@
|
||||||
#include <device/i2c_simple.h>
|
#include <device/i2c_simple.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/path.h>
|
#include <device/path.h>
|
||||||
|
#include <device/pci_def.h>
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
static void camera_fill_ssdt(const struct device *dev)
|
static void write_pci_camera_device(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
||||||
|
|
||||||
|
if (dev->path.type != DEVICE_PATH_PCI) {
|
||||||
|
printk(BIOS_ERR, "CIO2/IMGU devices require PCI\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
acpigen_write_device(acpi_device_name(dev));
|
||||||
|
acpigen_write_ADR_pci_device(dev);
|
||||||
|
acpigen_write_name_string("_DDN", config->device_type == INTEL_ACPI_CAMERA_CIO2 ?
|
||||||
|
"Camera and Imaging Subsystem" : "Imaging Unit");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_i2c_camera_device(const struct device *dev, const char *scope)
|
||||||
{
|
{
|
||||||
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
||||||
const char *scope = acpi_device_scope(dev);
|
|
||||||
struct acpi_i2c i2c = {
|
struct acpi_i2c i2c = {
|
||||||
.address = dev->path.i2c.device,
|
.address = dev->path.i2c.device,
|
||||||
.mode_10bit = dev->path.i2c.mode_10bit,
|
.mode_10bit = dev->path.i2c.mode_10bit,
|
||||||
|
@ -20,13 +35,23 @@ static void camera_fill_ssdt(const struct device *dev)
|
||||||
.resource = scope,
|
.resource = scope,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!dev->enabled || !scope)
|
if (dev->path.type != DEVICE_PATH_I2C) {
|
||||||
|
printk(BIOS_ERR, "Non-CIO2/IMGU devices require I2C\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Device */
|
|
||||||
acpigen_write_scope(scope);
|
|
||||||
acpigen_write_device(acpi_device_name(dev));
|
acpigen_write_device(acpi_device_name(dev));
|
||||||
acpigen_write_name_string("_HID", config->acpi_hid);
|
|
||||||
|
if (config->device_type == INTEL_ACPI_CAMERA_SENSOR)
|
||||||
|
acpigen_write_name_integer("_ADR", 0);
|
||||||
|
|
||||||
|
if (config->acpi_hid)
|
||||||
|
acpigen_write_name_string("_HID", config->acpi_hid);
|
||||||
|
else if (config->device_type == INTEL_ACPI_CAMERA_VCM)
|
||||||
|
acpigen_write_name_string("_HID", ACPI_DT_NAMESPACE_HID);
|
||||||
|
else if (config->device_type == INTEL_ACPI_CAMERA_NVM)
|
||||||
|
acpigen_write_name_string("_HID", "INT3499");
|
||||||
|
|
||||||
acpigen_write_name_integer("_UID", config->acpi_uid);
|
acpigen_write_name_integer("_UID", config->acpi_uid);
|
||||||
acpigen_write_name_string("_DDN", config->chip_name);
|
acpigen_write_name_string("_DDN", config->chip_name);
|
||||||
acpigen_write_STA(acpi_device_status(dev));
|
acpigen_write_STA(acpi_device_status(dev));
|
||||||
|
@ -35,35 +60,111 @@ static void camera_fill_ssdt(const struct device *dev)
|
||||||
acpigen_write_name("_CRS");
|
acpigen_write_name("_CRS");
|
||||||
acpigen_write_resourcetemplate_header();
|
acpigen_write_resourcetemplate_header();
|
||||||
acpi_device_write_i2c(&i2c);
|
acpi_device_write_i2c(&i2c);
|
||||||
acpigen_write_resourcetemplate_footer();
|
|
||||||
|
|
||||||
/* Mark it as Camera related device */
|
/*
|
||||||
acpigen_write_name_integer("CAMD", config->device_type);
|
* The optional vcm/nvram devices are presumed to be on the same I2C bus as the camera
|
||||||
|
* sensor.
|
||||||
/* Create Device specific data */
|
*/
|
||||||
if (config->device_type == INTEL_ACPI_CAMERA_SENSOR) {
|
if (config->device_type == INTEL_ACPI_CAMERA_SENSOR &&
|
||||||
acpigen_write_method_serialized("SSDB", 0);
|
config->ssdb.vcm_type && config->vcm_address) {
|
||||||
acpigen_write_return_byte_buffer((uint8_t *)&config->ssdb,
|
struct acpi_i2c i2c_vcm = i2c;
|
||||||
sizeof(config->ssdb));
|
i2c_vcm.address = config->vcm_address;
|
||||||
acpigen_pop_len(); /* Method */
|
acpi_device_write_i2c(&i2c_vcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill Power Sequencing Data */
|
if (config->device_type == INTEL_ACPI_CAMERA_SENSOR &&
|
||||||
acpigen_write_method_serialized("PWDB", 0);
|
config->ssdb.rom_type && config->rom_address) {
|
||||||
acpigen_write_return_byte_buffer((uint8_t *)&config->pwdb,
|
struct acpi_i2c i2c_rom = i2c;
|
||||||
(sizeof(struct intel_pwdb) * config->num_pwdb_entries));
|
i2c_rom.address = config->rom_address;
|
||||||
acpigen_pop_len(); /* Method */
|
acpi_device_write_i2c(&i2c_rom);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpigen_write_resourcetemplate_footer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_camera_device_common(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
||||||
|
|
||||||
|
/* Mark it as Camera related device */
|
||||||
|
if (config->device_type == INTEL_ACPI_CAMERA_CIO2 ||
|
||||||
|
config->device_type == INTEL_ACPI_CAMERA_IMGU ||
|
||||||
|
config->device_type == INTEL_ACPI_CAMERA_SENSOR ||
|
||||||
|
config->device_type == INTEL_ACPI_CAMERA_VCM) {
|
||||||
|
acpigen_write_name_integer("CAMD", config->device_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void camera_fill_ssdt(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
||||||
|
const char *scope = acpi_device_scope(dev);
|
||||||
|
|
||||||
|
if (!dev->enabled || !scope)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Device */
|
||||||
|
acpigen_write_scope(scope);
|
||||||
|
|
||||||
|
if (config->device_type == INTEL_ACPI_CAMERA_CIO2 ||
|
||||||
|
config->device_type == INTEL_ACPI_CAMERA_IMGU)
|
||||||
|
write_pci_camera_device(dev);
|
||||||
|
else
|
||||||
|
write_i2c_camera_device(dev, scope);
|
||||||
|
|
||||||
|
write_camera_device_common(dev);
|
||||||
|
|
||||||
acpigen_pop_len(); /* Device */
|
acpigen_pop_len(); /* Device */
|
||||||
acpigen_pop_len(); /* Scope */
|
acpigen_pop_len(); /* Scope */
|
||||||
printk(BIOS_INFO, "%s: %s address 0%xh\n", acpi_device_path(dev),
|
|
||||||
dev->chip_ops->name, dev->path.i2c.device);
|
if (dev->path.type == DEVICE_PATH_PCI) {
|
||||||
|
printk(BIOS_INFO, "%s: %s PCI address 0%x\n", acpi_device_path(dev),
|
||||||
|
dev->chip_ops->name, dev->path.pci.devfn);
|
||||||
|
} else {
|
||||||
|
printk(BIOS_INFO, "%s: %s I2C address 0%xh\n", acpi_device_path(dev),
|
||||||
|
dev->chip_ops->name, dev->path.i2c.device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *camera_acpi_name(const struct device *dev)
|
static const char *camera_acpi_name(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
const char *prefix = NULL;
|
||||||
|
static char name[5];
|
||||||
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
struct drivers_intel_mipi_camera_config *config = dev->chip_info;
|
||||||
return config->acpi_name;
|
|
||||||
|
if (config->acpi_name)
|
||||||
|
return config->acpi_name;
|
||||||
|
|
||||||
|
switch (config->device_type) {
|
||||||
|
case INTEL_ACPI_CAMERA_CIO2:
|
||||||
|
return "CIO2";
|
||||||
|
case INTEL_ACPI_CAMERA_IMGU:
|
||||||
|
return "IMGU";
|
||||||
|
case INTEL_ACPI_CAMERA_PMIC:
|
||||||
|
return "PMIC";
|
||||||
|
case INTEL_ACPI_CAMERA_SENSOR:
|
||||||
|
prefix = "CAM";
|
||||||
|
break;
|
||||||
|
case INTEL_ACPI_CAMERA_VCM:
|
||||||
|
prefix = "VCM";
|
||||||
|
break;
|
||||||
|
case INTEL_ACPI_CAMERA_NVM:
|
||||||
|
prefix = "NVM";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(BIOS_ERR, "Invalid device type: %x\n", config->device_type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The camera # knows which link # they use, so that's used as the basis for the
|
||||||
|
* instance #. The VCM and NVM don't have this information, so the best we can go on is
|
||||||
|
* the _UID.
|
||||||
|
*/
|
||||||
|
snprintf(name, sizeof(name), "%s%1u", prefix,
|
||||||
|
config->device_type == INTEL_ACPI_CAMERA_SENSOR ?
|
||||||
|
config->ssdb.link_used : config->acpi_uid);
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_operations camera_ops = {
|
static struct device_operations camera_ops = {
|
||||||
|
|
|
@ -12,6 +12,7 @@ enum intel_camera_device_type {
|
||||||
INTEL_ACPI_CAMERA_IMGU,
|
INTEL_ACPI_CAMERA_IMGU,
|
||||||
INTEL_ACPI_CAMERA_SENSOR,
|
INTEL_ACPI_CAMERA_SENSOR,
|
||||||
INTEL_ACPI_CAMERA_VCM,
|
INTEL_ACPI_CAMERA_VCM,
|
||||||
|
INTEL_ACPI_CAMERA_NVM,
|
||||||
INTEL_ACPI_CAMERA_PMIC = 100,
|
INTEL_ACPI_CAMERA_PMIC = 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,6 +91,10 @@ struct drivers_intel_mipi_camera_config {
|
||||||
const char *acpi_name;
|
const char *acpi_name;
|
||||||
const char *chip_name;
|
const char *chip_name;
|
||||||
unsigned int acpi_uid;
|
unsigned int acpi_uid;
|
||||||
|
const char *remote_name; /* default "\_SB.PCI0.CIO2" */
|
||||||
|
const char *vcm_name; /* defaults to |vcm_address| device */
|
||||||
|
uint16_t rom_address; /* I2C to use if ssdb.rom_type != 0 */
|
||||||
|
uint16_t vcm_address; /* I2C to use if ssdb.vcm_type != 0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue