From nobody Mon Jun 8 15:48:15 2026 Received: from sender-pp-o91.zoho.in (sender-pp-o91.zoho.in [103.117.158.91]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 362A33F0AA0 for ; Thu, 28 May 2026 13:13:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=103.117.158.91 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779974037; cv=pass; b=esE6Dl0Nru+NmkACiCLXgPMj7TursAAgqRBqUhKH7zApN8atbvs+jKePukEkVlA803v9q0cMbr01aJpZKjPIWrAmC2+mRJ7QcnYFHf0rifQoD4m3xOeLqVehmRqFBOn6TduORBYMc3OlJMNdtjOIuL27VB93jl/Byv+gXBMXYgo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779974037; c=relaxed/simple; bh=pvQ+STDiiZRBcqTtHGRjfrRWc2wJPAvVEHMATMnORoQ=; h=Date:From:To:Cc:Message-ID:Subject:MIME-Version:Content-Type; b=hMbRteaj7DWoaY6YZeJcidK61DRWpqnaZBAwevEqR9lJiWRjr7Nmy7ytiAtOcOcVrA4xDNiKL2RzHlZicsXxl1vZ9flGkz+zJJlf/IqcXK7fewiQduJXc+DL8BpzbmgkOk5B6S5Rf52QgWJLwulY17Bl5qc40Eo6ssvgd0xPKxI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=zohomail.in; spf=pass smtp.mailfrom=zohomail.in; dkim=pass (1024-bit key) header.d=zohomail.in header.i=linuxuser509@zohomail.in header.b=XFIG36Zo; arc=pass smtp.client-ip=103.117.158.91 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=zohomail.in Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zohomail.in Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=zohomail.in header.i=linuxuser509@zohomail.in header.b="XFIG36Zo" ARC-Seal: i=1; a=rsa-sha256; t=1779974014; cv=none; d=zohomail.in; s=zohoarc; b=QNEcmsx1FuEf9Uh+zOojaSIxTnYFs5mPBRdQBGtIlRu+u++7lU/+KTyIqqK1FPY5iFNSHp6fvqZUE/RdnEMoGC55pELkTprYWwES6y6t39Ma8vs+lUbaJwerGzEKSv6h6xLKN1SaoPbZvI67DO2CigcClG+ResQgJ5XLh68QWuc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.in; s=zohoarc; t=1779974014; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=/IfQZAxhx4wJKgCGkMH01Dqulb4JlEBqaUa0r4aR1QU=; b=TtM0an3o9gzZ8prsg93d5Q87CT82T3VwlYuIr75FKhQIESbuURIwtkBJIVmLdPhwo2DFp+v5ghuatnZx9w/WQjbR0MIXSdusNfwUWq+FihyS1kbPtyjQ4tfrOCxQBmiDIiP7I+6CmFcrtL4XYYSv2rhQzWJLHflSkDxcvRRpNaE= ARC-Authentication-Results: i=1; mx.zohomail.in; dkim=pass header.i=zohomail.in; spf=pass smtp.mailfrom=linuxuser509@zohomail.in; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1779974014; s=zoho; d=zohomail.in; i=linuxuser509@zohomail.in; h=Date:Date:From:From:To:To:Cc:Cc:Message-ID:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To; bh=/IfQZAxhx4wJKgCGkMH01Dqulb4JlEBqaUa0r4aR1QU=; b=XFIG36ZoXy0LSjuz328lJ7vP2GzgsXvorSKSNeGNaduA+DHLv5lX6GxtHAv3No12 mg31xR7COA0yXSMwtD1VPKkFLCfzO3yS6gg4ZTtp6Hnk4Z0YRvaif3kjkc6MRkUaMgD sNxWBrjr65w11ib+nVAsoRTFKzp2KGUWGvsD65i4= Received: from mail.zoho.in by mx.zoho.in with SMTP id 1779974013758499.1900685872248; Thu, 28 May 2026 18:43:33 +0530 (IST) Received: from [157.48.153.160] by mail.zoho.in with HTTP;Thu, 28 May 2026 18:43:33 +0530 (IST) Date: Thu, 28 May 2026 18:43:33 +0530 From: Ashwin Gundarapu To: "gregkh" Cc: "linux-kernel" , "linux-staging" Message-ID: <19e6eb80318.39c60cbc208598.4490466986425288169@zohomail.in> Subject: [PATCH] staging: greybus: camera: remove broken camera driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Importance: Medium User-Agent: Zoho Mail X-Mailer: Zoho Mail Content-Type: text/plain; charset="utf-8" The Greybus camera driver has been non-functional since its inclusion due to a missing greybus_protocols.h header and reliance on deprecated v4l2_mbus_pixelcode enum. The Project Ara hardware this driver was written for never shipped, and the driver has seen no real fixes in over 8 years=E2=80=94only treewide cleanups such as GFP_KERNEL conversions and debugfs error handling changes. Remove the entire camera driver (~2,000 lines). Signed-off-by: Ashwin Gundarapu --- drivers/staging/greybus/camera.c | 1047 --------------------------- drivers/staging/greybus/gb-camera.h | 127 ---- 2 files changed, 1174 deletions(-) delete mode 100644 drivers/staging/greybus/camera.c delete mode 100644 drivers/staging/greybus/gb-camera.h diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/cam= era.c deleted file mode 100644 index f448b7713384..000000000000 --- a/drivers/staging/greybus/camera.c +++ /dev/null @@ -1,1047 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus Camera protocol driver. - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gb-camera.h" -#include "greybus_protocols.h" - -enum gb_camera_debugs_buffer_id { - GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES, - GB_CAMERA_DEBUGFS_BUFFER_STREAMS, - GB_CAMERA_DEBUGFS_BUFFER_CAPTURE, - GB_CAMERA_DEBUGFS_BUFFER_FLUSH, - GB_CAMERA_DEBUGFS_BUFFER_MAX, -}; - -struct gb_camera_debugfs_buffer { - char data[PAGE_SIZE]; - size_t length; -}; - -enum gb_camera_state { - GB_CAMERA_STATE_UNCONFIGURED, - GB_CAMERA_STATE_CONFIGURED, -}; - -/** - * struct gb_camera - A Greybus Camera Device - * @connection: the greybus connection for camera management - * @data_connection: the greybus connection for camera data - * @data_cport_id: the data CPort ID on the module side - * @mutex: protects the connection and state fields - * @state: the current module state - * @debugfs: debugfs entries for camera protocol operations testing - * @module: Greybus camera module registered to HOST processor. - */ -struct gb_camera { - struct gb_bundle *bundle; - struct gb_connection *connection; - struct gb_connection *data_connection; - u16 data_cport_id; - - struct mutex mutex; - enum gb_camera_state state; - - struct { - struct dentry *root; - struct gb_camera_debugfs_buffer *buffers; - } debugfs; - - struct gb_camera_module module; -}; - -struct gb_camera_stream_config { - unsigned int width; - unsigned int height; - unsigned int format; - unsigned int vc; - unsigned int dt[2]; - unsigned int max_size; -}; - -struct gb_camera_fmt_info { - enum v4l2_mbus_pixelcode mbus_code; - unsigned int gb_format; - unsigned int bpp; -}; - -/* GB format to media code map */ -static const struct gb_camera_fmt_info gb_fmt_info[] =3D { - { - .mbus_code =3D V4L2_MBUS_FMT_UYVY8_1X16, - .gb_format =3D 0x01, - .bpp =3D 16, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_NV12_1x8, - .gb_format =3D 0x12, - .bpp =3D 12, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_NV21_1x8, - .gb_format =3D 0x13, - .bpp =3D 12, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_YU12_1x8, - .gb_format =3D 0x16, - .bpp =3D 12, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_YV12_1x8, - .gb_format =3D 0x17, - .bpp =3D 12, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_JPEG_1X8, - .gb_format =3D 0x40, - .bpp =3D 0, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_GB_CAM_METADATA_1X8, - .gb_format =3D 0x41, - .bpp =3D 0, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_GB_CAM_DEBUG_DATA_1X8, - .gb_format =3D 0x42, - .bpp =3D 0, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SBGGR10_1X10, - .gb_format =3D 0x80, - .bpp =3D 10, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SGBRG10_1X10, - .gb_format =3D 0x81, - .bpp =3D 10, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SGRBG10_1X10, - .gb_format =3D 0x82, - .bpp =3D 10, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SRGGB10_1X10, - .gb_format =3D 0x83, - .bpp =3D 10, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SBGGR12_1X12, - .gb_format =3D 0x84, - .bpp =3D 12, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SGBRG12_1X12, - .gb_format =3D 0x85, - .bpp =3D 12, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SGRBG12_1X12, - .gb_format =3D 0x86, - .bpp =3D 12, - }, - { - .mbus_code =3D V4L2_MBUS_FMT_SRGGB12_1X12, - .gb_format =3D 0x87, - .bpp =3D 12, - }, -}; - -static const struct gb_camera_fmt_info *gb_camera_get_format_info(u16 gb_f= mt) -{ - unsigned int i; - - for (i =3D 0; i < ARRAY_SIZE(gb_fmt_info); i++) { - if (gb_fmt_info[i].gb_format =3D=3D gb_fmt) - return &gb_fmt_info[i]; - } - - return NULL; -} - -#define ES2_APB_CDSI0_CPORT 16 -#define ES2_APB_CDSI1_CPORT 17 - -#define GB_CAMERA_MAX_SETTINGS_SIZE 8192 - -static int gb_camera_operation_sync_flags(struct gb_connection *connection, - int type, unsigned int flags, - void *request, size_t request_size, - void *response, size_t *response_size) -{ - struct gb_operation *operation; - int ret; - - operation =3D gb_operation_create_flags(connection, type, request_size, - *response_size, flags, - GFP_KERNEL); - if (!operation) - return -ENOMEM; - - if (request_size) - memcpy(operation->request->payload, request, request_size); - - ret =3D gb_operation_request_send_sync(operation); - if (ret) { - dev_err(&connection->hd->dev, - "%s: synchronous operation of type 0x%02x failed: %d\n", - connection->name, type, ret); - } else { - *response_size =3D operation->response->payload_size; - - if (operation->response->payload_size) - memcpy(response, operation->response->payload, - operation->response->payload_size); - } - - gb_operation_put(operation); - - return ret; -} - -static int gb_camera_get_max_pkt_size(struct gb_camera *gcam, - struct gb_camera_configure_streams_response *resp) -{ - unsigned int max_pkt_size =3D 0; - unsigned int i; - - for (i =3D 0; i < resp->num_streams; i++) { - struct gb_camera_stream_config_response *cfg =3D &resp->config[i]; - const struct gb_camera_fmt_info *fmt_info; - unsigned int pkt_size; - - fmt_info =3D gb_camera_get_format_info(cfg->format); - if (!fmt_info) { - dev_err(&gcam->bundle->dev, "unsupported greybus image format: %d\n", - cfg->format); - return -EIO; - } - - if (fmt_info->bpp =3D=3D 0) { - pkt_size =3D le32_to_cpu(cfg->max_pkt_size); - - if (pkt_size =3D=3D 0) { - dev_err(&gcam->bundle->dev, - "Stream %u: invalid zero maximum packet size\n", - i); - return -EIO; - } - } else { - pkt_size =3D le16_to_cpu(cfg->width) * fmt_info->bpp / 8; - - if (pkt_size !=3D le32_to_cpu(cfg->max_pkt_size)) { - dev_err(&gcam->bundle->dev, - "Stream %u: maximum packet size mismatch (%u/%u)\n", - i, pkt_size, cfg->max_pkt_size); - return -EIO; - } - } - - max_pkt_size =3D max(pkt_size, max_pkt_size); - } - - return max_pkt_size; -} - -/* - * Validate the stream configuration response verifying padding is correct= ly - * set and the returned number of streams is supported - */ -static const int gb_camera_configure_streams_validate_response(struct gb_c= amera *gcam, - struct gb_camera_configure_streams_response *resp, - unsigned int nstreams) -{ - unsigned int i; - - /* Validate the returned response structure */ - if (resp->padding[0] || resp->padding[1]) { - dev_err(&gcam->bundle->dev, "response padding !=3D 0\n"); - return -EIO; - } - - if (resp->num_streams > nstreams) { - dev_err(&gcam->bundle->dev, "got #streams %u > request %u\n", - resp->num_streams, nstreams); - return -EIO; - } - - for (i =3D 0; i < resp->num_streams; i++) { - struct gb_camera_stream_config_response *cfg =3D &resp->config[i]; - - if (cfg->padding) { - dev_err(&gcam->bundle->dev, "stream #%u padding !=3D 0\n", i); - return -EIO; - } - } - - return 0; -} - -/* -----------------------------------------------------------------------= ------ - * Hardware Configuration - */ - -static int gb_camera_set_intf_power_mode(struct gb_camera *gcam, u8 intf_i= d, - bool hs) -{ - struct gb_svc *svc =3D gcam->connection->hd->svc; - int ret; - - if (hs) - ret =3D gb_svc_intf_set_power_mode(svc, intf_id, - GB_SVC_UNIPRO_HS_SERIES_A, - GB_SVC_UNIPRO_FAST_MODE, 2, 2, - GB_SVC_SMALL_AMPLITUDE, - GB_SVC_NO_DE_EMPHASIS, - GB_SVC_UNIPRO_FAST_MODE, 2, 2, - GB_SVC_PWRM_RXTERMINATION | - GB_SVC_PWRM_TXTERMINATION, 0, - NULL, NULL); - else - ret =3D gb_svc_intf_set_power_mode(svc, intf_id, - GB_SVC_UNIPRO_HS_SERIES_A, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - GB_SVC_SMALL_AMPLITUDE, - GB_SVC_NO_DE_EMPHASIS, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - 0, 0, - NULL, NULL); - - return ret; -} - -static int gb_camera_set_power_mode(struct gb_camera *gcam, bool hs) -{ - struct gb_interface *intf =3D gcam->connection->intf; - struct gb_svc *svc =3D gcam->connection->hd->svc; - int ret; - - ret =3D gb_camera_set_intf_power_mode(gcam, intf->interface_id, hs); - if (ret < 0) { - dev_err(&gcam->bundle->dev, "failed to set module interface to %s (%d)\n= ", - hs ? "HS" : "PWM", ret); - return ret; - } - - ret =3D gb_camera_set_intf_power_mode(gcam, svc->ap_intf_id, hs); - if (ret < 0) { - gb_camera_set_intf_power_mode(gcam, intf->interface_id, !hs); - dev_err(&gcam->bundle->dev, "failed to set AP interface to %s (%d)\n", - hs ? "HS" : "PWM", ret); - return ret; - } - - return 0; -} - -struct ap_csi_config_request { - __u8 csi_id; - __u8 flags; -#define GB_CAMERA_CSI_FLAG_CLOCK_CONTINUOUS 0x01 - __u8 num_lanes; - __u8 padding; - __le32 csi_clk_freq; - __le32 max_pkt_size; -} __packed; - -/* - * TODO: Compute the number of lanes dynamically based on bandwidth - * requirements. - */ -#define GB_CAMERA_CSI_NUM_DATA_LANES 4 - -#define GB_CAMERA_CSI_CLK_FREQ_MAX 999000000U -#define GB_CAMERA_CSI_CLK_FREQ_MIN 100000000U -#define GB_CAMERA_CSI_CLK_FREQ_MARGIN 150000000U - -static int gb_camera_setup_data_connection(struct gb_camera *gcam, - struct gb_camera_configure_streams_response *resp, - struct gb_camera_csi_params *csi_params) -{ - struct ap_csi_config_request csi_cfg; - struct gb_connection *conn; - unsigned int clk_freq; - int ret; - - /* - * Create the data connection between the camera module data CPort and - * APB CDSI1. The CDSI1 CPort ID is hardcoded by the ES2 bridge. - */ - conn =3D gb_connection_create_offloaded(gcam->bundle, gcam->data_cport_id, - GB_CONNECTION_FLAG_NO_FLOWCTRL | - GB_CONNECTION_FLAG_CDSI1); - if (IS_ERR(conn)) - return PTR_ERR(conn); - - gcam->data_connection =3D conn; - gb_connection_set_data(conn, gcam); - - ret =3D gb_connection_enable(conn); - if (ret) - goto error_conn_destroy; - - /* Set the UniPro link to high speed mode. */ - ret =3D gb_camera_set_power_mode(gcam, true); - if (ret < 0) - goto error_conn_disable; - - /* - * Configure the APB-A CSI-2 transmitter. - * - * Hardcode the number of lanes to 4 and compute the bus clock frequency - * based on the module bandwidth requirements with a safety margin. - */ - memset(&csi_cfg, 0, sizeof(csi_cfg)); - csi_cfg.csi_id =3D 1; - csi_cfg.flags =3D 0; - csi_cfg.num_lanes =3D GB_CAMERA_CSI_NUM_DATA_LANES; - - clk_freq =3D resp->data_rate / 2 / GB_CAMERA_CSI_NUM_DATA_LANES; - clk_freq =3D clamp(clk_freq + GB_CAMERA_CSI_CLK_FREQ_MARGIN, - GB_CAMERA_CSI_CLK_FREQ_MIN, - GB_CAMERA_CSI_CLK_FREQ_MAX); - csi_cfg.csi_clk_freq =3D clk_freq; - - ret =3D gb_camera_get_max_pkt_size(gcam, resp); - if (ret < 0) { - ret =3D -EIO; - goto error_power; - } - csi_cfg.max_pkt_size =3D ret; - - ret =3D gb_hd_output(gcam->connection->hd, &csi_cfg, - sizeof(csi_cfg), - GB_APB_REQUEST_CSI_TX_CONTROL, false); - if (ret < 0) { - dev_err(&gcam->bundle->dev, "failed to start the CSI transmitter\n"); - goto error_power; - } - - if (csi_params) { - csi_params->clk_freq =3D csi_cfg.csi_clk_freq; - csi_params->num_lanes =3D csi_cfg.num_lanes; - } - - return 0; - -error_power: - gb_camera_set_power_mode(gcam, false); -error_conn_disable: - gb_connection_disable(gcam->data_connection); -error_conn_destroy: - gb_connection_destroy(gcam->data_connection); - gcam->data_connection =3D NULL; - return ret; -} - -static void gb_camera_teardown_data_connection(struct gb_camera *gcam) -{ - struct ap_csi_config_request csi_cfg; - int ret; - - /* Stop the APB1 CSI transmitter. */ - memset(&csi_cfg, 0, sizeof(csi_cfg)); - csi_cfg.csi_id =3D 1; - - ret =3D gb_hd_output(gcam->connection->hd, &csi_cfg, - sizeof(csi_cfg), - GB_APB_REQUEST_CSI_TX_CONTROL, false); - - if (ret < 0) - dev_err(&gcam->bundle->dev, "failed to stop the CSI transmitter\n"); - - /* Set the UniPro link to low speed mode. */ - gb_camera_set_power_mode(gcam, false); - - /* Destroy the data connection. */ - gb_connection_disable(gcam->data_connection); - gb_connection_destroy(gcam->data_connection); - gcam->data_connection =3D NULL; -} - -/* -----------------------------------------------------------------------= ------ - * Camera Protocol Operations - */ - -static int gb_camera_capabilities(struct gb_camera *gcam, - u8 *capabilities, size_t *size) -{ - int ret; - - ret =3D gb_pm_runtime_get_sync(gcam->bundle); - if (ret) - return ret; - - mutex_lock(&gcam->mutex); - - if (!gcam->connection) { - ret =3D -EINVAL; - goto done; - } - - ret =3D gb_camera_operation_sync_flags(gcam->connection, - GB_CAMERA_TYPE_CAPABILITIES, - GB_OPERATION_FLAG_SHORT_RESPONSE, - NULL, 0, - (void *)capabilities, size); - if (ret) - dev_err(&gcam->bundle->dev, "failed to retrieve capabilities: %d\n", ret= ); - -done: - mutex_unlock(&gcam->mutex); - - gb_pm_runtime_put_autosuspend(gcam->bundle); - - return ret; -} - -static int gb_camera_configure_streams(struct gb_camera *gcam, - unsigned int *num_streams, - unsigned int *flags, - struct gb_camera_stream_config *streams, - struct gb_camera_csi_params *csi_params) -{ - struct gb_camera_configure_streams_request *req; - struct gb_camera_configure_streams_response *resp; - unsigned int nstreams =3D *num_streams; - unsigned int i; - size_t req_size; - size_t resp_size; - int ret; - - if (nstreams > GB_CAMERA_MAX_STREAMS) - return -EINVAL; - - req_size =3D sizeof(*req) + nstreams * sizeof(req->config[0]); - resp_size =3D sizeof(*resp) + nstreams * sizeof(resp->config[0]); - - req =3D kmalloc(req_size, GFP_KERNEL); - resp =3D kmalloc(resp_size, GFP_KERNEL); - if (!req || !resp) { - kfree(req); - kfree(resp); - return -ENOMEM; - } - - req->num_streams =3D nstreams; - req->flags =3D *flags; - req->padding =3D 0; - - for (i =3D 0; i < nstreams; ++i) { - struct gb_camera_stream_config_request *cfg =3D &req->config[i]; - - cfg->width =3D cpu_to_le16(streams[i].width); - cfg->height =3D cpu_to_le16(streams[i].height); - cfg->format =3D cpu_to_le16(streams[i].format); - cfg->padding =3D 0; - } - - mutex_lock(&gcam->mutex); - - ret =3D gb_pm_runtime_get_sync(gcam->bundle); - if (ret) - goto done_skip_pm_put; - - if (!gcam->connection) { - ret =3D -EINVAL; - goto done; - } - - ret =3D gb_camera_operation_sync_flags(gcam->connection, - GB_CAMERA_TYPE_CONFIGURE_STREAMS, - GB_OPERATION_FLAG_SHORT_RESPONSE, - req, req_size, - resp, &resp_size); - if (ret < 0) - goto done; - - ret =3D gb_camera_configure_streams_validate_response(gcam, resp, - nstreams); - if (ret < 0) - goto done; - - *flags =3D resp->flags; - *num_streams =3D resp->num_streams; - - for (i =3D 0; i < resp->num_streams; ++i) { - struct gb_camera_stream_config_response *cfg =3D &resp->config[i]; - - streams[i].width =3D le16_to_cpu(cfg->width); - streams[i].height =3D le16_to_cpu(cfg->height); - streams[i].format =3D le16_to_cpu(cfg->format); - streams[i].vc =3D cfg->virtual_channel; - streams[i].dt[0] =3D cfg->data_type[0]; - streams[i].dt[1] =3D cfg->data_type[1]; - streams[i].max_size =3D le32_to_cpu(cfg->max_size); - } - - if ((resp->flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED) || - (req->flags & GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY)) - goto done; - - if (gcam->state =3D=3D GB_CAMERA_STATE_CONFIGURED) { - gb_camera_teardown_data_connection(gcam); - gcam->state =3D GB_CAMERA_STATE_UNCONFIGURED; - - /* - * When unconfiguring streams release the PM runtime reference - * that was acquired when streams were configured. The bundle - * won't be suspended until the PM runtime reference acquired at - * the beginning of this function gets released right before - * returning. - */ - gb_pm_runtime_put_noidle(gcam->bundle); - } - - if (resp->num_streams =3D=3D 0) - goto done; - - /* - * Make sure the bundle won't be suspended until streams get - * unconfigured after the stream is configured successfully - */ - gb_pm_runtime_get_noresume(gcam->bundle); - - /* Setup CSI-2 connection from APB-A to AP */ - ret =3D gb_camera_setup_data_connection(gcam, resp, csi_params); - if (ret < 0) { - memset(req, 0, sizeof(*req)); - gb_operation_sync(gcam->connection, - GB_CAMERA_TYPE_CONFIGURE_STREAMS, - req, sizeof(*req), - resp, sizeof(*resp)); - *flags =3D 0; - *num_streams =3D 0; - gb_pm_runtime_put_noidle(gcam->bundle); - goto done; - } - - gcam->state =3D GB_CAMERA_STATE_CONFIGURED; - -done: - gb_pm_runtime_put_autosuspend(gcam->bundle); - -done_skip_pm_put: - mutex_unlock(&gcam->mutex); - kfree(req); - kfree(resp); - return ret; -} - -static int gb_camera_capture(struct gb_camera *gcam, u32 request_id, - unsigned int streams, unsigned int num_frames, - size_t settings_size, const void *settings) -{ - struct gb_camera_capture_request *req; - size_t req_size; - int ret; - - if (settings_size > GB_CAMERA_MAX_SETTINGS_SIZE) - return -EINVAL; - - req_size =3D sizeof(*req) + settings_size; - req =3D kmalloc(req_size, GFP_KERNEL); - if (!req) - return -ENOMEM; - - req->request_id =3D cpu_to_le32(request_id); - req->streams =3D streams; - req->padding =3D 0; - req->num_frames =3D cpu_to_le16(num_frames); - memcpy(req->settings, settings, settings_size); - - mutex_lock(&gcam->mutex); - - if (!gcam->connection) { - ret =3D -EINVAL; - goto done; - } - - ret =3D gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_CAPTURE, - req, req_size, NULL, 0); -done: - mutex_unlock(&gcam->mutex); - - kfree(req); - - return ret; -} - -static int gb_camera_flush(struct gb_camera *gcam, u32 *request_id) -{ - struct gb_camera_flush_response resp; - int ret; - - mutex_lock(&gcam->mutex); - - if (!gcam->connection) { - ret =3D -EINVAL; - goto done; - } - - ret =3D gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_FLUSH, NULL, 0, - &resp, sizeof(resp)); - - if (ret < 0) - goto done; - - if (request_id) - *request_id =3D le32_to_cpu(resp.request_id); - -done: - mutex_unlock(&gcam->mutex); - - return ret; -} - -static int gb_camera_request_handler(struct gb_operation *op) -{ - struct gb_camera *gcam =3D gb_connection_get_data(op->connection); - struct gb_camera_metadata_request *payload; - struct gb_message *request; - - if (op->type !=3D GB_CAMERA_TYPE_METADATA) { - dev_err(&gcam->bundle->dev, "Unsupported unsolicited event: %u\n", op->t= ype); - return -EINVAL; - } - - request =3D op->request; - - if (request->payload_size < sizeof(*payload)) { - dev_err(&gcam->bundle->dev, "Wrong event size received (%zu < %zu)\n", - request->payload_size, sizeof(*payload)); - return -EINVAL; - } - - payload =3D request->payload; - - dev_dbg(&gcam->bundle->dev, "received metadata for request %u, frame %u, = stream %u\n", - payload->request_id, payload->frame_number, payload->stream); - - return 0; -} - -/* -----------------------------------------------------------------------= ------ - * Interface with HOST gmp camera. - */ -static unsigned int gb_camera_mbus_to_gb(enum v4l2_mbus_pixelcode mbus_cod= e) -{ - unsigned int i; - - for (i =3D 0; i < ARRAY_SIZE(gb_fmt_info); i++) { - if (gb_fmt_info[i].mbus_code =3D=3D mbus_code) - return gb_fmt_info[i].gb_format; - } - return gb_fmt_info[0].gb_format; -} - -static enum v4l2_mbus_pixelcode gb_camera_gb_to_mbus(u16 gb_fmt) -{ - unsigned int i; - - for (i =3D 0; i < ARRAY_SIZE(gb_fmt_info); i++) { - if (gb_fmt_info[i].gb_format =3D=3D gb_fmt) - return gb_fmt_info[i].mbus_code; - } - return gb_fmt_info[0].mbus_code; -} - -static ssize_t gb_camera_op_capabilities(void *priv, char *data, size_t le= n) -{ - struct gb_camera *gcam =3D priv; - size_t capabilities_len =3D len; - int ret; - - ret =3D gb_camera_capabilities(gcam, data, &capabilities_len); - if (ret) - return ret; - - return capabilities_len; -} - -static int gb_camera_op_configure_streams(void *priv, unsigned int *nstrea= ms, - unsigned int *flags, struct gb_camera_stream *streams, - struct gb_camera_csi_params *csi_params) -{ - struct gb_camera *gcam =3D priv; - struct gb_camera_stream_config *gb_streams; - unsigned int gb_flags =3D 0; - unsigned int gb_nstreams =3D *nstreams; - unsigned int i; - int ret; - - if (gb_nstreams > GB_CAMERA_MAX_STREAMS) - return -EINVAL; - - gb_streams =3D kzalloc_objs(*gb_streams, gb_nstreams); - if (!gb_streams) - return -ENOMEM; - - for (i =3D 0; i < gb_nstreams; i++) { - gb_streams[i].width =3D streams[i].width; - gb_streams[i].height =3D streams[i].height; - gb_streams[i].format =3D - gb_camera_mbus_to_gb(streams[i].pixel_code); - } - - if (*flags & GB_CAMERA_IN_FLAG_TEST) - gb_flags |=3D GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY; - - ret =3D gb_camera_configure_streams(gcam, &gb_nstreams, - &gb_flags, gb_streams, csi_params); - if (ret < 0) - goto done; - if (gb_nstreams > *nstreams) { - ret =3D -EINVAL; - goto done; - } - - *flags =3D 0; - if (gb_flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED) - *flags |=3D GB_CAMERA_OUT_FLAG_ADJUSTED; - - for (i =3D 0; i < gb_nstreams; i++) { - streams[i].width =3D gb_streams[i].width; - streams[i].height =3D gb_streams[i].height; - streams[i].vc =3D gb_streams[i].vc; - streams[i].dt[0] =3D gb_streams[i].dt[0]; - streams[i].dt[1] =3D gb_streams[i].dt[1]; - streams[i].max_size =3D gb_streams[i].max_size; - streams[i].pixel_code =3D - gb_camera_gb_to_mbus(gb_streams[i].format); - } - *nstreams =3D gb_nstreams; - -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) -{ - struct gb_camera *gcam =3D priv; - - return gb_camera_capture(gcam, request_id, streams, num_frames, - settings_size, settings); -} - -static int gb_camera_op_flush(void *priv, u32 *request_id) -{ - struct gb_camera *gcam =3D priv; - - return gb_camera_flush(gcam, request_id); -} - -static const struct gb_camera_ops gb_cam_ops =3D { - .capabilities =3D gb_camera_op_capabilities, - .configure_streams =3D gb_camera_op_configure_streams, - .capture =3D gb_camera_op_capture, - .flush =3D gb_camera_op_flush, -}; - -/* -----------------------------------------------------------------------= ------ - * DebugFS - */ - -static void gb_camera_cleanup(struct gb_camera *gcam) -{ - gb_camera_debugfs_cleanup(gcam); - - mutex_lock(&gcam->mutex); - if (gcam->data_connection) { - gb_connection_disable(gcam->data_connection); - gb_connection_destroy(gcam->data_connection); - gcam->data_connection =3D NULL; - } - - if (gcam->connection) { - gb_connection_disable(gcam->connection); - gb_connection_destroy(gcam->connection); - gcam->connection =3D NULL; - } - mutex_unlock(&gcam->mutex); -} - -static void gb_camera_release_module(struct kref *ref) -{ - struct gb_camera_module *cam_mod =3D - container_of(ref, struct gb_camera_module, refcount); - kfree(cam_mod->priv); -} - -static int gb_camera_probe(struct gb_bundle *bundle, - const struct greybus_bundle_id *id) -{ - struct gb_connection *conn; - struct gb_camera *gcam; - u16 mgmt_cport_id =3D 0; - u16 data_cport_id =3D 0; - unsigned int i; - int ret; - - /* - * The camera bundle must contain exactly two CPorts, one for the - * camera management protocol and one for the camera data protocol. - */ - if (bundle->num_cports !=3D 2) - return -ENODEV; - - for (i =3D 0; i < bundle->num_cports; ++i) { - struct greybus_descriptor_cport *desc =3D &bundle->cport_desc[i]; - - switch (desc->protocol_id) { - case GREYBUS_PROTOCOL_CAMERA_MGMT: - mgmt_cport_id =3D le16_to_cpu(desc->id); - break; - case GREYBUS_PROTOCOL_CAMERA_DATA: - data_cport_id =3D le16_to_cpu(desc->id); - break; - default: - return -ENODEV; - } - } - - if (!mgmt_cport_id || !data_cport_id) - return -ENODEV; - - gcam =3D kzalloc_obj(*gcam); - if (!gcam) - return -ENOMEM; - - mutex_init(&gcam->mutex); - - gcam->bundle =3D bundle; - gcam->state =3D GB_CAMERA_STATE_UNCONFIGURED; - gcam->data_cport_id =3D data_cport_id; - - conn =3D gb_connection_create(bundle, mgmt_cport_id, - gb_camera_request_handler); - if (IS_ERR(conn)) { - ret =3D PTR_ERR(conn); - goto error; - } - - gcam->connection =3D conn; - gb_connection_set_data(conn, gcam); - - ret =3D gb_connection_enable(conn); - if (ret) - goto error; - - ret =3D gb_camera_debugfs_init(gcam); - if (ret < 0) - goto error; - - gcam->module.priv =3D gcam; - gcam->module.ops =3D &gb_cam_ops; - gcam->module.interface_id =3D gcam->connection->intf->interface_id; - gcam->module.release =3D gb_camera_release_module; - ret =3D gb_camera_register(&gcam->module); - if (ret < 0) - goto error; - - greybus_set_drvdata(bundle, gcam); - - gb_pm_runtime_put_autosuspend(gcam->bundle); - - return 0; - -error: - gb_camera_cleanup(gcam); - kfree(gcam); - return ret; -} - -static void gb_camera_disconnect(struct gb_bundle *bundle) -{ - struct gb_camera *gcam =3D greybus_get_drvdata(bundle); - int ret; - - ret =3D gb_pm_runtime_get_sync(bundle); - if (ret) - gb_pm_runtime_get_noresume(bundle); - - gb_camera_cleanup(gcam); - gb_camera_unregister(&gcam->module); -} - -static const struct greybus_bundle_id gb_camera_id_table[] =3D { - { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) }, - { }, -}; - -#ifdef CONFIG_PM -static int gb_camera_suspend(struct device *dev) -{ - struct gb_bundle *bundle =3D to_gb_bundle(dev); - struct gb_camera *gcam =3D greybus_get_drvdata(bundle); - - if (gcam->data_connection) - gb_connection_disable(gcam->data_connection); - - gb_connection_disable(gcam->connection); - - return 0; -} - -static int gb_camera_resume(struct device *dev) -{ - struct gb_bundle *bundle =3D to_gb_bundle(dev); - struct gb_camera *gcam =3D greybus_get_drvdata(bundle); - int ret; - - ret =3D gb_connection_enable(gcam->connection); - if (ret) { - dev_err(&gcam->bundle->dev, "failed to enable connection: %d\n", ret); - return ret; - } - - if (gcam->data_connection) { - ret =3D gb_connection_enable(gcam->data_connection); - if (ret) { - dev_err(&gcam->bundle->dev, - "failed to enable data connection: %d\n", ret); - return ret; - } - } - - return 0; -} -#endif - -static const struct dev_pm_ops gb_camera_pm_ops =3D { - SET_RUNTIME_PM_OPS(gb_camera_suspend, gb_camera_resume, NULL) -}; - -static struct greybus_driver gb_camera_driver =3D { - .name =3D "camera", - .probe =3D gb_camera_probe, - .disconnect =3D gb_camera_disconnect, - .id_table =3D gb_camera_id_table, - .driver.pm =3D &gb_camera_pm_ops, -}; - -module_greybus_driver(gb_camera_driver); - -MODULE_DESCRIPTION("Greybus Camera protocol driver."); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/greybus/gb-camera.h b/drivers/staging/greybus/= gb-camera.h deleted file mode 100644 index d5a33a13f2a4..000000000000 --- a/drivers/staging/greybus/gb-camera.h +++ /dev/null @@ -1,127 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Greybus Camera protocol driver. - * - * Copyright 2015 Google Inc. - */ -#ifndef __GB_CAMERA_H -#define __GB_CAMERA_H - -#include - -/* Input flags need to be set from the caller */ -#define GB_CAMERA_IN_FLAG_TEST BIT(0) -/* Output flags returned */ -#define GB_CAMERA_OUT_FLAG_ADJUSTED BIT(0) - -/** - * struct gb_camera_stream - Represents greybus camera stream. - * @width: Stream width in pixels. - * @height: Stream height in pixels. - * @pixel_code: Media bus pixel code. - * @vc: MIPI CSI virtual channel. - * @dt: MIPI CSI data types. Most formats use a single data type, in which= case - * the second element will be ignored. - * @max_size: Maximum size of a frame in bytes. The camera module guarante= es - * that all data between the Frame Start and Frame End packet f= or - * the associated virtual channel and data type(s) will not exc= eed - * this size. - */ -struct gb_camera_stream { - unsigned int width; - unsigned int height; - enum v4l2_mbus_pixelcode pixel_code; - unsigned int vc; - unsigned int dt[2]; - unsigned int max_size; -}; - -/** - * struct gb_camera_csi_params - CSI configuration parameters - * @num_lanes: number of CSI data lanes - * @clk_freq: CSI clock frequency in Hz - */ -struct gb_camera_csi_params { - unsigned int num_lanes; - unsigned int clk_freq; -}; - -/** - * struct gb_camera_ops - Greybus camera operations, used by the Greybus c= amera - * driver to expose operations to the host camera d= river. - * @capabilities: Retrieve camera capabilities and store them in the buffer - * 'buf' capabilities. The buffer maximum size is specified= by - * the caller in the 'size' parameter, and the effective - * capabilities size is returned from the function. If the = buffer - * size is too small to hold the capabilities an error is - * returned and the buffer is left untouched. - * - * @configure_streams: Negotiate configuration and prepare the module for = video - * capture. The caller specifies the number of streams= it - * requests in the 'nstreams' argument and the associa= ted - * streams configurations in the 'streams' argument. T= he - * GB_CAMERA_IN_FLAG_TEST 'flag' can be set to test a - * configuration without applying it, otherwise the - * configuration is applied by the module. The module = can - * decide to modify the requested configuration, inclu= ding - * using a different number of streams. In that case t= he - * modified configuration won't be applied, the - * GB_CAMERA_OUT_FLAG_ADJUSTED 'flag' will be set upon - * return, and the modified configuration and number of - * streams stored in 'streams' and 'array'. The module - * returns its CSI-2 bus parameters in the 'csi_params' - * structure in all cases. - * - * @capture: Submit a capture request. The supplied 'request_id' must be u= nique - * and higher than the IDs of all the previously submitted reque= sts. - * The 'streams' argument specifies which streams are affected b= y the - * request in the form of a bitmask, with bits corresponding to = the - * configured streams indexes. If the request contains settings,= the - * 'settings' argument points to the settings buffer and its siz= e is - * specified by the 'settings_size' argument. Otherwise the 'set= tings' - * argument should be set to NULL and 'settings_size' to 0. - * - * @flush: Flush the capture requests queue. Return the ID of the last req= uest - * that will processed by the device before it stops transmitting = video - * frames. All queued capture requests with IDs higher than the re= turned - * ID will be dropped without being processed. - */ -struct gb_camera_ops { - ssize_t (*capabilities)(void *priv, char *buf, size_t len); - int (*configure_streams)(void *priv, unsigned int *nstreams, - unsigned int *flags, - struct gb_camera_stream *streams, - struct gb_camera_csi_params *csi_params); - int (*capture)(void *priv, u32 request_id, - unsigned int streams, unsigned int num_frames, - size_t settings_size, const void *settings); - int (*flush)(void *priv, u32 *request_id); -}; - -/** - * struct gb_camera_module - Represents greybus camera module. - * @priv: Module private data, passed to all camera operations. - * @ops: Greybus camera operation callbacks. - * @interface_id: Interface id of the module. - * @refcount: Reference counting object. - * @release: Module release function. - * @list: List entry in the camera modules list. - */ -struct gb_camera_module { - void *priv; - const struct gb_camera_ops *ops; - - unsigned int interface_id; - struct kref refcount; - void (*release)(struct kref *kref); - struct list_head list; /* Global list */ -}; - -#define gb_camera_call(f, op, args...) \ - (!(f) ? -ENODEV : (((f)->ops->op) ? \ - (f)->ops->op((f)->priv, ##args) : -ENOIOCTLCMD)) - -int gb_camera_register(struct gb_camera_module *module); -int gb_camera_unregister(struct gb_camera_module *module); - -#endif /* __GB_CAMERA_H */ --=20 2.43.0