Commit f663fb49 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

media: atomisp: csi2-bridge: Add support for VCM I2C-client instantiation

Fill sensor->vcm_type and call intel_cio2_bridge_instantiate_vcm() from
the v4l2-async bound op so that an I2C-client will be instatiated for
the VCM.

Note unfortunately on atomisp the _DSM to get the VCM type sometimes
returns a VCM even though there is none. Since VCMs are typically only
used together with certain sensors, work around this by adding a vcm
field to atomisp_sensor_config and only check for a VCM when that is set.
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent fc0f5b59
...@@ -66,15 +66,25 @@ static const guid_t atomisp_dsm_guid = ...@@ -66,15 +66,25 @@ static const guid_t atomisp_dsm_guid =
GUID_INIT(0xdc2f6c4f, 0x045b, 0x4f1d, GUID_INIT(0xdc2f6c4f, 0x045b, 0x4f1d,
0x97, 0xb9, 0x88, 0x2a, 0x68, 0x60, 0xa4, 0xbe); 0x97, 0xb9, 0x88, 0x2a, 0x68, 0x60, 0xa4, 0xbe);
/*
* 75c9a639-5c8a-4a00-9f48-a9c3b5da789f
* This _DSM GUID returns a string giving the VCM type e.g. "AD5823".
*/
static const guid_t vcm_dsm_guid =
GUID_INIT(0x75c9a639, 0x5c8a, 0x4a00,
0x9f, 0x48, 0xa9, 0xc3, 0xb5, 0xda, 0x78, 0x9f);
struct atomisp_sensor_config { struct atomisp_sensor_config {
int lanes; int lanes;
bool vcm;
}; };
#define ATOMISP_SENSOR_CONFIG(_HID, _LANES) \ #define ATOMISP_SENSOR_CONFIG(_HID, _LANES, _VCM) \
{ \ { \
.id = _HID, \ .id = _HID, \
.driver_data = (long)&((const struct atomisp_sensor_config) { \ .driver_data = (long)&((const struct atomisp_sensor_config) { \
.lanes = _LANES, \ .lanes = _LANES, \
.vcm = _VCM, \
}) \ }) \
} }
...@@ -490,8 +500,28 @@ static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev) ...@@ -490,8 +500,28 @@ static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev)
return ret; return ret;
} }
static char *atomisp_csi2_get_vcm_type(struct acpi_device *adev)
{
union acpi_object *obj;
char *vcm_type;
obj = acpi_evaluate_dsm_typed(adev->handle, &vcm_dsm_guid, 0, 0,
NULL, ACPI_TYPE_STRING);
if (!obj)
return NULL;
vcm_type = kstrdup(obj->string.pointer, GFP_KERNEL);
ACPI_FREE(obj);
if (!vcm_type)
return NULL;
string_lower(vcm_type, vcm_type);
return vcm_type;
}
static const struct acpi_device_id atomisp_sensor_configs[] = { static const struct acpi_device_id atomisp_sensor_configs[] = {
ATOMISP_SENSOR_CONFIG("INT33BE", 2), /* OV5693 */ ATOMISP_SENSOR_CONFIG("INT33BE", 2, true), /* OV5693 */
{} {}
}; };
...@@ -500,6 +530,7 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev, ...@@ -500,6 +530,7 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev,
{ {
const struct acpi_device_id *id; const struct acpi_device_id *id;
int ret, clock_num; int ret, clock_num;
bool vcm = false;
int lanes = 1; int lanes = 1;
id = acpi_match_acpi_device(atomisp_sensor_configs, adev); id = acpi_match_acpi_device(atomisp_sensor_configs, adev);
...@@ -508,6 +539,7 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev, ...@@ -508,6 +539,7 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev,
(struct atomisp_sensor_config *)id->driver_data; (struct atomisp_sensor_config *)id->driver_data;
lanes = cfg->lanes; lanes = cfg->lanes;
vcm = cfg->vcm;
} }
/* /*
...@@ -545,6 +577,9 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev, ...@@ -545,6 +577,9 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev,
sensor->orientation = (sensor->link == 1) ? sensor->orientation = (sensor->link == 1) ?
V4L2_FWNODE_ORIENTATION_BACK : V4L2_FWNODE_ORIENTATION_FRONT; V4L2_FWNODE_ORIENTATION_BACK : V4L2_FWNODE_ORIENTATION_FRONT;
if (vcm)
sensor->vcm_type = atomisp_csi2_get_vcm_type(adev);
return 0; return 0;
} }
...@@ -583,6 +618,7 @@ static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier, ...@@ -583,6 +618,7 @@ static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier,
{ {
struct atomisp_device *isp = notifier_to_atomisp(notifier); struct atomisp_device *isp = notifier_to_atomisp(notifier);
struct sensor_async_subdev *s_asd = to_sensor_asd(asd); struct sensor_async_subdev *s_asd = to_sensor_asd(asd);
int ret;
if (s_asd->port >= ATOMISP_CAMERA_NR_PORTS) { if (s_asd->port >= ATOMISP_CAMERA_NR_PORTS) {
dev_err(isp->dev, "port %d not supported\n", s_asd->port); dev_err(isp->dev, "port %d not supported\n", s_asd->port);
...@@ -594,6 +630,10 @@ static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier, ...@@ -594,6 +630,10 @@ static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier,
return -EBUSY; return -EBUSY;
} }
ret = ipu_bridge_instantiate_vcm(sd->dev);
if (ret)
return ret;
isp->sensor_subdevs[s_asd->port] = sd; isp->sensor_subdevs[s_asd->port] = sd;
return 0; return 0;
} }
......
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