1379 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Greybus Camera protocol driver.4 *5 * Copyright 2015 Google Inc.6 * Copyright 2015 Linaro Ltd.7 */8 9#include <linux/debugfs.h>10#include <linux/fs.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/slab.h>14#include <linux/string.h>15#include <linux/uaccess.h>16#include <linux/vmalloc.h>17#include <linux/greybus.h>18 19#include "gb-camera.h"20#include "greybus_protocols.h"21 22enum 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 30struct gb_camera_debugfs_buffer {31 char data[PAGE_SIZE];32 size_t length;33};34 35enum gb_camera_state {36 GB_CAMERA_STATE_UNCONFIGURED,37 GB_CAMERA_STATE_CONFIGURED,38};39 40/**41 * struct gb_camera - A Greybus Camera Device42 * @connection: the greybus connection for camera management43 * @data_connection: the greybus connection for camera data44 * @data_cport_id: the data CPort ID on the module side45 * @mutex: protects the connection and state fields46 * @state: the current module state47 * @debugfs: debugfs entries for camera protocol operations testing48 * @module: Greybus camera module registered to HOST processor.49 */50struct gb_camera {51 struct gb_bundle *bundle;52 struct gb_connection *connection;53 struct gb_connection *data_connection;54 u16 data_cport_id;55 56 struct mutex mutex;57 enum gb_camera_state state;58 59 struct {60 struct dentry *root;61 struct gb_camera_debugfs_buffer *buffers;62 } debugfs;63 64 struct gb_camera_module module;65};66 67struct gb_camera_stream_config {68 unsigned int width;69 unsigned int height;70 unsigned int format;71 unsigned int vc;72 unsigned int dt[2];73 unsigned int max_size;74};75 76struct gb_camera_fmt_info {77 enum v4l2_mbus_pixelcode mbus_code;78 unsigned int gb_format;79 unsigned int bpp;80};81 82/* GB format to media code map */83static const struct gb_camera_fmt_info gb_fmt_info[] = {84 {85 .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16,86 .gb_format = 0x01,87 .bpp = 16,88 },89 {90 .mbus_code = V4L2_MBUS_FMT_NV12_1x8,91 .gb_format = 0x12,92 .bpp = 12,93 },94 {95 .mbus_code = V4L2_MBUS_FMT_NV21_1x8,96 .gb_format = 0x13,97 .bpp = 12,98 },99 {100 .mbus_code = V4L2_MBUS_FMT_YU12_1x8,101 .gb_format = 0x16,102 .bpp = 12,103 },104 {105 .mbus_code = V4L2_MBUS_FMT_YV12_1x8,106 .gb_format = 0x17,107 .bpp = 12,108 },109 {110 .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,111 .gb_format = 0x40,112 .bpp = 0,113 },114 {115 .mbus_code = V4L2_MBUS_FMT_GB_CAM_METADATA_1X8,116 .gb_format = 0x41,117 .bpp = 0,118 },119 {120 .mbus_code = V4L2_MBUS_FMT_GB_CAM_DEBUG_DATA_1X8,121 .gb_format = 0x42,122 .bpp = 0,123 },124 {125 .mbus_code = V4L2_MBUS_FMT_SBGGR10_1X10,126 .gb_format = 0x80,127 .bpp = 10,128 },129 {130 .mbus_code = V4L2_MBUS_FMT_SGBRG10_1X10,131 .gb_format = 0x81,132 .bpp = 10,133 },134 {135 .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10,136 .gb_format = 0x82,137 .bpp = 10,138 },139 {140 .mbus_code = V4L2_MBUS_FMT_SRGGB10_1X10,141 .gb_format = 0x83,142 .bpp = 10,143 },144 {145 .mbus_code = V4L2_MBUS_FMT_SBGGR12_1X12,146 .gb_format = 0x84,147 .bpp = 12,148 },149 {150 .mbus_code = V4L2_MBUS_FMT_SGBRG12_1X12,151 .gb_format = 0x85,152 .bpp = 12,153 },154 {155 .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12,156 .gb_format = 0x86,157 .bpp = 12,158 },159 {160 .mbus_code = V4L2_MBUS_FMT_SRGGB12_1X12,161 .gb_format = 0x87,162 .bpp = 12,163 },164};165 166static const struct gb_camera_fmt_info *gb_camera_get_format_info(u16 gb_fmt)167{168 unsigned int i;169 170 for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) {171 if (gb_fmt_info[i].gb_format == gb_fmt)172 return &gb_fmt_info[i];173 }174 175 return NULL;176}177 178#define ES2_APB_CDSI0_CPORT 16179#define ES2_APB_CDSI1_CPORT 17180 181#define GB_CAMERA_MAX_SETTINGS_SIZE 8192182 183static int gb_camera_operation_sync_flags(struct gb_connection *connection,184 int type, unsigned int flags,185 void *request, size_t request_size,186 void *response, size_t *response_size)187{188 struct gb_operation *operation;189 int ret;190 191 operation = gb_operation_create_flags(connection, type, request_size,192 *response_size, flags,193 GFP_KERNEL);194 if (!operation)195 return -ENOMEM;196 197 if (request_size)198 memcpy(operation->request->payload, request, request_size);199 200 ret = gb_operation_request_send_sync(operation);201 if (ret) {202 dev_err(&connection->hd->dev,203 "%s: synchronous operation of type 0x%02x failed: %d\n",204 connection->name, type, ret);205 } else {206 *response_size = operation->response->payload_size;207 208 if (operation->response->payload_size)209 memcpy(response, operation->response->payload,210 operation->response->payload_size);211 }212 213 gb_operation_put(operation);214 215 return ret;216}217 218static int gb_camera_get_max_pkt_size(struct gb_camera *gcam,219 struct gb_camera_configure_streams_response *resp)220{221 unsigned int max_pkt_size = 0;222 unsigned int i;223 224 for (i = 0; i < resp->num_streams; i++) {225 struct gb_camera_stream_config_response *cfg = &resp->config[i];226 const struct gb_camera_fmt_info *fmt_info;227 unsigned int pkt_size;228 229 fmt_info = gb_camera_get_format_info(cfg->format);230 if (!fmt_info) {231 dev_err(&gcam->bundle->dev, "unsupported greybus image format: %d\n",232 cfg->format);233 return -EIO;234 }235 236 if (fmt_info->bpp == 0) {237 pkt_size = le32_to_cpu(cfg->max_pkt_size);238 239 if (pkt_size == 0) {240 dev_err(&gcam->bundle->dev,241 "Stream %u: invalid zero maximum packet size\n",242 i);243 return -EIO;244 }245 } else {246 pkt_size = le16_to_cpu(cfg->width) * fmt_info->bpp / 8;247 248 if (pkt_size != le32_to_cpu(cfg->max_pkt_size)) {249 dev_err(&gcam->bundle->dev,250 "Stream %u: maximum packet size mismatch (%u/%u)\n",251 i, pkt_size, cfg->max_pkt_size);252 return -EIO;253 }254 }255 256 max_pkt_size = max(pkt_size, max_pkt_size);257 }258 259 return max_pkt_size;260}261 262/*263 * Validate the stream configuration response verifying padding is correctly264 * set and the returned number of streams is supported265 */266static const int gb_camera_configure_streams_validate_response(struct gb_camera *gcam,267 struct gb_camera_configure_streams_response *resp,268 unsigned int nstreams)269{270 unsigned int i;271 272 /* Validate the returned response structure */273 if (resp->padding[0] || resp->padding[1]) {274 dev_err(&gcam->bundle->dev, "response padding != 0\n");275 return -EIO;276 }277 278 if (resp->num_streams > nstreams) {279 dev_err(&gcam->bundle->dev, "got #streams %u > request %u\n",280 resp->num_streams, nstreams);281 return -EIO;282 }283 284 for (i = 0; i < resp->num_streams; i++) {285 struct gb_camera_stream_config_response *cfg = &resp->config[i];286 287 if (cfg->padding) {288 dev_err(&gcam->bundle->dev, "stream #%u padding != 0\n", i);289 return -EIO;290 }291 }292 293 return 0;294}295 296/* -----------------------------------------------------------------------------297 * Hardware Configuration298 */299 300static int gb_camera_set_intf_power_mode(struct gb_camera *gcam, u8 intf_id,301 bool hs)302{303 struct gb_svc *svc = gcam->connection->hd->svc;304 int ret;305 306 if (hs)307 ret = gb_svc_intf_set_power_mode(svc, intf_id,308 GB_SVC_UNIPRO_HS_SERIES_A,309 GB_SVC_UNIPRO_FAST_MODE, 2, 2,310 GB_SVC_SMALL_AMPLITUDE,311 GB_SVC_NO_DE_EMPHASIS,312 GB_SVC_UNIPRO_FAST_MODE, 2, 2,313 GB_SVC_PWRM_RXTERMINATION |314 GB_SVC_PWRM_TXTERMINATION, 0,315 NULL, NULL);316 else317 ret = gb_svc_intf_set_power_mode(svc, intf_id,318 GB_SVC_UNIPRO_HS_SERIES_A,319 GB_SVC_UNIPRO_SLOW_AUTO_MODE,320 2, 1,321 GB_SVC_SMALL_AMPLITUDE,322 GB_SVC_NO_DE_EMPHASIS,323 GB_SVC_UNIPRO_SLOW_AUTO_MODE,324 2, 1,325 0, 0,326 NULL, NULL);327 328 return ret;329}330 331static int gb_camera_set_power_mode(struct gb_camera *gcam, bool hs)332{333 struct gb_interface *intf = gcam->connection->intf;334 struct gb_svc *svc = gcam->connection->hd->svc;335 int ret;336 337 ret = gb_camera_set_intf_power_mode(gcam, intf->interface_id, hs);338 if (ret < 0) {339 dev_err(&gcam->bundle->dev, "failed to set module interface to %s (%d)\n",340 hs ? "HS" : "PWM", ret);341 return ret;342 }343 344 ret = gb_camera_set_intf_power_mode(gcam, svc->ap_intf_id, hs);345 if (ret < 0) {346 gb_camera_set_intf_power_mode(gcam, intf->interface_id, !hs);347 dev_err(&gcam->bundle->dev, "failed to set AP interface to %s (%d)\n",348 hs ? "HS" : "PWM", ret);349 return ret;350 }351 352 return 0;353}354 355struct ap_csi_config_request {356 __u8 csi_id;357 __u8 flags;358#define GB_CAMERA_CSI_FLAG_CLOCK_CONTINUOUS 0x01359 __u8 num_lanes;360 __u8 padding;361 __le32 csi_clk_freq;362 __le32 max_pkt_size;363} __packed;364 365/*366 * TODO: Compute the number of lanes dynamically based on bandwidth367 * requirements.368 */369#define GB_CAMERA_CSI_NUM_DATA_LANES 4370 371#define GB_CAMERA_CSI_CLK_FREQ_MAX 999000000U372#define GB_CAMERA_CSI_CLK_FREQ_MIN 100000000U373#define GB_CAMERA_CSI_CLK_FREQ_MARGIN 150000000U374 375static int gb_camera_setup_data_connection(struct gb_camera *gcam,376 struct gb_camera_configure_streams_response *resp,377 struct gb_camera_csi_params *csi_params)378{379 struct ap_csi_config_request csi_cfg;380 struct gb_connection *conn;381 unsigned int clk_freq;382 int ret;383 384 /*385 * Create the data connection between the camera module data CPort and386 * APB CDSI1. The CDSI1 CPort ID is hardcoded by the ES2 bridge.387 */388 conn = gb_connection_create_offloaded(gcam->bundle, gcam->data_cport_id,389 GB_CONNECTION_FLAG_NO_FLOWCTRL |390 GB_CONNECTION_FLAG_CDSI1);391 if (IS_ERR(conn))392 return PTR_ERR(conn);393 394 gcam->data_connection = conn;395 gb_connection_set_data(conn, gcam);396 397 ret = gb_connection_enable(conn);398 if (ret)399 goto error_conn_destroy;400 401 /* Set the UniPro link to high speed mode. */402 ret = gb_camera_set_power_mode(gcam, true);403 if (ret < 0)404 goto error_conn_disable;405 406 /*407 * Configure the APB-A CSI-2 transmitter.408 *409 * Hardcode the number of lanes to 4 and compute the bus clock frequency410 * based on the module bandwidth requirements with a safety margin.411 */412 memset(&csi_cfg, 0, sizeof(csi_cfg));413 csi_cfg.csi_id = 1;414 csi_cfg.flags = 0;415 csi_cfg.num_lanes = GB_CAMERA_CSI_NUM_DATA_LANES;416 417 clk_freq = resp->data_rate / 2 / GB_CAMERA_CSI_NUM_DATA_LANES;418 clk_freq = clamp(clk_freq + GB_CAMERA_CSI_CLK_FREQ_MARGIN,419 GB_CAMERA_CSI_CLK_FREQ_MIN,420 GB_CAMERA_CSI_CLK_FREQ_MAX);421 csi_cfg.csi_clk_freq = clk_freq;422 423 ret = gb_camera_get_max_pkt_size(gcam, resp);424 if (ret < 0) {425 ret = -EIO;426 goto error_power;427 }428 csi_cfg.max_pkt_size = ret;429 430 ret = gb_hd_output(gcam->connection->hd, &csi_cfg,431 sizeof(csi_cfg),432 GB_APB_REQUEST_CSI_TX_CONTROL, false);433 if (ret < 0) {434 dev_err(&gcam->bundle->dev, "failed to start the CSI transmitter\n");435 goto error_power;436 }437 438 if (csi_params) {439 csi_params->clk_freq = csi_cfg.csi_clk_freq;440 csi_params->num_lanes = csi_cfg.num_lanes;441 }442 443 return 0;444 445error_power:446 gb_camera_set_power_mode(gcam, false);447error_conn_disable:448 gb_connection_disable(gcam->data_connection);449error_conn_destroy:450 gb_connection_destroy(gcam->data_connection);451 gcam->data_connection = NULL;452 return ret;453}454 455static void gb_camera_teardown_data_connection(struct gb_camera *gcam)456{457 struct ap_csi_config_request csi_cfg;458 int ret;459 460 /* Stop the APB1 CSI transmitter. */461 memset(&csi_cfg, 0, sizeof(csi_cfg));462 csi_cfg.csi_id = 1;463 464 ret = gb_hd_output(gcam->connection->hd, &csi_cfg,465 sizeof(csi_cfg),466 GB_APB_REQUEST_CSI_TX_CONTROL, false);467 468 if (ret < 0)469 dev_err(&gcam->bundle->dev, "failed to stop the CSI transmitter\n");470 471 /* Set the UniPro link to low speed mode. */472 gb_camera_set_power_mode(gcam, false);473 474 /* Destroy the data connection. */475 gb_connection_disable(gcam->data_connection);476 gb_connection_destroy(gcam->data_connection);477 gcam->data_connection = NULL;478}479 480/* -----------------------------------------------------------------------------481 * Camera Protocol Operations482 */483 484static int gb_camera_capabilities(struct gb_camera *gcam,485 u8 *capabilities, size_t *size)486{487 int ret;488 489 ret = gb_pm_runtime_get_sync(gcam->bundle);490 if (ret)491 return ret;492 493 mutex_lock(&gcam->mutex);494 495 if (!gcam->connection) {496 ret = -EINVAL;497 goto done;498 }499 500 ret = gb_camera_operation_sync_flags(gcam->connection,501 GB_CAMERA_TYPE_CAPABILITIES,502 GB_OPERATION_FLAG_SHORT_RESPONSE,503 NULL, 0,504 (void *)capabilities, size);505 if (ret)506 dev_err(&gcam->bundle->dev, "failed to retrieve capabilities: %d\n", ret);507 508done:509 mutex_unlock(&gcam->mutex);510 511 gb_pm_runtime_put_autosuspend(gcam->bundle);512 513 return ret;514}515 516static int gb_camera_configure_streams(struct gb_camera *gcam,517 unsigned int *num_streams,518 unsigned int *flags,519 struct gb_camera_stream_config *streams,520 struct gb_camera_csi_params *csi_params)521{522 struct gb_camera_configure_streams_request *req;523 struct gb_camera_configure_streams_response *resp;524 unsigned int nstreams = *num_streams;525 unsigned int i;526 size_t req_size;527 size_t resp_size;528 int ret;529 530 if (nstreams > GB_CAMERA_MAX_STREAMS)531 return -EINVAL;532 533 req_size = sizeof(*req) + nstreams * sizeof(req->config[0]);534 resp_size = sizeof(*resp) + nstreams * sizeof(resp->config[0]);535 536 req = kmalloc(req_size, GFP_KERNEL);537 resp = kmalloc(resp_size, GFP_KERNEL);538 if (!req || !resp) {539 kfree(req);540 kfree(resp);541 return -ENOMEM;542 }543 544 req->num_streams = nstreams;545 req->flags = *flags;546 req->padding = 0;547 548 for (i = 0; i < nstreams; ++i) {549 struct gb_camera_stream_config_request *cfg = &req->config[i];550 551 cfg->width = cpu_to_le16(streams[i].width);552 cfg->height = cpu_to_le16(streams[i].height);553 cfg->format = cpu_to_le16(streams[i].format);554 cfg->padding = 0;555 }556 557 mutex_lock(&gcam->mutex);558 559 ret = gb_pm_runtime_get_sync(gcam->bundle);560 if (ret)561 goto done_skip_pm_put;562 563 if (!gcam->connection) {564 ret = -EINVAL;565 goto done;566 }567 568 ret = gb_camera_operation_sync_flags(gcam->connection,569 GB_CAMERA_TYPE_CONFIGURE_STREAMS,570 GB_OPERATION_FLAG_SHORT_RESPONSE,571 req, req_size,572 resp, &resp_size);573 if (ret < 0)574 goto done;575 576 ret = gb_camera_configure_streams_validate_response(gcam, resp,577 nstreams);578 if (ret < 0)579 goto done;580 581 *flags = resp->flags;582 *num_streams = resp->num_streams;583 584 for (i = 0; i < resp->num_streams; ++i) {585 struct gb_camera_stream_config_response *cfg = &resp->config[i];586 587 streams[i].width = le16_to_cpu(cfg->width);588 streams[i].height = le16_to_cpu(cfg->height);589 streams[i].format = le16_to_cpu(cfg->format);590 streams[i].vc = cfg->virtual_channel;591 streams[i].dt[0] = cfg->data_type[0];592 streams[i].dt[1] = cfg->data_type[1];593 streams[i].max_size = le32_to_cpu(cfg->max_size);594 }595 596 if ((resp->flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED) ||597 (req->flags & GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY))598 goto done;599 600 if (gcam->state == GB_CAMERA_STATE_CONFIGURED) {601 gb_camera_teardown_data_connection(gcam);602 gcam->state = GB_CAMERA_STATE_UNCONFIGURED;603 604 /*605 * When unconfiguring streams release the PM runtime reference606 * that was acquired when streams were configured. The bundle607 * won't be suspended until the PM runtime reference acquired at608 * the beginning of this function gets released right before609 * returning.610 */611 gb_pm_runtime_put_noidle(gcam->bundle);612 }613 614 if (resp->num_streams == 0)615 goto done;616 617 /*618 * Make sure the bundle won't be suspended until streams get619 * unconfigured after the stream is configured successfully620 */621 gb_pm_runtime_get_noresume(gcam->bundle);622 623 /* Setup CSI-2 connection from APB-A to AP */624 ret = gb_camera_setup_data_connection(gcam, resp, csi_params);625 if (ret < 0) {626 memset(req, 0, sizeof(*req));627 gb_operation_sync(gcam->connection,628 GB_CAMERA_TYPE_CONFIGURE_STREAMS,629 req, sizeof(*req),630 resp, sizeof(*resp));631 *flags = 0;632 *num_streams = 0;633 gb_pm_runtime_put_noidle(gcam->bundle);634 goto done;635 }636 637 gcam->state = GB_CAMERA_STATE_CONFIGURED;638 639done:640 gb_pm_runtime_put_autosuspend(gcam->bundle);641 642done_skip_pm_put:643 mutex_unlock(&gcam->mutex);644 kfree(req);645 kfree(resp);646 return ret;647}648 649static int gb_camera_capture(struct gb_camera *gcam, u32 request_id,650 unsigned int streams, unsigned int num_frames,651 size_t settings_size, const void *settings)652{653 struct gb_camera_capture_request *req;654 size_t req_size;655 int ret;656 657 if (settings_size > GB_CAMERA_MAX_SETTINGS_SIZE)658 return -EINVAL;659 660 req_size = sizeof(*req) + settings_size;661 req = kmalloc(req_size, GFP_KERNEL);662 if (!req)663 return -ENOMEM;664 665 req->request_id = cpu_to_le32(request_id);666 req->streams = streams;667 req->padding = 0;668 req->num_frames = cpu_to_le16(num_frames);669 memcpy(req->settings, settings, settings_size);670 671 mutex_lock(&gcam->mutex);672 673 if (!gcam->connection) {674 ret = -EINVAL;675 goto done;676 }677 678 ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_CAPTURE,679 req, req_size, NULL, 0);680done:681 mutex_unlock(&gcam->mutex);682 683 kfree(req);684 685 return ret;686}687 688static int gb_camera_flush(struct gb_camera *gcam, u32 *request_id)689{690 struct gb_camera_flush_response resp;691 int ret;692 693 mutex_lock(&gcam->mutex);694 695 if (!gcam->connection) {696 ret = -EINVAL;697 goto done;698 }699 700 ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_FLUSH, NULL, 0,701 &resp, sizeof(resp));702 703 if (ret < 0)704 goto done;705 706 if (request_id)707 *request_id = le32_to_cpu(resp.request_id);708 709done:710 mutex_unlock(&gcam->mutex);711 712 return ret;713}714 715static int gb_camera_request_handler(struct gb_operation *op)716{717 struct gb_camera *gcam = gb_connection_get_data(op->connection);718 struct gb_camera_metadata_request *payload;719 struct gb_message *request;720 721 if (op->type != GB_CAMERA_TYPE_METADATA) {722 dev_err(&gcam->bundle->dev, "Unsupported unsolicited event: %u\n", op->type);723 return -EINVAL;724 }725 726 request = op->request;727 728 if (request->payload_size < sizeof(*payload)) {729 dev_err(&gcam->bundle->dev, "Wrong event size received (%zu < %zu)\n",730 request->payload_size, sizeof(*payload));731 return -EINVAL;732 }733 734 payload = request->payload;735 736 dev_dbg(&gcam->bundle->dev, "received metadata for request %u, frame %u, stream %u\n",737 payload->request_id, payload->frame_number, payload->stream);738 739 return 0;740}741 742/* -----------------------------------------------------------------------------743 * Interface with HOST gmp camera.744 */745static unsigned int gb_camera_mbus_to_gb(enum v4l2_mbus_pixelcode mbus_code)746{747 unsigned int i;748 749 for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) {750 if (gb_fmt_info[i].mbus_code == mbus_code)751 return gb_fmt_info[i].gb_format;752 }753 return gb_fmt_info[0].gb_format;754}755 756static enum v4l2_mbus_pixelcode gb_camera_gb_to_mbus(u16 gb_fmt)757{758 unsigned int i;759 760 for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) {761 if (gb_fmt_info[i].gb_format == gb_fmt)762 return gb_fmt_info[i].mbus_code;763 }764 return gb_fmt_info[0].mbus_code;765}766 767static ssize_t gb_camera_op_capabilities(void *priv, char *data, size_t len)768{769 struct gb_camera *gcam = priv;770 size_t capabilities_len = len;771 int ret;772 773 ret = gb_camera_capabilities(gcam, data, &capabilities_len);774 if (ret)775 return ret;776 777 return capabilities_len;778}779 780static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams,781 unsigned int *flags, struct gb_camera_stream *streams,782 struct gb_camera_csi_params *csi_params)783{784 struct gb_camera *gcam = priv;785 struct gb_camera_stream_config *gb_streams;786 unsigned int gb_flags = 0;787 unsigned int gb_nstreams = *nstreams;788 unsigned int i;789 int ret;790 791 if (gb_nstreams > GB_CAMERA_MAX_STREAMS)792 return -EINVAL;793 794 gb_streams = kcalloc(gb_nstreams, sizeof(*gb_streams), GFP_KERNEL);795 if (!gb_streams)796 return -ENOMEM;797 798 for (i = 0; i < gb_nstreams; i++) {799 gb_streams[i].width = streams[i].width;800 gb_streams[i].height = streams[i].height;801 gb_streams[i].format =802 gb_camera_mbus_to_gb(streams[i].pixel_code);803 }804 805 if (*flags & GB_CAMERA_IN_FLAG_TEST)806 gb_flags |= GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY;807 808 ret = gb_camera_configure_streams(gcam, &gb_nstreams,809 &gb_flags, gb_streams, csi_params);810 if (ret < 0)811 goto done;812 if (gb_nstreams > *nstreams) {813 ret = -EINVAL;814 goto done;815 }816 817 *flags = 0;818 if (gb_flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED)819 *flags |= GB_CAMERA_OUT_FLAG_ADJUSTED;820 821 for (i = 0; i < gb_nstreams; i++) {822 streams[i].width = gb_streams[i].width;823 streams[i].height = gb_streams[i].height;824 streams[i].vc = gb_streams[i].vc;825 streams[i].dt[0] = gb_streams[i].dt[0];826 streams[i].dt[1] = gb_streams[i].dt[1];827 streams[i].max_size = gb_streams[i].max_size;828 streams[i].pixel_code =829 gb_camera_gb_to_mbus(gb_streams[i].format);830 }831 *nstreams = gb_nstreams;832 833done:834 kfree(gb_streams);835 return ret;836}837 838static int gb_camera_op_capture(void *priv, u32 request_id,839 unsigned int streams, unsigned int num_frames,840 size_t settings_size, const void *settings)841{842 struct gb_camera *gcam = priv;843 844 return gb_camera_capture(gcam, request_id, streams, num_frames,845 settings_size, settings);846}847 848static int gb_camera_op_flush(void *priv, u32 *request_id)849{850 struct gb_camera *gcam = priv;851 852 return gb_camera_flush(gcam, request_id);853}854 855static const struct gb_camera_ops gb_cam_ops = {856 .capabilities = gb_camera_op_capabilities,857 .configure_streams = gb_camera_op_configure_streams,858 .capture = gb_camera_op_capture,859 .flush = gb_camera_op_flush,860};861 862/* -----------------------------------------------------------------------------863 * DebugFS864 */865 866static ssize_t gb_camera_debugfs_capabilities(struct gb_camera *gcam,867 char *buf, size_t len)868{869 struct gb_camera_debugfs_buffer *buffer =870 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES];871 size_t size = 1024;872 unsigned int i;873 u8 *caps;874 int ret;875 876 caps = kmalloc(size, GFP_KERNEL);877 if (!caps)878 return -ENOMEM;879 880 ret = gb_camera_capabilities(gcam, caps, &size);881 if (ret < 0)882 goto done;883 884 /*885 * hex_dump_to_buffer() doesn't return the number of bytes dumped prior886 * to v4.0, we need our own implementation :-(887 */888 buffer->length = 0;889 890 for (i = 0; i < size; i += 16) {891 unsigned int nbytes = min_t(unsigned int, size - i, 16);892 893 buffer->length += sprintf(buffer->data + buffer->length,894 "%*ph\n", nbytes, caps + i);895 }896 897done:898 kfree(caps);899 return ret;900}901 902static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam,903 char *buf, size_t len)904{905 struct gb_camera_debugfs_buffer *buffer =906 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_STREAMS];907 struct gb_camera_stream_config *streams;908 unsigned int nstreams;909 unsigned int flags;910 unsigned int i;911 char *token;912 int ret;913 914 /* Retrieve number of streams to configure */915 token = strsep(&buf, ";");916 if (!token)917 return -EINVAL;918 919 ret = kstrtouint(token, 10, &nstreams);920 if (ret < 0)921 return ret;922 923 if (nstreams > GB_CAMERA_MAX_STREAMS)924 return -EINVAL;925 926 token = strsep(&buf, ";");927 if (!token)928 return -EINVAL;929 930 ret = kstrtouint(token, 10, &flags);931 if (ret < 0)932 return ret;933 934 /* For each stream to configure parse width, height and format */935 streams = kcalloc(nstreams, sizeof(*streams), GFP_KERNEL);936 if (!streams)937 return -ENOMEM;938 939 for (i = 0; i < nstreams; ++i) {940 struct gb_camera_stream_config *stream = &streams[i];941 942 /* width */943 token = strsep(&buf, ";");944 if (!token) {945 ret = -EINVAL;946 goto done;947 }948 ret = kstrtouint(token, 10, &stream->width);949 if (ret < 0)950 goto done;951 952 /* height */953 token = strsep(&buf, ";");954 if (!token)955 goto done;956 957 ret = kstrtouint(token, 10, &stream->height);958 if (ret < 0)959 goto done;960 961 /* Image format code */962 token = strsep(&buf, ";");963 if (!token)964 goto done;965 966 ret = kstrtouint(token, 16, &stream->format);967 if (ret < 0)968 goto done;969 }970 971 ret = gb_camera_configure_streams(gcam, &nstreams, &flags, streams,972 NULL);973 if (ret < 0)974 goto done;975 976 buffer->length = sprintf(buffer->data, "%u;%u;", nstreams, flags);977 978 for (i = 0; i < nstreams; ++i) {979 struct gb_camera_stream_config *stream = &streams[i];980 981 buffer->length += sprintf(buffer->data + buffer->length,982 "%u;%u;%u;%u;%u;%u;%u;",983 stream->width, stream->height,984 stream->format, stream->vc,985 stream->dt[0], stream->dt[1],986 stream->max_size);987 }988 989 ret = len;990 991done:992 kfree(streams);993 return ret;994};995 996static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam,997 char *buf, size_t len)998{999 unsigned int request_id;1000 unsigned int streams_mask;1001 unsigned int num_frames;1002 char *token;1003 int ret;1004 1005 /* Request id */1006 token = strsep(&buf, ";");1007 if (!token)1008 return -EINVAL;1009 ret = kstrtouint(token, 10, &request_id);1010 if (ret < 0)1011 return ret;1012 1013 /* Stream mask */1014 token = strsep(&buf, ";");1015 if (!token)1016 return -EINVAL;1017 ret = kstrtouint(token, 16, &streams_mask);1018 if (ret < 0)1019 return ret;1020 1021 /* number of frames */1022 token = strsep(&buf, ";");1023 if (!token)1024 return -EINVAL;1025 ret = kstrtouint(token, 10, &num_frames);1026 if (ret < 0)1027 return ret;1028 1029 ret = gb_camera_capture(gcam, request_id, streams_mask, num_frames, 0,1030 NULL);1031 if (ret < 0)1032 return ret;1033 1034 return len;1035}1036 1037static ssize_t gb_camera_debugfs_flush(struct gb_camera *gcam,1038 char *buf, size_t len)1039{1040 struct gb_camera_debugfs_buffer *buffer =1041 &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_FLUSH];1042 unsigned int req_id;1043 int ret;1044 1045 ret = gb_camera_flush(gcam, &req_id);1046 if (ret < 0)1047 return ret;1048 1049 buffer->length = sprintf(buffer->data, "%u", req_id);1050 1051 return len;1052}1053 1054struct gb_camera_debugfs_entry {1055 const char *name;1056 unsigned int mask;1057 unsigned int buffer;1058 ssize_t (*execute)(struct gb_camera *gcam, char *buf, size_t len);1059};1060 1061static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = {1062 {1063 .name = "capabilities",1064 .mask = S_IFREG | 0444,1065 .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,1066 .execute = gb_camera_debugfs_capabilities,1067 }, {1068 .name = "configure_streams",1069 .mask = S_IFREG | 0666,1070 .buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS,1071 .execute = gb_camera_debugfs_configure_streams,1072 }, {1073 .name = "capture",1074 .mask = S_IFREG | 0666,1075 .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,1076 .execute = gb_camera_debugfs_capture,1077 }, {1078 .name = "flush",1079 .mask = S_IFREG | 0666,1080 .buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH,1081 .execute = gb_camera_debugfs_flush,1082 },1083};1084 1085static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf,1086 size_t len, loff_t *offset)1087{1088 const struct gb_camera_debugfs_entry *op = file->private_data;1089 struct gb_camera *gcam = file_inode(file)->i_private;1090 struct gb_camera_debugfs_buffer *buffer;1091 ssize_t ret;1092 1093 /* For read-only entries the operation is triggered by a read. */1094 if (!(op->mask & 0222)) {1095 ret = op->execute(gcam, NULL, 0);1096 if (ret < 0)1097 return ret;1098 }1099 1100 buffer = &gcam->debugfs.buffers[op->buffer];1101 1102 return simple_read_from_buffer(buf, len, offset, buffer->data,1103 buffer->length);1104}1105 1106static ssize_t gb_camera_debugfs_write(struct file *file,1107 const char __user *buf, size_t len,1108 loff_t *offset)1109{1110 const struct gb_camera_debugfs_entry *op = file->private_data;1111 struct gb_camera *gcam = file_inode(file)->i_private;1112 ssize_t ret;1113 char *kbuf;1114 1115 if (len > 1024)1116 return -EINVAL;1117 1118 kbuf = memdup_user_nul(buf, len);1119 if (IS_ERR(kbuf))1120 return PTR_ERR(kbuf);1121 1122 ret = op->execute(gcam, kbuf, len);1123 1124done:1125 kfree(kbuf);1126 return ret;1127}1128 1129static int gb_camera_debugfs_open(struct inode *inode, struct file *file)1130{1131 unsigned int i;1132 1133 for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {1134 const struct gb_camera_debugfs_entry *entry =1135 &gb_camera_debugfs_entries[i];1136 1137 if (!strcmp(file->f_path.dentry->d_iname, entry->name)) {1138 file->private_data = (void *)entry;1139 break;1140 }1141 }1142 1143 return 0;1144}1145 1146static const struct file_operations gb_camera_debugfs_ops = {1147 .open = gb_camera_debugfs_open,1148 .read = gb_camera_debugfs_read,1149 .write = gb_camera_debugfs_write,1150};1151 1152static int gb_camera_debugfs_init(struct gb_camera *gcam)1153{1154 struct gb_connection *connection = gcam->connection;1155 char dirname[27];1156 unsigned int i;1157 1158 /*1159 * Create root debugfs entry and a file entry for each camera operation.1160 */1161 snprintf(dirname, 27, "camera-%u.%u", connection->intf->interface_id,1162 gcam->bundle->id);1163 1164 gcam->debugfs.root = debugfs_create_dir(dirname, gb_debugfs_get());1165 1166 gcam->debugfs.buffers =1167 vmalloc(array_size(GB_CAMERA_DEBUGFS_BUFFER_MAX,1168 sizeof(*gcam->debugfs.buffers)));1169 if (!gcam->debugfs.buffers)1170 return -ENOMEM;1171 1172 for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {1173 const struct gb_camera_debugfs_entry *entry =1174 &gb_camera_debugfs_entries[i];1175 1176 gcam->debugfs.buffers[i].length = 0;1177 1178 debugfs_create_file(entry->name, entry->mask,1179 gcam->debugfs.root, gcam,1180 &gb_camera_debugfs_ops);1181 }1182 1183 return 0;1184}1185 1186static void gb_camera_debugfs_cleanup(struct gb_camera *gcam)1187{1188 debugfs_remove_recursive(gcam->debugfs.root);1189 1190 vfree(gcam->debugfs.buffers);1191}1192 1193/* -----------------------------------------------------------------------------1194 * Init & Cleanup1195 */1196 1197static void gb_camera_cleanup(struct gb_camera *gcam)1198{1199 gb_camera_debugfs_cleanup(gcam);1200 1201 mutex_lock(&gcam->mutex);1202 if (gcam->data_connection) {1203 gb_connection_disable(gcam->data_connection);1204 gb_connection_destroy(gcam->data_connection);1205 gcam->data_connection = NULL;1206 }1207 1208 if (gcam->connection) {1209 gb_connection_disable(gcam->connection);1210 gb_connection_destroy(gcam->connection);1211 gcam->connection = NULL;1212 }1213 mutex_unlock(&gcam->mutex);1214}1215 1216static void gb_camera_release_module(struct kref *ref)1217{1218 struct gb_camera_module *cam_mod =1219 container_of(ref, struct gb_camera_module, refcount);1220 kfree(cam_mod->priv);1221}1222 1223static int gb_camera_probe(struct gb_bundle *bundle,1224 const struct greybus_bundle_id *id)1225{1226 struct gb_connection *conn;1227 struct gb_camera *gcam;1228 u16 mgmt_cport_id = 0;1229 u16 data_cport_id = 0;1230 unsigned int i;1231 int ret;1232 1233 /*1234 * The camera bundle must contain exactly two CPorts, one for the1235 * camera management protocol and one for the camera data protocol.1236 */1237 if (bundle->num_cports != 2)1238 return -ENODEV;1239 1240 for (i = 0; i < bundle->num_cports; ++i) {1241 struct greybus_descriptor_cport *desc = &bundle->cport_desc[i];1242 1243 switch (desc->protocol_id) {1244 case GREYBUS_PROTOCOL_CAMERA_MGMT:1245 mgmt_cport_id = le16_to_cpu(desc->id);1246 break;1247 case GREYBUS_PROTOCOL_CAMERA_DATA:1248 data_cport_id = le16_to_cpu(desc->id);1249 break;1250 default:1251 return -ENODEV;1252 }1253 }1254 1255 if (!mgmt_cport_id || !data_cport_id)1256 return -ENODEV;1257 1258 gcam = kzalloc(sizeof(*gcam), GFP_KERNEL);1259 if (!gcam)1260 return -ENOMEM;1261 1262 mutex_init(&gcam->mutex);1263 1264 gcam->bundle = bundle;1265 gcam->state = GB_CAMERA_STATE_UNCONFIGURED;1266 gcam->data_cport_id = data_cport_id;1267 1268 conn = gb_connection_create(bundle, mgmt_cport_id,1269 gb_camera_request_handler);1270 if (IS_ERR(conn)) {1271 ret = PTR_ERR(conn);1272 goto error;1273 }1274 1275 gcam->connection = conn;1276 gb_connection_set_data(conn, gcam);1277 1278 ret = gb_connection_enable(conn);1279 if (ret)1280 goto error;1281 1282 ret = gb_camera_debugfs_init(gcam);1283 if (ret < 0)1284 goto error;1285 1286 gcam->module.priv = gcam;1287 gcam->module.ops = &gb_cam_ops;1288 gcam->module.interface_id = gcam->connection->intf->interface_id;1289 gcam->module.release = gb_camera_release_module;1290 ret = gb_camera_register(&gcam->module);1291 if (ret < 0)1292 goto error;1293 1294 greybus_set_drvdata(bundle, gcam);1295 1296 gb_pm_runtime_put_autosuspend(gcam->bundle);1297 1298 return 0;1299 1300error:1301 gb_camera_cleanup(gcam);1302 kfree(gcam);1303 return ret;1304}1305 1306static void gb_camera_disconnect(struct gb_bundle *bundle)1307{1308 struct gb_camera *gcam = greybus_get_drvdata(bundle);1309 int ret;1310 1311 ret = gb_pm_runtime_get_sync(bundle);1312 if (ret)1313 gb_pm_runtime_get_noresume(bundle);1314 1315 gb_camera_cleanup(gcam);1316 gb_camera_unregister(&gcam->module);1317}1318 1319static const struct greybus_bundle_id gb_camera_id_table[] = {1320 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) },1321 { },1322};1323 1324#ifdef CONFIG_PM1325static int gb_camera_suspend(struct device *dev)1326{1327 struct gb_bundle *bundle = to_gb_bundle(dev);1328 struct gb_camera *gcam = greybus_get_drvdata(bundle);1329 1330 if (gcam->data_connection)1331 gb_connection_disable(gcam->data_connection);1332 1333 gb_connection_disable(gcam->connection);1334 1335 return 0;1336}1337 1338static int gb_camera_resume(struct device *dev)1339{1340 struct gb_bundle *bundle = to_gb_bundle(dev);1341 struct gb_camera *gcam = greybus_get_drvdata(bundle);1342 int ret;1343 1344 ret = gb_connection_enable(gcam->connection);1345 if (ret) {1346 dev_err(&gcam->bundle->dev, "failed to enable connection: %d\n", ret);1347 return ret;1348 }1349 1350 if (gcam->data_connection) {1351 ret = gb_connection_enable(gcam->data_connection);1352 if (ret) {1353 dev_err(&gcam->bundle->dev,1354 "failed to enable data connection: %d\n", ret);1355 return ret;1356 }1357 }1358 1359 return 0;1360}1361#endif1362 1363static const struct dev_pm_ops gb_camera_pm_ops = {1364 SET_RUNTIME_PM_OPS(gb_camera_suspend, gb_camera_resume, NULL)1365};1366 1367static struct greybus_driver gb_camera_driver = {1368 .name = "camera",1369 .probe = gb_camera_probe,1370 .disconnect = gb_camera_disconnect,1371 .id_table = gb_camera_id_table,1372 .driver.pm = &gb_camera_pm_ops,1373};1374 1375module_greybus_driver(gb_camera_driver);1376 1377MODULE_DESCRIPTION("Greybus Camera protocol driver.");1378MODULE_LICENSE("GPL v2");1379