brintos

brintos / linux-shallow public Read only

0
0
Text · 31.9 KiB · ca71023 Raw
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