2 * Greybus Camera protocol driver.
4 * Copyright 2015 Google Inc.
5 * Copyright 2015 Linaro Ltd.
7 * Released under the GPLv2 only.
10 #include <linux/debugfs.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/string.h>
16 #include <linux/uaccess.h>
17 #include <linux/vmalloc.h>
19 #include "gb-camera.h"
21 #include "greybus_protocols.h"
23 enum gb_camera_debugs_buffer_id {
24 GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,
25 GB_CAMERA_DEBUGFS_BUFFER_STREAMS,
26 GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,
27 GB_CAMERA_DEBUGFS_BUFFER_FLUSH,
28 GB_CAMERA_DEBUGFS_BUFFER_MAX,
31 struct gb_camera_debugfs_buffer {
37 * struct gb_camera - A Greybus Camera Device
38 * @connection: the greybus connection for camera control
39 * @data_connected: whether the data connection has been established
40 * @debugfs: debugfs entries for camera protocol operations testing
41 * @module: Greybus camera module registered to HOST processor.
44 struct gb_connection *connection;
45 struct gb_connection *data_connection;
49 struct gb_camera_debugfs_buffer *buffers;
52 struct gb_camera_module module;
55 struct gb_camera_stream_config {
61 unsigned int max_size;
64 struct gb_camera_fmt_map {
65 enum v4l2_mbus_pixelcode mbus_code;
66 unsigned int gb_format;
69 /* GB format to media code map */
70 static const struct gb_camera_fmt_map mbus_to_gbus_format[] = {
72 .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16,
76 .mbus_code = V4L2_MBUS_FMT_NV12_1x8,
80 .mbus_code = V4L2_MBUS_FMT_NV21_1x8,
84 .mbus_code = V4L2_MBUS_FMT_YU12_1x8,
88 .mbus_code = V4L2_MBUS_FMT_YV12_1x8,
92 .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
96 .mbus_code = V4L2_MBUS_FMT_ARA_METADATA_1X8,
101 #define ES2_APB_CDSI0_CPORT 16
102 #define ES2_APB_CDSI1_CPORT 17
104 #define GB_CAMERA_MAX_SETTINGS_SIZE 8192
106 #define gcam_dbg(gcam, format...) \
107 dev_dbg(&gcam->connection->bundle->dev, format)
108 #define gcam_info(gcam, format...) \
109 dev_info(&gcam->connection->bundle->dev, format)
110 #define gcam_err(gcam, format...) \
111 dev_err(&gcam->connection->bundle->dev, format)
113 /* -----------------------------------------------------------------------------
114 * Camera Protocol Operations
117 static int gb_camera_set_intf_power_mode(struct gb_camera *gcam, u8 intf_id,
120 struct gb_svc *svc = gcam->connection->hd->svc;
124 ret = gb_svc_intf_set_power_mode(svc, intf_id,
125 GB_SVC_UNIPRO_HS_SERIES_A,
126 GB_SVC_UNIPRO_FAST_MODE, 2, 2,
127 GB_SVC_UNIPRO_FAST_MODE, 2, 2,
128 GB_SVC_PWRM_RXTERMINATION |
129 GB_SVC_PWRM_TXTERMINATION, 0);
131 ret = gb_svc_intf_set_power_mode(svc, intf_id,
132 GB_SVC_UNIPRO_HS_SERIES_A,
133 GB_SVC_UNIPRO_SLOW_AUTO_MODE,
135 GB_SVC_UNIPRO_SLOW_AUTO_MODE,
142 static int gb_camera_set_power_mode(struct gb_camera *gcam, bool hs)
144 struct gb_interface *intf = gcam->connection->intf;
145 struct gb_svc *svc = gcam->connection->hd->svc;
148 ret = gb_camera_set_intf_power_mode(gcam, intf->interface_id, hs);
150 gcam_err(gcam, "failed to set module interface to %s (%d)\n",
151 hs ? "HS" : "PWM", ret);
155 ret = gb_camera_set_intf_power_mode(gcam, svc->ap_intf_id, hs);
157 gb_camera_set_intf_power_mode(gcam, intf->interface_id, !hs);
158 gcam_err(gcam, "failed to set AP interface to %s (%d)\n",
159 hs ? "HS" : "PWM", ret);
166 static int gb_camera_capabilities(struct gb_camera *gcam,
167 u8 *capabilities, size_t *size)
169 struct gb_operation *op;
172 op = gb_operation_create_flags(gcam->connection,
173 GB_CAMERA_TYPE_CAPABILITIES, 0, *size,
174 GB_OPERATION_FLAG_SHORT_RESPONSE,
179 ret = gb_operation_request_send_sync(op);
181 gcam_err(gcam, "failed to retrieve capabilities: %d\n", ret);
185 memcpy(capabilities, op->response->payload, op->response->payload_size);
186 *size = op->response->payload_size;
189 gb_operation_put(op);
193 struct ap_csi_config_request {
196 #define GB_CAMERA_CSI_FLAG_CLOCK_CONTINUOUS 0x01
200 __le32 lines_per_second;
203 static int gb_camera_configure_streams(struct gb_camera *gcam,
204 unsigned int *num_streams,
206 struct gb_camera_stream_config *streams,
207 struct gb_camera_csi_params *csi_params)
209 struct gb_camera_configure_streams_request *req;
210 struct gb_camera_configure_streams_response *resp;
211 struct ap_csi_config_request csi_cfg;
213 unsigned int nstreams = *num_streams;
219 if (nstreams > GB_CAMERA_MAX_STREAMS)
222 req_size = sizeof(*req) + nstreams * sizeof(req->config[0]);
223 resp_size = sizeof(*resp) + nstreams * sizeof(resp->config[0]);
225 req = kmalloc(req_size, GFP_KERNEL);
226 resp = kmalloc(resp_size, GFP_KERNEL);
232 req->num_streams = nstreams;
236 for (i = 0; i < nstreams; ++i) {
237 struct gb_camera_stream_config_request *cfg = &req->config[i];
239 cfg->width = cpu_to_le16(streams[i].width);
240 cfg->height = cpu_to_le16(streams[i].height);
241 cfg->format = cpu_to_le16(streams[i].format);
245 ret = gb_operation_sync(gcam->connection,
246 GB_CAMERA_TYPE_CONFIGURE_STREAMS,
247 req, req_size, resp, resp_size);
251 if (resp->num_streams > nstreams) {
252 gcam_dbg(gcam, "got #streams %u > request %u\n",
253 resp->num_streams, nstreams);
258 if (resp->padding != 0) {
259 gcam_dbg(gcam, "response padding != 0");
264 for (i = 0; i < nstreams; ++i) {
265 struct gb_camera_stream_config_response *cfg = &resp->config[i];
267 streams[i].width = le16_to_cpu(cfg->width);
268 streams[i].height = le16_to_cpu(cfg->height);
269 streams[i].format = le16_to_cpu(cfg->format);
270 streams[i].vc = cfg->virtual_channel;
271 streams[i].dt[0] = cfg->data_type[0];
272 streams[i].dt[1] = cfg->data_type[1];
273 streams[i].max_size = le32_to_cpu(cfg->max_size);
275 if (cfg->padding[0] || cfg->padding[1] || cfg->padding[2]) {
276 gcam_dbg(gcam, "stream #%u padding != 0", i);
282 if ((resp->flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED) ||
283 (*flags & GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY)) {
284 *flags = resp->flags;
285 *num_streams = resp->num_streams;
289 /* Setup unipro link speed. */
290 ret = gb_camera_set_power_mode(gcam, nstreams != 0);
295 * Configure the APB1 CSI transmitter using the lines count reported by
296 * the camera module, but with hard-coded bus frequency and lanes number.
298 * TODO: use the clocking and size informations reported by camera module
299 * to compute the required CSI bandwidth, and configure the CSI receiver
300 * on AP side, and the CSI transmitter on APB1 side accordingly.
302 memset(&csi_cfg, 0, sizeof(csi_cfg));
307 csi_cfg.num_lanes = resp->num_lanes;
308 csi_cfg.bus_freq = cpu_to_le32(960000000);
309 csi_cfg.lines_per_second = resp->lines_per_second;
310 ret = gb_hd_output(gcam->connection->hd, &csi_cfg,
312 GB_APB_REQUEST_CSI_TX_CONTROL, false);
314 csi_params->num_lanes = csi_cfg.num_lanes;
315 /* Transmitting two bits per cycle. (DDR clock) */
316 csi_params->clk_freq = csi_cfg.bus_freq / 2;
317 csi_params->lines_per_second = csi_cfg.lines_per_second;
321 ret = gb_hd_output(gcam->connection->hd, &csi_cfg,
323 GB_APB_REQUEST_CSI_TX_CONTROL, false);
327 gcam_err(gcam, "failed to %s the CSI transmitter\n",
328 nstreams ? "start" : "stop");
330 *flags = resp->flags;
331 *num_streams = resp->num_streams;
340 static int gb_camera_capture(struct gb_camera *gcam, u32 request_id,
341 unsigned int streams, unsigned int num_frames,
342 size_t settings_size, const void *settings)
344 struct gb_camera_capture_request *req;
348 if (settings_size > GB_CAMERA_MAX_SETTINGS_SIZE)
351 req_size = sizeof(*req) + settings_size;
352 req = kmalloc(req_size, GFP_KERNEL);
356 req->request_id = cpu_to_le32(request_id);
357 req->streams = streams;
359 req->num_frames = cpu_to_le16(num_frames);
360 memcpy(req->settings, settings, settings_size);
362 ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_CAPTURE,
363 req, req_size, NULL, 0);
370 static int gb_camera_flush(struct gb_camera *gcam, u32 *request_id)
372 struct gb_camera_flush_response resp;
375 ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_FLUSH, NULL, 0,
376 &resp, sizeof(resp));
381 *request_id = le32_to_cpu(resp.request_id);
386 static int gb_camera_event_recv(u8 type, struct gb_operation *op)
388 struct gb_camera *gcam = gb_connection_get_data(op->connection);
389 struct gb_camera_metadata_request *payload;
390 struct gb_message *request;
392 if (type != GB_CAMERA_TYPE_METADATA) {
393 gcam_err(gcam, "Unsupported unsolicited event: %u\n", type);
397 request = op->request;
399 if (request->payload_size < sizeof(*payload)) {
400 gcam_err(gcam, "Wrong event size received (%zu < %zu)\n",
401 request->payload_size, sizeof(*payload));
405 payload = request->payload;
407 gcam_dbg(gcam, "received metadata for request %u, frame %u, stream %u\n",
408 payload->request_id, payload->frame_number, payload->stream);
413 /* -----------------------------------------------------------------------------
414 * Interface with HOST ara camera.
416 static unsigned int gb_camera_mbus_to_gb(enum v4l2_mbus_pixelcode mbus_code)
420 for (i = 0; i < ARRAY_SIZE(mbus_to_gbus_format); i++) {
421 if (mbus_to_gbus_format[i].mbus_code == mbus_code)
422 return mbus_to_gbus_format[i].gb_format;
424 return mbus_to_gbus_format[0].gb_format;
427 static enum v4l2_mbus_pixelcode gb_camera_gb_to_mbus(u16 gb_fmt)
431 for (i = 0; i < ARRAY_SIZE(mbus_to_gbus_format); i++) {
432 if (mbus_to_gbus_format[i].gb_format == gb_fmt)
433 return mbus_to_gbus_format[i].mbus_code;
435 return mbus_to_gbus_format[0].mbus_code;
438 static ssize_t gb_camera_op_capabilities(void *priv, char *data, size_t len)
440 struct gb_camera *gcam = priv;
441 size_t capabilities_len = len;
444 ret = gb_camera_capabilities(gcam, data, &capabilities_len);
448 return capabilities_len;
451 static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams,
452 unsigned int *flags, struct gb_camera_stream *streams,
453 struct gb_camera_csi_params *csi_params)
455 struct gb_camera *gcam = priv;
456 struct gb_camera_stream_config *gb_streams;
457 unsigned int gb_flags = 0;
458 unsigned int gb_nstreams = *nstreams;
462 if (gb_nstreams > GB_CAMERA_MAX_STREAMS)
465 gb_streams = kzalloc(gb_nstreams * sizeof(*gb_streams), GFP_KERNEL);
469 for (i = 0; i < gb_nstreams; i++) {
470 gb_streams[i].width = streams[i].width;
471 gb_streams[i].height = streams[i].height;
472 gb_streams[i].format =
473 gb_camera_mbus_to_gb(streams[i].pixel_code);
476 if (*flags & GB_CAMERA_IN_FLAG_TEST)
477 gb_flags |= GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY;
479 ret = gb_camera_configure_streams(gcam, &gb_nstreams,
480 &gb_flags, gb_streams, csi_params);
483 if (gb_nstreams > *nstreams) {
489 if (gb_flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED)
490 *flags |= GB_CAMERA_OUT_FLAG_ADJUSTED;
492 for (i = 0; i < gb_nstreams; i++) {
493 streams[i].width = gb_streams[i].width;
494 streams[i].height = gb_streams[i].height;
495 streams[i].vc = gb_streams[i].vc;
496 streams[i].dt[0] = gb_streams[i].dt[0];
497 streams[i].dt[1] = gb_streams[i].dt[1];
498 streams[i].max_size = gb_streams[i].max_size;
499 streams[i].pixel_code =
500 gb_camera_gb_to_mbus(gb_streams[i].format);
502 *nstreams = gb_nstreams;
509 static int gb_camera_op_capture(void *priv, u32 request_id,
510 unsigned int streams, unsigned int num_frames,
511 size_t settings_size, const void *settings)
513 struct gb_camera *gcam = priv;
515 return gb_camera_capture(gcam, request_id, streams, num_frames,
516 settings_size, settings);
519 static int gb_camera_op_flush(void *priv, u32 *request_id)
521 struct gb_camera *gcam = priv;
523 return gb_camera_flush(gcam, request_id);
526 static const struct gb_camera_ops gb_cam_ops = {
527 .capabilities = gb_camera_op_capabilities,
528 .configure_streams = gb_camera_op_configure_streams,
529 .capture = gb_camera_op_capture,
530 .flush = gb_camera_op_flush,
533 static int gb_camera_register_intf_ops(struct gb_camera *gcam)
535 gcam->module.priv = gcam;
536 gcam->module.ops = &gb_cam_ops;
537 return gb_camera_register(&gcam->module);
540 static int gb_camera_unregister_intf_ops(struct gb_camera *gcam)
542 return gb_camera_unregister(&gcam->module);
545 /* -----------------------------------------------------------------------------
549 static ssize_t gb_camera_debugfs_capabilities(struct gb_camera *gcam,
550 char *buf, size_t len)
552 struct gb_camera_debugfs_buffer *buffer =
553 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES];
559 caps = kmalloc(size, GFP_KERNEL);
563 ret = gb_camera_capabilities(gcam, caps, &size);
568 * hex_dump_to_buffer() doesn't return the number of bytes dumped prior
569 * to v4.0, we need our own implementation :-(
573 for (i = 0; i < size; i += 16) {
574 unsigned int nbytes = min_t(unsigned int, size - i, 16);
576 buffer->length += sprintf(buffer->data + buffer->length,
577 "%*ph\n", nbytes, caps + i);
585 static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam,
586 char *buf, size_t len)
588 struct gb_camera_debugfs_buffer *buffer =
589 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_STREAMS];
590 struct gb_camera_stream_config *streams;
591 unsigned int nstreams;
597 /* Retrieve number of streams to configure */
598 token = strsep(&buf, ";");
602 ret = kstrtouint(token, 10, &nstreams);
606 if (nstreams > GB_CAMERA_MAX_STREAMS)
609 token = strsep(&buf, ";");
613 ret = kstrtouint(token, 10, &flags);
617 /* For each stream to configure parse width, height and format */
618 streams = kzalloc(nstreams * sizeof(*streams), GFP_KERNEL);
622 for (i = 0; i < nstreams; ++i) {
623 struct gb_camera_stream_config *stream = &streams[i];
626 token = strsep(&buf, ";");
631 ret = kstrtouint(token, 10, &stream->width);
636 token = strsep(&buf, ";");
640 ret = kstrtouint(token, 10, &stream->height);
644 /* Image format code */
645 token = strsep(&buf, ";");
649 ret = kstrtouint(token, 16, &stream->format);
654 ret = gb_camera_configure_streams(gcam, &nstreams, &flags, streams,
659 buffer->length = sprintf(buffer->data, "%u;%u;", nstreams, flags);
661 for (i = 0; i < nstreams; ++i) {
662 struct gb_camera_stream_config *stream = &streams[i];
664 buffer->length += sprintf(buffer->data + buffer->length,
665 "%u;%u;%u;%u;%u;%u;%u;",
666 stream->width, stream->height,
667 stream->format, stream->vc,
668 stream->dt[0], stream->dt[1],
679 static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam,
680 char *buf, size_t len)
682 unsigned int request_id;
683 unsigned int streams_mask;
684 unsigned int num_frames;
689 token = strsep(&buf, ";");
692 ret = kstrtouint(token, 10, &request_id);
697 token = strsep(&buf, ";");
700 ret = kstrtouint(token, 16, &streams_mask);
704 /* number of frames */
705 token = strsep(&buf, ";");
708 ret = kstrtouint(token, 10, &num_frames);
712 ret = gb_camera_capture(gcam, request_id, streams_mask, num_frames, 0,
720 static ssize_t gb_camera_debugfs_flush(struct gb_camera *gcam,
721 char *buf, size_t len)
723 struct gb_camera_debugfs_buffer *buffer =
724 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_FLUSH];
728 ret = gb_camera_flush(gcam, &req_id);
732 buffer->length = sprintf(buffer->data, "%u", req_id);
737 struct gb_camera_debugfs_entry {
741 ssize_t (*execute)(struct gb_camera *gcam, char *buf, size_t len);
744 static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = {
746 .name = "capabilities",
747 .mask = S_IFREG | S_IRUGO,
748 .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,
749 .execute = gb_camera_debugfs_capabilities,
751 .name = "configure_streams",
752 .mask = S_IFREG | S_IRUGO | S_IWUGO,
753 .buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS,
754 .execute = gb_camera_debugfs_configure_streams,
757 .mask = S_IFREG | S_IRUGO | S_IWUGO,
758 .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,
759 .execute = gb_camera_debugfs_capture,
762 .mask = S_IFREG | S_IRUGO | S_IWUGO,
763 .buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH,
764 .execute = gb_camera_debugfs_flush,
768 static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf,
769 size_t len, loff_t *offset)
771 const struct gb_camera_debugfs_entry *op = file->private_data;
772 struct gb_camera *gcam = file->f_inode->i_private;
773 struct gb_camera_debugfs_buffer *buffer;
776 /* For read-only entries the operation is triggered by a read. */
777 if (!(op->mask & S_IWUGO)) {
778 ret = op->execute(gcam, NULL, 0);
783 buffer = &gcam->debugfs.buffers[op->buffer];
785 return simple_read_from_buffer(buf, len, offset, buffer->data,
789 static ssize_t gb_camera_debugfs_write(struct file *file,
790 const char __user *buf, size_t len,
793 const struct gb_camera_debugfs_entry *op = file->private_data;
794 struct gb_camera *gcam = file->f_inode->i_private;
801 kbuf = kmalloc(len + 1, GFP_KERNEL);
805 if (copy_from_user(kbuf, buf, len)) {
812 ret = op->execute(gcam, kbuf, len);
819 static int gb_camera_debugfs_open(struct inode *inode, struct file *file)
823 for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
824 const struct gb_camera_debugfs_entry *entry =
825 &gb_camera_debugfs_entries[i];
827 if (!strcmp(file->f_path.dentry->d_iname, entry->name)) {
828 file->private_data = (void *)entry;
836 static const struct file_operations gb_camera_debugfs_ops = {
837 .open = gb_camera_debugfs_open,
838 .read = gb_camera_debugfs_read,
839 .write = gb_camera_debugfs_write,
842 static int gb_camera_debugfs_init(struct gb_camera *gcam)
844 struct gb_connection *connection = gcam->connection;
849 * Create root debugfs entry and a file entry for each camera operation.
851 snprintf(dirname, 27, "camera-%u.%u", connection->intf->interface_id,
852 connection->bundle->id);
854 gcam->debugfs.root = debugfs_create_dir(dirname, gb_debugfs_get());
855 if (IS_ERR(gcam->debugfs.root)) {
856 gcam_err(gcam, "debugfs root create failed (%ld)\n",
857 PTR_ERR(gcam->debugfs.root));
858 return PTR_ERR(gcam->debugfs.root);
861 gcam->debugfs.buffers = vmalloc(sizeof(*gcam->debugfs.buffers) *
862 GB_CAMERA_DEBUGFS_BUFFER_MAX);
863 if (!gcam->debugfs.buffers)
866 for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
867 const struct gb_camera_debugfs_entry *entry =
868 &gb_camera_debugfs_entries[i];
869 struct dentry *dentry;
871 gcam->debugfs.buffers[i].length = 0;
873 dentry = debugfs_create_file(entry->name, entry->mask,
874 gcam->debugfs.root, gcam,
875 &gb_camera_debugfs_ops);
876 if (IS_ERR(dentry)) {
878 "debugfs operation %s create failed (%ld)\n",
879 entry->name, PTR_ERR(gcam->debugfs.root));
880 return PTR_ERR(dentry);
887 static void gb_camera_debugfs_cleanup(struct gb_camera *gcam)
889 if (gcam->debugfs.root)
890 debugfs_remove_recursive(gcam->debugfs.root);
892 vfree(gcam->debugfs.buffers);
895 /* -----------------------------------------------------------------------------
899 static void gb_camera_cleanup(struct gb_camera *gcam)
901 gb_camera_debugfs_cleanup(gcam);
903 if (gcam->data_connection) {
904 gb_connection_disable(gcam->data_connection);
905 gb_connection_destroy(gcam->data_connection);
911 static int gb_camera_connection_init(struct gb_connection *connection)
913 struct gb_connection *data;
914 struct gb_camera *gcam;
915 unsigned long data_flags;
918 gcam = kzalloc(sizeof(*gcam), GFP_KERNEL);
922 gcam->connection = connection;
923 gb_connection_set_data(connection, gcam);
926 * Create the data connection between camera module CDSI0 and APB CDS1.
927 * The CPort IDs are hardcoded by the ES2 bridges.
929 data_flags = GB_CONNECTION_FLAG_NO_FLOWCTRL | GB_CONNECTION_FLAG_CDSI1;
931 data = gb_connection_create_offloaded(connection->bundle,
938 gcam->data_connection = data;
940 ret = gb_connection_enable(data);
944 ret = gb_camera_debugfs_init(gcam);
948 ret = gb_camera_register_intf_ops(gcam);
955 gb_camera_cleanup(gcam);
959 static void gb_camera_connection_exit(struct gb_connection *connection)
961 struct gb_camera *gcam = gb_connection_get_data(connection);
963 gb_camera_unregister_intf_ops(gcam);
965 gb_camera_cleanup(gcam);
968 static struct gb_protocol camera_protocol = {
970 .id = GREYBUS_PROTOCOL_CAMERA_MGMT,
971 .major = GB_CAMERA_VERSION_MAJOR,
972 .minor = GB_CAMERA_VERSION_MINOR,
973 .connection_init = gb_camera_connection_init,
974 .connection_exit = gb_camera_connection_exit,
975 .request_recv = gb_camera_event_recv,
978 gb_protocol_driver(&camera_protocol);
980 MODULE_LICENSE("GPL v2");