]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
greybus: camera: HACK: Register gb camera to the HOST camera
authorGjorgji Rosikopulos <grosikopulos@mm-sol.com>
Wed, 13 Jan 2016 19:52:38 +0000 (21:52 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 13 Jan 2016 23:29:59 +0000 (15:29 -0800)
This change implements gb camera interface and register
gb camera to the HOST driver.
This implementation need to be reworked after the demo.

Tested with db3 with two camera modules.

Signed-off-by: Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
Acked-by: Laurent Pinchart <laurent.pinchart@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/camera.c

index 783a435bbae6b12ce7a589b4d4da39a3c2698bbb..a69797b13c845357d00ebee593586108b7d5a504 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>
 
+#include "gb-camera.h"
 #include "greybus.h"
 #include "greybus_protocols.h"
 
@@ -57,6 +58,31 @@ struct gb_camera_stream_config {
        unsigned int max_size;
 };
 
+struct gb_camera_fmt_map {
+       enum v4l2_mbus_pixelcode mbus_code;
+       unsigned int gb_format;
+};
+
+/* GB format to media code map */
+static const struct gb_camera_fmt_map mbus_to_gbus_format[] = {
+       {
+               .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16,
+               .gb_format = 0x01,
+       },
+       {
+               .mbus_code = V4L2_MBUS_FMT_YUYV8_1_5X8,
+               .gb_format = 0x16,
+       },
+       {
+               .mbus_code = V4L2_MBUS_FMT_YVYU8_1_5X8,
+               .gb_format = 0x17,
+       },
+       {
+               .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
+               .gb_format = 0x40,
+       }
+};
+
 #define ES2_APB_CDSI0_CPORT            16
 #define ES2_APB_CDSI1_CPORT            17
 
@@ -260,6 +286,97 @@ static int gb_camera_event_recv(u8 type, struct gb_operation *op)
        return 0;
 }
 
+/* -----------------------------------------------------------------------------
+ * Interface with HOST ara camera.
+ */
+static unsigned int gb_camera_mbus_to_gb(enum v4l2_mbus_pixelcode mbus_code)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(mbus_to_gbus_format); i++) {
+               if (mbus_to_gbus_format[i].mbus_code == mbus_code)
+                       return mbus_to_gbus_format[i].gb_format;
+       }
+       return mbus_to_gbus_format[0].gb_format;
+}
+
+static enum v4l2_mbus_pixelcode gb_camera_gb_to_mbus(u16 gb_fmt)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(mbus_to_gbus_format); i++) {
+               if (mbus_to_gbus_format[i].gb_format == gb_fmt)
+                       return mbus_to_gbus_format[i].mbus_code;
+       }
+       return mbus_to_gbus_format[0].mbus_code;
+}
+
+static int gb_camera_op_configure_streams(void *priv, unsigned int nstreams,
+                       struct gb_camera_stream *streams)
+{
+       struct gb_camera *gcam = priv;
+       struct gb_camera_stream_config *gb_streams;
+       unsigned int i;
+       int ret;
+
+       if (nstreams > GB_CAMERA_MAX_STREAMS)
+               return -EINVAL;
+
+       gb_streams = kzalloc(nstreams * sizeof(*gb_streams), GFP_KERNEL);
+       if (!gb_streams)
+               return -ENOMEM;
+
+       for (i = 0; i < nstreams; i++) {
+               gb_streams[i].width = streams[i].width;
+               gb_streams[i].height = streams[i].height;
+               gb_streams[i].format =
+                       gb_camera_mbus_to_gb(streams[i].pixel_code);
+       }
+
+       ret = gb_camera_configure_streams(gcam, nstreams, 0, gb_streams);
+       if (ret < 0)
+               goto done;
+
+       for (i = 0; i < nstreams; i++) {
+               streams[i].width = gb_streams[i].width;
+               streams[i].height = gb_streams[i].height;
+               streams[i].vc = gb_streams[i].vc;
+               streams[i].dt[0] = gb_streams[i].dt[0];
+               streams[i].dt[1] = gb_streams[i].dt[1];
+               streams[i].max_size = gb_streams[i].max_size;
+               streams[i].pixel_code =
+                       gb_camera_gb_to_mbus(gb_streams[i].format);
+       }
+
+done:
+       kfree(gb_streams);
+       return ret;
+}
+
+static int gb_camera_op_capture(void *priv, u32 request_id,
+               unsigned int streams, unsigned int num_frames,
+               size_t settings_size, const void *settings)
+{
+       return gb_camera_capture(priv, request_id, streams, num_frames,
+                                settings_size, settings);
+}
+
+static int gb_camera_op_flush(void *priv, u32 *request_id)
+{
+       return gb_camera_flush(priv, request_id);
+}
+
+struct gb_camera_ops gb_cam_ops = {
+       .configure_streams = gb_camera_op_configure_streams,
+       .capture = gb_camera_op_capture,
+       .flush = gb_camera_op_flush,
+};
+
+static int gb_camera_register_intf_ops(struct gb_camera *gcam)
+{
+       return gb_camera_register(&gb_cam_ops, gcam);
+}
+
 /* -----------------------------------------------------------------------------
  * DebugFS
  */
@@ -646,6 +763,10 @@ static int gb_camera_connection_init(struct gb_connection *connection)
        if (ret < 0)
                goto error;
 
+       ret = gb_camera_register_intf_ops(gcam);
+       if (ret < 0)
+               goto error;
+
        return 0;
 
 error: