122 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| /*
 | |
|  * Maxim Quad GMSL Deserializer Remode Device Manage
 | |
|  *
 | |
|  * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
 | |
|  *
 | |
|  * Author: Cai Wenzhong <cwz@rock-chips.com>
 | |
|  *
 | |
|  */
 | |
| #include <linux/module.h>
 | |
| #include <linux/of_graph.h>
 | |
| #include <media/v4l2-async.h>
 | |
| #include <media/v4l2-ctrls.h>
 | |
| #include <media/v4l2-subdev.h>
 | |
| #include <media/v4l2-fwnode.h>
 | |
| 
 | |
| #include "maxim4c_api.h"
 | |
| 
 | |
| int maxim4c_remote_devices_power(maxim4c_t *maxim4c, u8 link_mask, int on)
 | |
| {
 | |
| 	struct device *dev = &maxim4c->client->dev;
 | |
| 	maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link;
 | |
| 	struct maxim4c_link_cfg *link_cfg = NULL;
 | |
| 	struct device_node *remote_cam_node = NULL;
 | |
| 	struct i2c_client *remote_cam_client = NULL;
 | |
| 	struct v4l2_subdev *remote_cam_sd = NULL;
 | |
| 	int ret = 0, error = 0, i = 0;
 | |
| 
 | |
| 	dev_dbg(dev, "%s: link mask = 0x%02x, on = %d\n", __func__, link_mask, on);
 | |
| 
 | |
| 	for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) {
 | |
| 		if ((link_mask & BIT(i)) == 0) {
 | |
| 			dev_dbg(dev, "link id = %d mask is disabled\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		link_cfg = &gmsl_link->link_cfg[i];
 | |
| 		if (link_cfg->link_enable == 0) {
 | |
| 			dev_info(dev, "link id = %d is disabled\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		remote_cam_node = link_cfg->remote_cam_node;
 | |
| 		if (IS_ERR_OR_NULL(remote_cam_node)) {
 | |
| 			dev_info(dev, "link id = %d remote camera node error\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 		remote_cam_client = of_find_i2c_device_by_node(remote_cam_node);
 | |
| 		if (IS_ERR_OR_NULL(remote_cam_client)) {
 | |
| 			dev_info(dev, "link id = %d remote camera client error\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 		remote_cam_sd = i2c_get_clientdata(remote_cam_client);
 | |
| 		if (IS_ERR_OR_NULL(remote_cam_sd)) {
 | |
| 			dev_info(dev, "link id = %d remote camera v4l2_subdev error\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		dev_info(dev, "link id = %d remote camera power = %d\n", i, on);
 | |
| 		error = v4l2_subdev_call(remote_cam_sd, core, s_power, on);
 | |
| 		if (error < 0) {
 | |
| 			ret |= error;
 | |
| 			dev_err(dev, "link id = %d remote camera power error = %d\n", i, error);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return ret;
 | |
| }
 | |
| EXPORT_SYMBOL(maxim4c_remote_devices_power);
 | |
| 
 | |
| int maxim4c_remote_devices_s_stream(maxim4c_t *maxim4c, u8 link_mask, int enable)
 | |
| {
 | |
| 	struct device *dev = &maxim4c->client->dev;
 | |
| 	maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link;
 | |
| 	struct maxim4c_link_cfg *link_cfg = NULL;
 | |
| 	struct device_node *remote_cam_node = NULL;
 | |
| 	struct i2c_client *remote_cam_client = NULL;
 | |
| 	struct v4l2_subdev *remote_cam_sd = NULL;
 | |
| 	int ret = 0, error = 0, i = 0;
 | |
| 
 | |
| 	dev_dbg(dev, "%s: link mask = 0x%02x, enable = %d\n", __func__, link_mask, enable);
 | |
| 
 | |
| 	for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) {
 | |
| 		if ((link_mask & BIT(i)) == 0) {
 | |
| 			dev_dbg(dev, "link id = %d mask is disabled\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		link_cfg = &gmsl_link->link_cfg[i];
 | |
| 		if (link_cfg->link_enable == 0) {
 | |
| 			dev_info(dev, "link id = %d is disabled\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		remote_cam_node = link_cfg->remote_cam_node;
 | |
| 		if (IS_ERR_OR_NULL(remote_cam_node)) {
 | |
| 			dev_info(dev, "link id = %d remote camera node error\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 		remote_cam_client = of_find_i2c_device_by_node(remote_cam_node);
 | |
| 		if (IS_ERR_OR_NULL(remote_cam_client)) {
 | |
| 			dev_info(dev, "link id = %d remote camera client error\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 		remote_cam_sd = i2c_get_clientdata(remote_cam_client);
 | |
| 		if (IS_ERR_OR_NULL(remote_cam_sd)) {
 | |
| 			dev_info(dev, "link id = %d remote camera v4l2_subdev error\n", i);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		dev_info(dev, "link id = %d remote camera s_stream = %d\n", i, enable);
 | |
| 		error = v4l2_subdev_call(remote_cam_sd, video, s_stream, enable);
 | |
| 		if (error < 0) {
 | |
| 			ret |= error;
 | |
| 			dev_err(dev, "link id = %d remote camera s_stream error = %d\n", i, error);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return ret;
 | |
| }
 | |
| EXPORT_SYMBOL(maxim4c_remote_devices_s_stream);
 |