]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/greybus/camera.c
783a435bbae6b12ce7a589b4d4da39a3c2698bbb
[karo-tx-linux.git] / drivers / staging / greybus / camera.c
1 /*
2  * Greybus Camera protocol driver.
3  *
4  * Copyright 2015 Google Inc.
5  * Copyright 2015 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
10 #include <linux/debugfs.h>
11 #include <linux/fs.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>
18
19 #include "greybus.h"
20 #include "greybus_protocols.h"
21
22 enum gb_camera_debugs_buffer_id {
23         GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,
24         GB_CAMERA_DEBUGFS_BUFFER_STREAMS,
25         GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,
26         GB_CAMERA_DEBUGFS_BUFFER_FLUSH,
27         GB_CAMERA_DEBUGFS_BUFFER_MAX,
28 };
29
30 struct gb_camera_debugfs_buffer {
31         char data[PAGE_SIZE];
32         size_t length;
33 };
34
35 /**
36  * struct gb_camera - A Greybus Camera Device
37  * @connection: the greybus connection for camera control
38  * @data_connected: whether the data connection has been established
39  * @debugfs: debugfs entries for camera protocol operations testing
40  */
41 struct gb_camera {
42         struct gb_connection *connection;
43         bool data_connected;
44
45         struct {
46                 struct dentry *root;
47                 struct gb_camera_debugfs_buffer *buffers;
48         } debugfs;
49 };
50
51 struct gb_camera_stream_config {
52         unsigned int width;
53         unsigned int height;
54         unsigned int format;
55         unsigned int vc;
56         unsigned int dt[2];
57         unsigned int max_size;
58 };
59
60 #define ES2_APB_CDSI0_CPORT             16
61 #define ES2_APB_CDSI1_CPORT             17
62
63 #define GB_CAMERA_MAX_SETTINGS_SIZE     8192
64
65 #define gcam_dbg(gcam, format...) \
66         dev_dbg(&gcam->connection->bundle->dev, format)
67 #define gcam_info(gcam, format...) \
68         dev_info(&gcam->connection->bundle->dev, format)
69 #define gcam_err(gcam, format...) \
70         dev_err(&gcam->connection->bundle->dev, format)
71
72 /* -----------------------------------------------------------------------------
73  * Camera Protocol Operations
74  */
75
76 struct ap_csi_config_request {
77         __u8 csi_id;
78         __u8 clock_mode;
79         __u8 num_lanes;
80         __u8 padding;
81         __le32 bus_freq;
82 } __packed;
83
84 static int gb_camera_configure_streams(struct gb_camera *gcam,
85                                        unsigned int nstreams,
86                                        unsigned int flags,
87                                        struct gb_camera_stream_config *streams)
88 {
89         struct gb_camera_configure_streams_request *req;
90         struct gb_camera_configure_streams_response *resp;
91         struct ap_csi_config_request csi_cfg;
92         unsigned int i;
93         size_t req_size;
94         size_t resp_size;
95         int ret;
96
97         if (nstreams > GB_CAMERA_MAX_STREAMS)
98                 return -EINVAL;
99
100         req_size = sizeof(*req) + nstreams * sizeof(req->config[0]);
101         resp_size = sizeof(*resp) + nstreams * sizeof(resp->config[0]);
102
103         req = kmalloc(req_size, GFP_KERNEL);
104         resp = kmalloc(resp_size, GFP_KERNEL);
105         if (!req || !resp) {
106                 ret = -ENOMEM;
107                 goto done;
108         }
109
110         req->num_streams = nstreams;
111         req->flags = flags;
112         req->padding = 0;
113
114         for (i = 0; i < nstreams; ++i) {
115                 struct gb_camera_stream_config_request *cfg = &req->config[i];
116
117                 cfg->width = cpu_to_le16(streams[i].width);
118                 cfg->height = cpu_to_le16(streams[i].height);
119                 cfg->format = cpu_to_le16(streams[i].format);
120                 cfg->padding = 0;
121         }
122
123         ret = gb_operation_sync(gcam->connection,
124                                 GB_CAMERA_TYPE_CONFIGURE_STREAMS,
125                                 req, req_size, resp, resp_size);
126         if (ret < 0)
127                 goto done;
128
129         if (resp->num_streams > nstreams) {
130                 gcam_dbg(gcam, "got #streams %u > request %u\n",
131                          resp->num_streams, nstreams);
132                 ret = -EIO;
133                 goto done;
134         }
135
136         if (resp->padding != 0) {
137                 gcam_dbg(gcam, "response padding != 0");
138                 ret = -EIO;
139                 goto done;
140         }
141
142         for (i = 0; i < nstreams; ++i) {
143                 struct gb_camera_stream_config_response *cfg = &resp->config[i];
144
145                 streams[i].width = le16_to_cpu(cfg->width);
146                 streams[i].height = le16_to_cpu(cfg->height);
147                 streams[i].format = le16_to_cpu(cfg->format);
148                 streams[i].vc = cfg->virtual_channel;
149                 streams[i].dt[0] = cfg->data_type[0];
150                 streams[i].dt[1] = cfg->data_type[1];
151                 streams[i].max_size = le32_to_cpu(cfg->max_size);
152
153                 if (cfg->padding[0] || cfg->padding[1] || cfg->padding[2]) {
154                         gcam_dbg(gcam, "stream #%u padding != 0", i);
155                         ret = -EIO;
156                         goto done;
157                 }
158         }
159
160         memset(&csi_cfg, 0, sizeof(csi_cfg));
161
162         /* Configure the CSI transmitter. Hardcode the parameters for now. */
163         if (nstreams && !(resp->flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED)) {
164                 csi_cfg.csi_id = 1;
165                 csi_cfg.clock_mode = 0;
166                 csi_cfg.num_lanes = 4;
167                 csi_cfg.bus_freq = cpu_to_le32(960000000);
168                 ret = gb_hd_output(gcam->connection->hd, &csi_cfg,
169                                    sizeof(csi_cfg),
170                                    GB_APB_REQUEST_CSI_TX_CONTROL, false);
171         } else if (nstreams == 0) {
172                 csi_cfg.csi_id = 1;
173                 ret = gb_hd_output(gcam->connection->hd, &csi_cfg,
174                                    sizeof(csi_cfg),
175                                    GB_APB_REQUEST_CSI_TX_CONTROL, false);
176         }
177
178         if (ret < 0)
179                 gcam_err(gcam, "failed to %s the CSI transmitter\n",
180                          nstreams ? "start" : "stop");
181
182         ret = resp->num_streams;
183
184 done:
185         kfree(req);
186         kfree(resp);
187         return ret;
188 }
189
190 static int gb_camera_capture(struct gb_camera *gcam, u32 request_id,
191                              unsigned int streams, unsigned int num_frames,
192                              size_t settings_size, const void *settings)
193 {
194         struct gb_camera_capture_request *req;
195         size_t req_size;
196         int ret;
197
198         if (settings_size > GB_CAMERA_MAX_SETTINGS_SIZE)
199                 return -EINVAL;
200
201         req_size = sizeof(*req) + settings_size;
202         req = kmalloc(req_size, GFP_KERNEL);
203         if (!req)
204                 return -ENOMEM;
205
206         req->request_id = cpu_to_le32(request_id);
207         req->streams = streams;
208         req->padding = 0;
209         req->num_frames = cpu_to_le16(num_frames);
210         memcpy(req->settings, settings, settings_size);
211
212         ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_CAPTURE,
213                                  req, req_size, NULL, 0);
214
215         kfree(req);
216
217         return ret;
218 }
219
220 static int gb_camera_flush(struct gb_camera *gcam, u32 *request_id)
221 {
222         struct gb_camera_flush_response resp;
223         int ret;
224
225         ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_FLUSH, NULL, 0,
226                                 &resp, sizeof(resp));
227         if (ret < 0)
228                 return ret;
229
230         if (request_id)
231                 *request_id = le32_to_cpu(resp.request_id);
232
233         return 0;
234 }
235
236 static int gb_camera_event_recv(u8 type, struct gb_operation *op)
237 {
238         struct gb_camera *gcam = op->connection->private;
239         struct gb_camera_metadata_request *payload;
240         struct gb_message *request;
241
242         if (type != GB_CAMERA_TYPE_METADATA) {
243                 gcam_err(gcam, "Unsupported unsolicited event: %u\n", type);
244                 return -EINVAL;
245         }
246
247         request = op->request;
248
249         if (request->payload_size < sizeof(*payload)) {
250                 gcam_err(gcam, "Wrong event size received (%zu < %zu)\n",
251                          request->payload_size, sizeof(*payload));
252                 return -EINVAL;
253         }
254
255         payload = request->payload;
256
257         gcam_dbg(gcam, "received metadata for request %u, frame %u, stream %u\n",
258                  payload->request_id, payload->frame_number, payload->stream);
259
260         return 0;
261 }
262
263 /* -----------------------------------------------------------------------------
264  * DebugFS
265  */
266 static ssize_t gb_camera_debugfs_capabilities(struct gb_camera *gcam,
267                 char *buf, size_t len)
268 {
269         return len;
270 }
271
272 static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam,
273                 char *buf, size_t len)
274 {
275         struct gb_camera_debugfs_buffer *buffer =
276                 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_STREAMS];
277         struct gb_camera_stream_config *streams;
278         unsigned int nstreams;
279         unsigned int flags;
280         unsigned int i;
281         char *token;
282         int ret;
283
284         /* Retrieve number of streams to configure */
285         token = strsep(&buf, ";");
286         if (token == NULL)
287                 return -EINVAL;
288
289         ret = kstrtouint(token, 10, &nstreams);
290         if (ret < 0)
291                 return ret;
292
293         if (nstreams > GB_CAMERA_MAX_STREAMS)
294                 return -EINVAL;
295
296         token = strsep(&buf, ";");
297         if (token == NULL)
298                 return -EINVAL;
299
300         ret = kstrtouint(token, 10, &flags);
301         if (ret < 0)
302                 return ret;
303
304         /* For each stream to configure parse width, height and format */
305         streams = kzalloc(nstreams * sizeof(*streams), GFP_KERNEL);
306         if (!streams)
307                 return -ENOMEM;
308
309         for (i = 0; i < nstreams; ++i) {
310                 struct gb_camera_stream_config *stream = &streams[i];
311
312                 /* width */
313                 token = strsep(&buf, ";");
314                 if (token == NULL) {
315                         ret = -EINVAL;
316                         goto done;
317                 }
318                 ret = kstrtouint(token, 10, &stream->width);
319                 if (ret < 0)
320                         goto done;
321
322                 /* height */
323                 token = strsep(&buf, ";");
324                 if (token == NULL)
325                         goto done;
326
327                 ret = kstrtouint(token, 10, &stream->height);
328                 if (ret < 0)
329                         goto done;
330
331                 /* Image format code */
332                 token = strsep(&buf, ";");
333                 if (token == NULL)
334                         goto done;
335
336                 ret = kstrtouint(token, 16, &stream->format);
337                 if (ret < 0)
338                         goto done;
339         }
340
341         ret = gb_camera_configure_streams(gcam, nstreams, flags, streams);
342         if (ret < 0)
343                 goto done;
344
345         nstreams = ret;
346         buffer->length = sprintf(buffer->data, "%u;", nstreams);
347
348         for (i = 0; i < nstreams; ++i) {
349                 struct gb_camera_stream_config *stream = &streams[i];
350
351                 buffer->length += sprintf(buffer->data + buffer->length,
352                                           "%u;%u;%u;%u;%u;%u;%u;",
353                                           stream->width, stream->height,
354                                           stream->format, stream->vc,
355                                           stream->dt[0], stream->dt[1],
356                                           stream->max_size);
357         }
358
359         ret = len;
360
361 done:
362         kfree(streams);
363         return ret;
364 };
365
366 static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam,
367                 char *buf, size_t len)
368 {
369         unsigned int request_id;
370         unsigned int streams_mask;
371         unsigned int num_frames;
372         char *token;
373         int ret;
374
375         /* Request id */
376         token = strsep(&buf, ";");
377         if (token == NULL)
378                 return -EINVAL;
379         ret = kstrtouint(token, 10, &request_id);
380         if (ret < 0)
381                 return ret;
382
383         /* Stream mask */
384         token = strsep(&buf, ";");
385         if (token == NULL)
386                 return -EINVAL;
387         ret = kstrtouint(token, 16, &streams_mask);
388         if (ret < 0)
389                 return ret;
390
391         /* number of frames */
392         token = strsep(&buf, ";");
393         if (token == NULL)
394                 return -EINVAL;
395         ret = kstrtouint(token, 10, &num_frames);
396         if (ret < 0)
397                 return ret;
398
399         ret = gb_camera_capture(gcam, request_id, streams_mask, num_frames, 0,
400                                 NULL);
401         if (ret < 0)
402                 return ret;
403
404         return len;
405 }
406
407 static ssize_t gb_camera_debugfs_flush(struct gb_camera *gcam,
408                 char *buf, size_t len)
409 {
410         struct gb_camera_debugfs_buffer *buffer =
411                 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_FLUSH];
412         unsigned int req_id;
413         int ret;
414
415         ret = gb_camera_flush(gcam, &req_id);
416         if (ret < 0)
417                 return ret;
418
419         buffer->length = sprintf(buffer->data, "%u", req_id);
420
421         return len;
422 }
423
424 struct gb_camera_debugfs_entry {
425         const char *name;
426         unsigned int mask;
427         unsigned int buffer;
428         ssize_t (*execute)(struct gb_camera *gcam, char *buf, size_t len);
429 };
430
431 static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = {
432         {
433                 .name = "capabilities",
434                 .mask = S_IFREG | S_IRUGO,
435                 .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,
436                 .execute = gb_camera_debugfs_capabilities,
437         }, {
438                 .name = "configure_streams",
439                 .mask = S_IFREG | S_IRUGO | S_IWUGO,
440                 .buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS,
441                 .execute = gb_camera_debugfs_configure_streams,
442         }, {
443                 .name = "capture",
444                 .mask = S_IFREG | S_IRUGO | S_IWUGO,
445                 .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,
446                 .execute = gb_camera_debugfs_capture,
447         }, {
448                 .name = "flush",
449                 .mask = S_IFREG | S_IRUGO | S_IWUGO,
450                 .buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH,
451                 .execute = gb_camera_debugfs_flush,
452         },
453 };
454
455 static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf,
456                                       size_t len, loff_t *offset)
457 {
458         const struct gb_camera_debugfs_entry *op = file->private_data;
459         struct gb_camera *gcam = file->f_inode->i_private;
460         struct gb_camera_debugfs_buffer *buffer;
461         ssize_t ret;
462
463         /* For read-only entries the operation is triggered by a read. */
464         if (!(op->mask & S_IWUGO)) {
465                 ret = op->execute(gcam, NULL, 0);
466                 if (ret < 0)
467                         return ret;
468         }
469
470         buffer = &gcam->debugfs.buffers[op->buffer];
471
472         return simple_read_from_buffer(buf, len, offset, buffer->data,
473                                        buffer->length);
474 }
475
476 static ssize_t gb_camera_debugfs_write(struct file *file,
477                                        const char __user *buf, size_t len,
478                                        loff_t *offset)
479 {
480         const struct gb_camera_debugfs_entry *op = file->private_data;
481         struct gb_camera *gcam = file->f_inode->i_private;
482         ssize_t ret;
483         char *kbuf;
484
485         if (len > 1024)
486                return -EINVAL;
487
488         kbuf = kmalloc(len + 1, GFP_KERNEL);
489         if (kbuf == NULL)
490                 return -ENOMEM;
491
492         if (copy_from_user(kbuf, buf, len)) {
493                 ret = -EFAULT;
494                 goto done;
495         }
496
497         kbuf[len] = '\0';
498
499         ret = op->execute(gcam, kbuf, len);
500
501 done:
502         kfree(kbuf);
503         return ret;
504 }
505
506 static int gb_camera_debugfs_open(struct inode *inode, struct file *file)
507 {
508         unsigned int i;
509
510         for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
511                 const struct gb_camera_debugfs_entry *entry =
512                         &gb_camera_debugfs_entries[i];
513
514                 if (!strcmp(file->f_path.dentry->d_iname, entry->name)) {
515                         file->private_data = (void *)entry;
516                         break;
517                 }
518         }
519
520         return 0;
521 }
522
523 static const struct file_operations gb_camera_debugfs_ops = {
524         .open = gb_camera_debugfs_open,
525         .read = gb_camera_debugfs_read,
526         .write = gb_camera_debugfs_write,
527 };
528
529 static int gb_camera_debugfs_init(struct gb_camera *gcam)
530 {
531         struct gb_connection *connection = gcam->connection;
532         char dirname[27];
533         unsigned int i;
534
535         /*
536          * Create root debugfs entry and a file entry for each camera operation.
537          */
538         snprintf(dirname, 27, "camera-%u.%u", connection->intf->interface_id,
539                  connection->bundle->id);
540
541         gcam->debugfs.root = debugfs_create_dir(dirname, gb_debugfs_get());
542         if (IS_ERR(gcam->debugfs.root)) {
543                 gcam_err(gcam, "debugfs root create failed (%ld)\n",
544                          PTR_ERR(gcam->debugfs.root));
545                 return PTR_ERR(gcam->debugfs.root);
546         }
547
548         gcam->debugfs.buffers = vmalloc(sizeof(*gcam->debugfs.buffers) *
549                                         GB_CAMERA_DEBUGFS_BUFFER_MAX);
550         if (!gcam->debugfs.buffers)
551                 return -ENOMEM;
552
553         for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
554                 const struct gb_camera_debugfs_entry *entry =
555                         &gb_camera_debugfs_entries[i];
556                 struct dentry *dentry;
557
558                 gcam->debugfs.buffers[i].length = 0;
559
560                 dentry = debugfs_create_file(entry->name, entry->mask,
561                                              gcam->debugfs.root, gcam,
562                                              &gb_camera_debugfs_ops);
563                 if (IS_ERR(dentry)) {
564                         gcam_err(gcam,
565                                  "debugfs operation %s create failed (%ld)\n",
566                                  entry->name, PTR_ERR(gcam->debugfs.root));
567                         return PTR_ERR(dentry);
568                 }
569         }
570
571         return 0;
572 }
573
574 static void gb_camera_debugfs_cleanup(struct gb_camera *gcam)
575 {
576         if (gcam->debugfs.root)
577                 debugfs_remove_recursive(gcam->debugfs.root);
578
579         vfree(gcam->debugfs.buffers);
580 }
581
582 /* -----------------------------------------------------------------------------
583  * Init & Cleanup
584  */
585
586 static void gb_camera_cleanup(struct gb_camera *gcam)
587 {
588         gb_camera_debugfs_cleanup(gcam);
589
590         if (gcam->data_connected) {
591                 struct gb_interface *intf = gcam->connection->intf;
592                 struct gb_svc *svc = gcam->connection->hd->svc;
593
594                 gb_svc_connection_destroy(svc, intf->interface_id,
595                                           ES2_APB_CDSI0_CPORT, svc->ap_intf_id,
596                                           ES2_APB_CDSI1_CPORT);
597         }
598
599         kfree(gcam);
600 }
601
602 static int gb_camera_connection_init(struct gb_connection *connection)
603 {
604         struct gb_svc *svc = connection->hd->svc;
605         struct gb_camera *gcam;
606         int ret;
607
608         gcam = kzalloc(sizeof(*gcam), GFP_KERNEL);
609         if (!gcam)
610                 return -ENOMEM;
611
612         gcam->connection = connection;
613         connection->private = gcam;
614
615         /*
616          * Create the data connection between camera module CDSI0 and APB CDS1.
617          * The CPort IDs are hardcoded by the ES2 bridges.
618          */
619         ret = gb_svc_connection_create(svc, connection->intf->interface_id,
620                                        ES2_APB_CDSI0_CPORT, svc->ap_intf_id,
621                                        ES2_APB_CDSI1_CPORT, false);
622         if (ret < 0)
623                 goto error;
624
625         gcam->data_connected = true;
626
627         ret = gb_svc_intf_set_power_mode(svc, connection->intf->interface_id,
628                                          GB_SVC_UNIPRO_HS_SERIES_A,
629                                          GB_SVC_UNIPRO_FAST_MODE, 2, 2,
630                                          GB_SVC_UNIPRO_FAST_MODE, 2, 2,
631                                          GB_SVC_PWRM_RXTERMINATION |
632                                          GB_SVC_PWRM_TXTERMINATION, 0);
633         if (ret < 0)
634                 goto error;
635
636         ret = gb_svc_intf_set_power_mode(svc, svc->ap_intf_id,
637                                          GB_SVC_UNIPRO_HS_SERIES_A,
638                                          GB_SVC_UNIPRO_FAST_MODE, 2, 2,
639                                          GB_SVC_UNIPRO_FAST_MODE, 2, 2,
640                                          GB_SVC_PWRM_RXTERMINATION |
641                                          GB_SVC_PWRM_TXTERMINATION, 0);
642         if (ret < 0)
643                 goto error;
644
645         ret = gb_camera_debugfs_init(gcam);
646         if (ret < 0)
647                 goto error;
648
649         return 0;
650
651 error:
652         gb_camera_cleanup(gcam);
653         return ret;
654 }
655
656 static void gb_camera_connection_exit(struct gb_connection *connection)
657 {
658         struct gb_camera *gcam = connection->private;
659
660         gb_camera_cleanup(gcam);
661 }
662
663 static struct gb_protocol camera_protocol = {
664         .name                   = "camera",
665         .id                     = GREYBUS_PROTOCOL_CAMERA_MGMT,
666         .major                  = GB_CAMERA_VERSION_MAJOR,
667         .minor                  = GB_CAMERA_VERSION_MINOR,
668         .connection_init        = gb_camera_connection_init,
669         .connection_exit        = gb_camera_connection_exit,
670         .request_recv           = gb_camera_event_recv,
671 };
672
673 gb_protocol_driver(&camera_protocol);
674
675 MODULE_LICENSE("GPL v2");