summaryrefslogtreecommitdiff
path: root/drivers/staging/media/atomisp/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/atomisp/pci')
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.c24
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_css20.c3
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_csi2.h67
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c414
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.c3
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_mipi.c16
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_param_dvs.c3
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_sp.c14
8 files changed, 138 insertions, 406 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index e27f9dc8e7aa..0803b296e9ac 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -3001,12 +3001,6 @@ void atomisp_handle_parameter_and_buffer(struct atomisp_video_pipe *pipe)
bool need_to_enqueue_buffer = false;
int i;
- if (!asd) {
- dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
- __func__, pipe->vdev.name);
- return;
- }
-
lockdep_assert_held(&asd->isp->mutex);
/*
@@ -3068,12 +3062,6 @@ int atomisp_set_parameters(struct video_device *vdev,
struct atomisp_css_params *css_param = &asd->params.css_param;
int ret;
- if (!asd) {
- dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
- __func__, vdev->name);
- return -EINVAL;
- }
-
lockdep_assert_held(&asd->isp->mutex);
if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
@@ -4067,12 +4055,6 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
const struct atomisp_in_fmt_conv *fc = NULL;
int ret, i;
- if (!asd) {
- dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
- __func__, vdev->name);
- return -EINVAL;
- }
-
isp_sink_crop = atomisp_subdev_get_rect(
&asd->subdev, NULL, V4L2_SUBDEV_FORMAT_ACTIVE,
ATOMISP_SUBDEV_PAD_SINK, V4L2_SEL_TGT_CROP);
@@ -4280,12 +4262,6 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
(struct atomisp_input_stream_info *)ffmt->reserved;
int ret;
- if (!asd) {
- dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
- __func__, vdev->name);
- return -EINVAL;
- }
-
format = atomisp_get_format_bridge(f->pixelformat);
if (!format)
return -EINVAL;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
index b13d1cb4668d..b97ec85aa0ba 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
@@ -613,9 +613,6 @@ static void __apply_additional_pipe_config(
static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd,
enum ia_css_pipe_id pipe_id)
{
- if (!asd)
- return false;
-
if (pipe_id == IA_CSS_PIPE_ID_YUVPP)
return true;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.h b/drivers/staging/media/atomisp/pci/atomisp_csi2.h
index 16ddb3ab2963..8a112acba1e0 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_csi2.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.h
@@ -30,9 +30,6 @@
#define CSI2_PAD_SOURCE 1
#define CSI2_PADS_NUM 2
-#define CSI2_MAX_LANES 4
-#define CSI2_MAX_LINK_FREQS 3
-
#define CSI2_MAX_ACPI_GPIOS 2u
struct acpi_device;
@@ -55,70 +52,6 @@ struct atomisp_csi2_acpi_gpio_parsing_data {
unsigned int map_count;
};
-enum atomisp_csi2_sensor_swnodes {
- SWNODE_SENSOR,
- SWNODE_SENSOR_PORT,
- SWNODE_SENSOR_ENDPOINT,
- SWNODE_CSI2_PORT,
- SWNODE_CSI2_ENDPOINT,
- SWNODE_COUNT
-};
-
-struct atomisp_csi2_property_names {
- char clock_frequency[16];
- char rotation[9];
- char bus_type[9];
- char data_lanes[11];
- char remote_endpoint[16];
- char link_frequencies[17];
-};
-
-struct atomisp_csi2_node_names {
- char port[7];
- char endpoint[11];
- char remote_port[7];
-};
-
-struct atomisp_csi2_sensor_config {
- const char *hid;
- int lanes;
- int nr_link_freqs;
- u64 link_freqs[CSI2_MAX_LINK_FREQS];
-};
-
-struct atomisp_csi2_sensor {
- /* Append port in "-%u" format as suffix of HID */
- char name[ACPI_ID_LEN + 4];
- struct acpi_device *adev;
- int port;
- int lanes;
-
- /* SWNODE_COUNT + 1 for terminating NULL */
- const struct software_node *group[SWNODE_COUNT + 1];
- struct software_node swnodes[SWNODE_COUNT];
- struct atomisp_csi2_node_names node_names;
- struct atomisp_csi2_property_names prop_names;
- /* "clock-frequency", "rotation" + terminating entry */
- struct property_entry dev_properties[3];
- /* "bus-type", "data-lanes", "remote-endpoint" + "link-freq" + terminating entry */
- struct property_entry ep_properties[5];
- /* "data-lanes", "remote-endpoint" + terminating entry */
- struct property_entry csi2_properties[3];
- struct software_node_ref_args local_ref[1];
- struct software_node_ref_args remote_ref[1];
- struct software_node_ref_args vcm_ref[1];
- /* GPIO mappings storage */
- struct atomisp_csi2_acpi_gpio_map gpio_map;
-};
-
-struct atomisp_csi2_bridge {
- struct software_node csi2_node;
- char csi2_node_name[14];
- u32 data_lanes[CSI2_MAX_LANES];
- unsigned int n_sensors;
- struct atomisp_csi2_sensor sensors[ATOMISP_CAMERA_NR_PORTS];
-};
-
struct atomisp_mipi_csi2_device {
struct v4l2_subdev subdev;
struct media_pad pads[CSI2_PADS_NUM];
diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c
index 0d12ba78d9c1..03940c11505f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c
@@ -14,31 +14,14 @@
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/property.h>
+
+#include <media/ipu-bridge.h>
#include <media/v4l2-fwnode.h>
#include "atomisp_cmd.h"
#include "atomisp_csi2.h"
#include "atomisp_internal.h"
-#define NODE_SENSOR(_HID, _PROPS) \
- ((const struct software_node) { \
- .name = _HID, \
- .properties = _PROPS, \
- })
-
-#define NODE_PORT(_PORT, _SENSOR_NODE) \
- ((const struct software_node) { \
- .name = _PORT, \
- .parent = _SENSOR_NODE, \
- })
-
-#define NODE_ENDPOINT(_EP, _PORT, _PROPS) \
- ((const struct software_node) { \
- .name = _EP, \
- .parent = _PORT, \
- .properties = _PROPS, \
- })
-
#define PMC_CLK_RATE_19_2MHZ 19200000
/*
@@ -84,20 +67,27 @@ static const guid_t atomisp_dsm_guid =
0x97, 0xb9, 0x88, 0x2a, 0x68, 0x60, 0xa4, 0xbe);
/*
- * Extend this array with ACPI Hardware IDs of sensors known to be working
- * plus the default number of links + link-frequencies.
- *
- * Do not add an entry for a sensor that is not actually supported,
- * or which have not yet been converted to work without atomisp_gmin
- * power-management and with v4l2-async probing.
+ * 75c9a639-5c8a-4a00-9f48-a9c3b5da789f
+ * This _DSM GUID returns a string giving the VCM type e.g. "AD5823".
*/
-static const struct atomisp_csi2_sensor_config supported_sensors[] = {
- /* GalaxyCore GC0310 */
- { "INT0310", 1 },
- /* Omnivision OV2680 */
- { "OVTI2680", 1 },
+static const guid_t vcm_dsm_guid =
+ GUID_INIT(0x75c9a639, 0x5c8a, 0x4a00,
+ 0x9f, 0x48, 0xa9, 0xc3, 0xb5, 0xda, 0x78, 0x9f);
+
+struct atomisp_sensor_config {
+ int lanes;
+ bool vcm;
};
+#define ATOMISP_SENSOR_CONFIG(_HID, _LANES, _VCM) \
+{ \
+ .id = _HID, \
+ .driver_data = (long)&((const struct atomisp_sensor_config) { \
+ .lanes = _LANES, \
+ .vcm = _VCM, \
+ }) \
+}
+
/*
* gmin_cfg parsing code. This is a cleaned up version of the gmin_cfg parsing
* code from atomisp_gmin_platform.c.
@@ -151,7 +141,8 @@ static char *gmin_cfg_get_dsm(struct acpi_device *adev, const char *key)
if (!val)
break;
- acpi_handle_info(adev->handle, "Using DSM entry %s=%s\n", key, val);
+ acpi_handle_info(adev->handle, "%s: Using DSM entry %s=%s\n",
+ dev_name(&adev->dev), key, val);
break;
}
}
@@ -176,7 +167,8 @@ static char *gmin_cfg_get_dmi_override(struct acpi_device *adev, const char *key
if (strcmp(key, gv->key))
continue;
- acpi_handle_info(adev->handle, "Using DMI entry %s=%s\n", key, gv->val);
+ acpi_handle_info(adev->handle, "%s: Using DMI entry %s=%s\n",
+ dev_name(&adev->dev), key, gv->val);
return kstrdup(gv->val, GFP_KERNEL);
}
@@ -212,7 +204,8 @@ static int gmin_cfg_get_int(struct acpi_device *adev, const char *key, int defau
return int_val;
out_use_default:
- acpi_handle_info(adev->handle, "Using default %s=%d\n", key, default_val);
+ acpi_handle_info(adev->handle, "%s: Using default %s=%d\n",
+ dev_name(&adev->dev), key, default_val);
return default_val;
}
@@ -255,7 +248,8 @@ static int atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(struct acpi_device *adev)
ACPI_FREE(buffer.pointer);
if (ret < 0)
- acpi_handle_warn(adev->handle, "Could not find PMC clk in _PR0\n");
+ acpi_handle_warn(adev->handle, "%s: Could not find PMC clk in _PR0\n",
+ dev_name(&adev->dev));
return ret;
}
@@ -274,7 +268,8 @@ static int atomisp_csi2_set_pmc_clk_freq(struct acpi_device *adev, int clock_num
clk = clk_get(NULL, name);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
- acpi_handle_err(adev->handle, "Error getting clk %s:%d\n", name, ret);
+ acpi_handle_err(adev->handle, "%s: Error getting clk %s: %d\n",
+ dev_name(&adev->dev), name, ret);
return ret;
}
@@ -288,7 +283,8 @@ static int atomisp_csi2_set_pmc_clk_freq(struct acpi_device *adev, int clock_num
if (!ret)
ret = clk_set_rate(clk, PMC_CLK_RATE_19_2MHZ);
if (ret)
- acpi_handle_err(adev->handle, "Error setting clk-rate for %s:%d\n", name, ret);
+ acpi_handle_err(adev->handle, "%s: Error setting clk-rate for %s: %d\n",
+ dev_name(&adev->dev), name, ret);
clk_put(clk);
return ret;
@@ -337,7 +333,8 @@ static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_
if (i == data->settings_count) {
acpi_handle_warn(data->adev->handle,
- "Could not find DSM GPIO settings for pin %u\n", pin);
+ "%s: Could not find DSM GPIO settings for pin %u\n",
+ dev_name(&data->adev->dev), pin);
return 1;
}
@@ -349,7 +346,8 @@ static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_
name = "powerdown-gpios";
break;
default:
- acpi_handle_warn(data->adev->handle, "Unknown GPIO type 0x%02lx for pin %u\n",
+ acpi_handle_warn(data->adev->handle, "%s: Unknown GPIO type 0x%02lx for pin %u\n",
+ dev_name(&data->adev->dev),
INTEL_GPIO_DSM_TYPE(settings), pin);
return 1;
}
@@ -374,7 +372,8 @@ static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_
data->map->mapping[i].size = 1;
data->map_count++;
- acpi_handle_info(data->adev->handle, "%s crs %d %s pin %u active-%s\n", name,
+ acpi_handle_info(data->adev->handle, "%s: %s crs %d %s pin %u active-%s\n",
+ dev_name(&data->adev->dev), name,
data->res_count - 1, agpio->resource_source.string_ptr,
pin, active_low ? "low" : "high");
@@ -400,8 +399,7 @@ static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_
* the INT3472 discrete.c code and there is some overlap, but there are
* enough differences that it is difficult to share the code.
*/
-static int atomisp_csi2_add_gpio_mappings(struct atomisp_csi2_sensor *sensor,
- struct acpi_device *adev)
+static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev)
{
struct atomisp_csi2_acpi_gpio_parsing_data data = { };
LIST_HEAD(resource_list);
@@ -412,7 +410,8 @@ static int atomisp_csi2_add_gpio_mappings(struct atomisp_csi2_sensor *sensor,
obj = acpi_evaluate_dsm_typed(adev->handle, &intel_sensor_module_guid,
0x00, 1, NULL, ACPI_TYPE_STRING);
if (obj) {
- acpi_handle_info(adev->handle, "Sensor module id: '%s'\n", obj->string.pointer);
+ acpi_handle_info(adev->handle, "%s: Sensor module id: '%s'\n",
+ dev_name(&adev->dev), obj->string.pointer);
ACPI_FREE(obj);
}
@@ -426,7 +425,8 @@ static int atomisp_csi2_add_gpio_mappings(struct atomisp_csi2_sensor *sensor,
&intel_sensor_gpio_info_guid, 0x00, 1,
NULL, ACPI_TYPE_INTEGER);
if (!obj) {
- acpi_handle_err(adev->handle, "No _DSM entry for GPIO pin count\n");
+ acpi_handle_err(adev->handle, "%s: No _DSM entry for GPIO pin count\n",
+ dev_name(&adev->dev));
return -EIO;
}
@@ -434,7 +434,9 @@ static int atomisp_csi2_add_gpio_mappings(struct atomisp_csi2_sensor *sensor,
ACPI_FREE(obj);
if (data.settings_count > CSI2_MAX_ACPI_GPIOS) {
- acpi_handle_err(adev->handle, "Too many GPIOs %u > %u\n", data.settings_count, CSI2_MAX_ACPI_GPIOS);
+ acpi_handle_err(adev->handle, "%s: Too many GPIOs %u > %u\n",
+ dev_name(&adev->dev), data.settings_count,
+ CSI2_MAX_ACPI_GPIOS);
return -EOVERFLOW;
}
@@ -448,7 +450,8 @@ static int atomisp_csi2_add_gpio_mappings(struct atomisp_csi2_sensor *sensor,
0x00, i + 2,
NULL, ACPI_TYPE_INTEGER);
if (!obj) {
- acpi_handle_err(adev->handle, "No _DSM entry for pin %u\n", i);
+ acpi_handle_err(adev->handle, "%s: No _DSM entry for pin %u\n",
+ dev_name(&adev->dev), i);
return -EIO;
}
@@ -463,15 +466,19 @@ static int atomisp_csi2_add_gpio_mappings(struct atomisp_csi2_sensor *sensor,
INTEL_GPIO_DSM_PIN(data.settings[j]))
continue;
- acpi_handle_err(adev->handle, "Duplicate pin number %lu\n",
+ acpi_handle_err(adev->handle, "%s: Duplicate pin number %lu\n",
+ dev_name(&adev->dev),
INTEL_GPIO_DSM_PIN(data.settings[i]));
return -EIO;
}
}
+ data.map = kzalloc(sizeof(*data.map), GFP_KERNEL);
+ if (!data.map)
+ return -ENOMEM;
+
/* Now parse the ACPI resources and build the lookup table */
data.adev = adev;
- data.map = &sensor->gpio_map;
ret = acpi_dev_get_resources(adev, &resource_list,
atomisp_csi2_handle_acpi_gpio_res, &data);
if (ret < 0)
@@ -481,230 +488,105 @@ static int atomisp_csi2_add_gpio_mappings(struct atomisp_csi2_sensor *sensor,
if (data.map_count != data.settings_count ||
data.res_count != data.settings_count)
- acpi_handle_warn(adev->handle, "ACPI GPIO resources vs DSM GPIO-info count mismatch (dsm: %d res: %d map %d\n",
- data.settings_count, data.res_count, data.map_count);
+ acpi_handle_warn(adev->handle, "%s: ACPI GPIO resources vs DSM GPIO-info count mismatch (dsm: %d res: %d map %d\n",
+ dev_name(&adev->dev), data.settings_count,
+ data.res_count, data.map_count);
ret = acpi_dev_add_driver_gpios(adev, data.map->mapping);
if (ret)
- acpi_handle_err(adev->handle, "Error adding driver GPIOs: %d\n", ret);
+ acpi_handle_err(adev->handle, "%s: Error adding driver GPIOs: %d\n",
+ dev_name(&adev->dev), ret);
return ret;
}
-static const struct atomisp_csi2_property_names prop_names = {
- .clock_frequency = "clock-frequency",
- .rotation = "rotation",
- .bus_type = "bus-type",
- .data_lanes = "data-lanes",
- .remote_endpoint = "remote-endpoint",
- .link_frequencies = "link-frequencies",
-};
-
-static void atomisp_csi2_create_fwnode_properties(struct atomisp_csi2_sensor *sensor,
- struct atomisp_csi2_bridge *bridge,
- const struct atomisp_csi2_sensor_config *cfg)
+static char *atomisp_csi2_get_vcm_type(struct acpi_device *adev)
{
- sensor->prop_names = prop_names;
-
- sensor->local_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_CSI2_ENDPOINT]);
- sensor->remote_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_SENSOR_ENDPOINT]);
-
- sensor->dev_properties[0] = PROPERTY_ENTRY_U32(sensor->prop_names.clock_frequency,
- PMC_CLK_RATE_19_2MHZ);
- sensor->dev_properties[1] = PROPERTY_ENTRY_U32(sensor->prop_names.rotation, 0);
-
- sensor->ep_properties[0] = PROPERTY_ENTRY_U32(sensor->prop_names.bus_type,
- V4L2_FWNODE_BUS_TYPE_CSI2_DPHY);
- sensor->ep_properties[1] = PROPERTY_ENTRY_U32_ARRAY_LEN(sensor->prop_names.data_lanes,
- bridge->data_lanes,
- sensor->lanes);
- sensor->ep_properties[2] = PROPERTY_ENTRY_REF_ARRAY(sensor->prop_names.remote_endpoint,
- sensor->local_ref);
- if (cfg->nr_link_freqs > 0)
- sensor->ep_properties[3] =
- PROPERTY_ENTRY_U64_ARRAY_LEN(sensor->prop_names.link_frequencies,
- cfg->link_freqs, cfg->nr_link_freqs);
-
- sensor->csi2_properties[0] = PROPERTY_ENTRY_U32_ARRAY_LEN(sensor->prop_names.data_lanes,
- bridge->data_lanes,
- sensor->lanes);
- sensor->csi2_properties[1] = PROPERTY_ENTRY_REF_ARRAY(sensor->prop_names.remote_endpoint,
- sensor->remote_ref);
-}
+ union acpi_object *obj;
+ char *vcm_type;
-static void atomisp_csi2_init_swnode_names(struct atomisp_csi2_sensor *sensor)
-{
- snprintf(sensor->node_names.remote_port,
- sizeof(sensor->node_names.remote_port),
- SWNODE_GRAPH_PORT_NAME_FMT, sensor->port);
- snprintf(sensor->node_names.port,
- sizeof(sensor->node_names.port),
- SWNODE_GRAPH_PORT_NAME_FMT, 0); /* Always port 0 */
- snprintf(sensor->node_names.endpoint,
- sizeof(sensor->node_names.endpoint),
- SWNODE_GRAPH_ENDPOINT_NAME_FMT, 0); /* And endpoint 0 */
-}
+ obj = acpi_evaluate_dsm_typed(adev->handle, &vcm_dsm_guid, 0, 0,
+ NULL, ACPI_TYPE_STRING);
+ if (!obj)
+ return NULL;
-static void atomisp_csi2_init_swnode_group(struct atomisp_csi2_sensor *sensor)
-{
- struct software_node *nodes = sensor->swnodes;
+ vcm_type = kstrdup(obj->string.pointer, GFP_KERNEL);
+ ACPI_FREE(obj);
- sensor->group[SWNODE_SENSOR] = &nodes[SWNODE_SENSOR];
- sensor->group[SWNODE_SENSOR_PORT] = &nodes[SWNODE_SENSOR_PORT];
- sensor->group[SWNODE_SENSOR_ENDPOINT] = &nodes[SWNODE_SENSOR_ENDPOINT];
- sensor->group[SWNODE_CSI2_PORT] = &nodes[SWNODE_CSI2_PORT];
- sensor->group[SWNODE_CSI2_ENDPOINT] = &nodes[SWNODE_CSI2_ENDPOINT];
-}
+ if (!vcm_type)
+ return NULL;
-static void atomisp_csi2_create_connection_swnodes(struct atomisp_csi2_bridge *bridge,
- struct atomisp_csi2_sensor *sensor)
-{
- struct software_node *nodes = sensor->swnodes;
-
- atomisp_csi2_init_swnode_names(sensor);
-
- nodes[SWNODE_SENSOR] = NODE_SENSOR(sensor->name,
- sensor->dev_properties);
- nodes[SWNODE_SENSOR_PORT] = NODE_PORT(sensor->node_names.port,
- &nodes[SWNODE_SENSOR]);
- nodes[SWNODE_SENSOR_ENDPOINT] = NODE_ENDPOINT(sensor->node_names.endpoint,
- &nodes[SWNODE_SENSOR_PORT],
- sensor->ep_properties);
- nodes[SWNODE_CSI2_PORT] = NODE_PORT(sensor->node_names.remote_port,
- &bridge->csi2_node);
- nodes[SWNODE_CSI2_ENDPOINT] = NODE_ENDPOINT(sensor->node_names.endpoint,
- &nodes[SWNODE_CSI2_PORT],
- sensor->csi2_properties);
-
- atomisp_csi2_init_swnode_group(sensor);
+ string_lower(vcm_type, vcm_type);
+ return vcm_type;
}
-static void atomisp_csi2_unregister_sensors(struct atomisp_csi2_bridge *bridge)
-{
- struct atomisp_csi2_sensor *sensor;
- unsigned int i;
-
- for (i = 0; i < bridge->n_sensors; i++) {
- sensor = &bridge->sensors[i];
- software_node_unregister_node_group(sensor->group);
- acpi_dev_remove_driver_gpios(sensor->adev);
- acpi_dev_put(sensor->adev);
- }
-}
+static const struct acpi_device_id atomisp_sensor_configs[] = {
+ ATOMISP_SENSOR_CONFIG("INT33BE", 2, true), /* OV5693 */
+ {}
+};
-static int atomisp_csi2_connect_sensor(const struct atomisp_csi2_sensor_config *cfg,
- struct atomisp_csi2_bridge *bridge,
- struct atomisp_device *isp)
+static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev,
+ struct ipu_sensor *sensor)
{
- struct fwnode_handle *fwnode, *primary;
- struct atomisp_csi2_sensor *sensor;
- struct acpi_device *adev;
+ const struct acpi_device_id *id;
int ret, clock_num;
+ bool vcm = false;
+ int lanes = 1;
- for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
- if (!adev->status.enabled)
- continue;
-
- if (bridge->n_sensors >= ATOMISP_CAMERA_NR_PORTS) {
- dev_err(isp->dev, "Exceeded available CSI2 ports\n");
- ret = -EOVERFLOW;
- goto err_put_adev;
- }
-
- sensor = &bridge->sensors[bridge->n_sensors];
-
- /*
- * ACPI takes care of turning the PMC clock on and off, but on BYT
- * the clock defaults to 25 MHz instead of the expected 19.2 MHz.
- * Get the PMC-clock number from ACPI _PR0 method and set it to 19.2 MHz.
- * The PMC-clock number is also used to determine the default CSI port.
- */
- clock_num = atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(adev);
-
- ret = atomisp_csi2_set_pmc_clk_freq(adev, clock_num);
- if (ret)
- goto err_put_adev;
-
- sensor->port = atomisp_csi2_get_port(adev, clock_num);
- if (sensor->port >= ATOMISP_CAMERA_NR_PORTS) {
- acpi_handle_err(adev->handle, "Invalid port: %d\n", sensor->port);
- ret = -EINVAL;
- goto err_put_adev;
- }
-
- sensor->lanes = gmin_cfg_get_int(adev, "CsiLanes", cfg->lanes);
- if (sensor->lanes > CSI2_MAX_LANES) {
- acpi_handle_err(adev->handle, "Invalid number of lanes: %d\n", sensor->lanes);
- ret = -EINVAL;
- goto err_put_adev;
- }
-
- ret = atomisp_csi2_add_gpio_mappings(sensor, adev);
- if (ret)
- goto err_put_adev;
+ id = acpi_match_acpi_device(atomisp_sensor_configs, adev);
+ if (id) {
+ struct atomisp_sensor_config *cfg =
+ (struct atomisp_sensor_config *)id->driver_data;
- snprintf(sensor->name, sizeof(sensor->name), "%s-%u",
- cfg->hid, sensor->port);
-
- atomisp_csi2_create_fwnode_properties(sensor, bridge, cfg);
- atomisp_csi2_create_connection_swnodes(bridge, sensor);
-
- ret = software_node_register_node_group(sensor->group);
- if (ret)
- goto err_remove_mappings;
-
- fwnode = software_node_fwnode(&sensor->swnodes[SWNODE_SENSOR]);
- if (!fwnode) {
- ret = -ENODEV;
- goto err_free_swnodes;
- }
+ lanes = cfg->lanes;
+ vcm = cfg->vcm;
+ }
- sensor->adev = acpi_dev_get(adev);
+ /*
+ * ACPI takes care of turning the PMC clock on and off, but on BYT
+ * the clock defaults to 25 MHz instead of the expected 19.2 MHz.
+ * Get the PMC-clock number from ACPI PR0 method and set it to 19.2 MHz.
+ * The PMC-clock number is also used to determine the default CSI port.
+ */
+ clock_num = atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(adev);
- primary = acpi_fwnode_handle(adev);
- primary->secondary = fwnode;
+ ret = atomisp_csi2_set_pmc_clk_freq(adev, clock_num);
+ if (ret)
+ return ret;
- bridge->n_sensors++;
+ sensor->link = atomisp_csi2_get_port(adev, clock_num);
+ if (sensor->link >= ATOMISP_CAMERA_NR_PORTS) {
+ acpi_handle_err(adev->handle, "%s: Invalid port: %u\n",
+ dev_name(&adev->dev), sensor->link);
+ return -EINVAL;
}
- return 0;
-
-err_free_swnodes:
- software_node_unregister_node_group(sensor->group);
-err_remove_mappings:
- acpi_dev_remove_driver_gpios(adev);
-err_put_adev:
- acpi_dev_put(adev);
- return ret;
-}
+ sensor->lanes = gmin_cfg_get_int(adev, "CsiLanes", lanes);
+ if (sensor->lanes > IPU_MAX_LANES) {
+ acpi_handle_err(adev->handle, "%s: Invalid lane-count: %d\n",
+ dev_name(&adev->dev), sensor->lanes);
+ return -EINVAL;
+ }
-static int atomisp_csi2_connect_sensors(struct atomisp_csi2_bridge *bridge,
- struct atomisp_device *isp)
-{
- unsigned int i;
- int ret;
+ ret = atomisp_csi2_add_gpio_mappings(adev);
+ if (ret)
+ return ret;
- for (i = 0; i < ARRAY_SIZE(supported_sensors); i++) {
- const struct atomisp_csi2_sensor_config *cfg = &supported_sensors[i];
+ sensor->mclkspeed = PMC_CLK_RATE_19_2MHZ;
+ sensor->rotation = 0;
+ sensor->orientation = (sensor->link == 1) ?
+ V4L2_FWNODE_ORIENTATION_BACK : V4L2_FWNODE_ORIENTATION_FRONT;
- ret = atomisp_csi2_connect_sensor(cfg, bridge, isp);
- if (ret)
- goto err_unregister_sensors;
- }
+ if (vcm)
+ sensor->vcm_type = atomisp_csi2_get_vcm_type(adev);
return 0;
-
-err_unregister_sensors:
- atomisp_csi2_unregister_sensors(bridge);
- return ret;
}
int atomisp_csi2_bridge_init(struct atomisp_device *isp)
{
- struct atomisp_csi2_bridge *bridge;
struct device *dev = isp->dev;
struct fwnode_handle *fwnode;
- int i, ret;
/*
* This function is intended to run only once and then leave
@@ -716,58 +598,13 @@ int atomisp_csi2_bridge_init(struct atomisp_device *isp)
if (fwnode && fwnode->secondary)
return 0;
- bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
- if (!bridge)
- return -ENOMEM;
-
- strscpy(bridge->csi2_node_name, "atomisp-csi2", sizeof(bridge->csi2_node_name));
- bridge->csi2_node.name = bridge->csi2_node_name;
-
- ret = software_node_register(&bridge->csi2_node);
- if (ret < 0) {
- dev_err(dev, "Failed to register the CSI2 HID node\n");
- goto err_free_bridge;
- }
-
- /*
- * Map the lane arrangement, which is fixed for the ISP2 (meaning we
- * only need one, rather than one per sensor). We include it as a
- * member of the bridge struct rather than a global variable so
- * that it survives if the module is unloaded along with the rest of
- * the struct.
- */
- for (i = 0; i < CSI2_MAX_LANES; i++)
- bridge->data_lanes[i] = i + 1;
-
- ret = atomisp_csi2_connect_sensors(bridge, isp);
- if (ret || bridge->n_sensors == 0)
- goto err_unregister_csi2;
-
- fwnode = software_node_fwnode(&bridge->csi2_node);
- if (!fwnode) {
- dev_err(dev, "Error getting fwnode from csi2 software_node\n");
- ret = -ENODEV;
- goto err_unregister_sensors;
- }
-
- set_secondary_fwnode(dev, fwnode);
-
- return 0;
-
-err_unregister_sensors:
- atomisp_csi2_unregister_sensors(bridge);
-err_unregister_csi2:
- software_node_unregister(&bridge->csi2_node);
-err_free_bridge:
- kfree(bridge);
-
- return ret;
+ return ipu_bridge_init(dev, atomisp_csi2_parse_sensor_fwnode);
}
/******* V4L2 sub-device asynchronous registration callbacks***********/
struct sensor_async_subdev {
- struct v4l2_async_subdev asd;
+ struct v4l2_async_connection asd;
int port;
};
@@ -777,10 +614,11 @@ struct sensor_async_subdev {
/* .bound() notifier callback when a match is found */
static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *sd,
- struct v4l2_async_subdev *asd)
+ struct v4l2_async_connection *asd)
{
struct atomisp_device *isp = notifier_to_atomisp(notifier);
struct sensor_async_subdev *s_asd = to_sensor_asd(asd);
+ int ret;
if (s_asd->port >= ATOMISP_CAMERA_NR_PORTS) {
dev_err(isp->dev, "port %d not supported\n", s_asd->port);
@@ -792,6 +630,10 @@ static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier,
return -EBUSY;
}
+ ret = ipu_bridge_instantiate_vcm(sd->dev);
+ if (ret)
+ return ret;
+
isp->sensor_subdevs[s_asd->port] = sd;
return 0;
}
@@ -799,7 +641,7 @@ static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier,
/* The .unbind callback */
static void atomisp_notifier_unbind(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *sd,
- struct v4l2_async_subdev *asd)
+ struct v4l2_async_connection *asd)
{
struct atomisp_device *isp = notifier_to_atomisp(notifier);
struct sensor_async_subdev *s_asd = to_sensor_asd(asd);
@@ -825,7 +667,7 @@ int atomisp_csi2_bridge_parse_firmware(struct atomisp_device *isp)
{
int i, mipi_port, ret;
- v4l2_async_nf_init(&isp->notifier);
+ v4l2_async_nf_init(&isp->notifier, &isp->v4l2_dev);
isp->notifier.ops = &atomisp_async_ops;
for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index c43b916a006e..0d0329f5e4ad 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -1508,7 +1508,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
isp->firmware = NULL;
isp->css_env.isp_css_fw.data = NULL;
- err = v4l2_async_nf_register(&isp->v4l2_dev, &isp->notifier);
+ err = v4l2_async_nf_register(&isp->notifier);
if (err) {
dev_err(isp->dev, "failed to register async notifier : %d\n", err);
goto css_init_fail;
@@ -1615,3 +1615,4 @@ MODULE_AUTHOR("Wen Wang <wen.w.wang@intel.com>");
MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Intel ATOM Platform ISP Driver");
+MODULE_IMPORT_NS(INTEL_IPU_BRIDGE);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
index b20acaab0595..ced21dedf7ac 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
@@ -351,15 +351,6 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) enter:\n", pipe);
- assert(pipe);
- assert(pipe->stream);
- if ((!pipe) || (!pipe->stream)) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "allocate_mipi_frames(%p) exit: pipe or stream is null.\n",
- pipe);
- return -EINVAL;
- }
-
if (IS_ISP2401 && pipe->stream->config.online) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) exit: no buffers needed for 2401 pipe mode.\n",
@@ -557,13 +548,6 @@ send_mipi_frames(struct ia_css_pipe *pipe)
IA_CSS_ENTER_PRIVATE("pipe=%p", pipe);
- assert(pipe);
- assert(pipe->stream);
- if (!pipe || !pipe->stream) {
- IA_CSS_ERROR("pipe or stream is null");
- return -EINVAL;
- }
-
/* multi stream video needs mipi buffers */
/* nothing to be done in other cases. */
if (pipe->stream->config.mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
index ff0082d02af3..5174bc210ae1 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
@@ -202,9 +202,6 @@ generate_dvs_6axis_table_from_config(struct ia_css_dvs_6axis_config
void
free_dvs_6axis_table(struct ia_css_dvs_6axis_config **dvs_6axis_config)
{
- assert(dvs_6axis_config);
- assert(*dvs_6axis_config);
-
if ((dvs_6axis_config) && (*dvs_6axis_config)) {
IA_CSS_ENTER_PRIVATE("dvs_6axis_config %p", (*dvs_6axis_config));
if ((*dvs_6axis_config)->xcoords_y) {
diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.c b/drivers/staging/media/atomisp/pci/sh_css_sp.c
index 297e1b981720..f35c745c22c0 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_sp.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_sp.c
@@ -51,6 +51,7 @@
#include "ia_css_event.h"
#include "mmu_device.h"
#include "ia_css_spctrl.h"
+#include "atomisp_internal.h"
#ifndef offsetof
#define offsetof(T, x) ((unsigned int)&(((T *)0)->x))
@@ -1212,14 +1213,15 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
struct ia_css_binary *first_binary = NULL;
struct ia_css_pipe *pipe = NULL;
unsigned int num;
-
enum ia_css_pipe_id pipe_id = id;
unsigned int thread_id;
u8 if_config_index, tmp_if_config_index;
- assert(me);
-
- assert(me->stages);
+ if (!me->stages) {
+ dev_err(atomisp_dev, "%s called on a pipeline without stages\n",
+ __func__);
+ return; /* FIXME should be able to return an error */
+ }
first_binary = me->stages->binary;
@@ -1252,8 +1254,8 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
} /* if (first_binary != NULL) */
/* Signal the host immediately after start for SP_ISYS_COPY only */
- if ((me->num_stages == 1) && me->stages &&
- (me->stages->sp_func == IA_CSS_PIPELINE_ISYS_COPY))
+ if (me->num_stages == 1 &&
+ me->stages->sp_func == IA_CSS_PIPELINE_ISYS_COPY)
sh_css_sp_group.config.no_isp_sync = true;
/* Init stage data */