2 * Tegra Video Input device common APIs
4 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
6 * Author: Bryan Wu <pengw@nvidia.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/init.h>
14 #include <linux/export.h>
15 #include <linux/module.h>
17 #include <linux/of_device.h>
18 #include <linux/of_platform.h>
20 #include <media/tegra_v4l2_camera.h>
21 #include <media/camera_common.h>
22 #include <media/v4l2-event.h>
23 #include <media/tegra_camera_platform.h>
26 #include "camera/mc_common.h"
28 #include "camera/registers.h"
30 /* In TPG mode, VI only support 2 formats */
31 static void vi_tpg_fmts_bitmap_init(struct tegra_mc_vi *vi)
35 bitmap_zero(vi->tpg_fmts_bitmap, MAX_FORMAT_NUM);
37 index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_SRGGB10_1X10);
38 bitmap_set(vi->tpg_fmts_bitmap, index, 1);
40 index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_RGB888_1X32_PADHI);
41 bitmap_set(vi->tpg_fmts_bitmap, index, 1);
44 int tegra_vi_power_on(struct tegra_mc_vi *vi)
48 if (atomic_add_return(1, &vi->power_on_refcnt) > 1)
51 ret = nvhost_module_busy_ext(vi->ndev);
53 dev_err(vi->dev, "%s:nvhost module is busy\n", __func__);
58 ret = regulator_enable(vi->reg);
60 dev_err(vi->dev, "%s: enable csi regulator failed.\n",
62 goto error_regulator_fail;
66 ret = vi->fops->soc_power_on(vi);
68 goto error_soc_power_on;
71 clk_prepare_enable(vi->clk);
72 ret = clk_set_rate(vi->clk, 0);
74 dev_err(vi->dev, "failed to set vi clock\n");
75 goto error_clk_set_rate;
78 ret = tegra_camera_emc_clk_enable();
84 clk_disable_unprepare(vi->clk);
86 vi->fops->soc_power_off(vi);
88 regulator_disable(vi->reg);
90 nvhost_module_idle_ext(vi->ndev);
95 void tegra_vi_power_off(struct tegra_mc_vi *vi)
97 if (!atomic_dec_and_test(&vi->power_on_refcnt))
100 tegra_channel_ec_close(vi);
101 tegra_camera_emc_clk_disable();
102 clk_disable_unprepare(vi->clk);
103 vi->fops->soc_power_off(vi);
104 regulator_disable(vi->reg);
105 nvhost_module_idle_ext(vi->ndev);
108 /* -----------------------------------------------------------------------------
109 * Media Controller and V4L2
112 static const char *const vi_pattern_strings[] = {
114 "Black/White Direct Mode",
118 static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
120 struct tegra_mc_vi *vi = container_of(ctrl->handler, struct tegra_mc_vi,
124 case V4L2_CID_TEST_PATTERN:
126 * TPG control is only avaiable to TPG driver,
127 * it can't be changed to 0 to disable TPG mode.
133 dev_info(&vi->ndev->dev, "Set TPG mode to %d\n",
135 vi->pg_mode = ctrl->val;
136 vi->csi->pg_mode = vi->pg_mode;
138 dev_warn(&vi->ndev->dev,
139 "TPG mode can't be disabled for TPG driver\n");
142 dev_err(vi->dev, "%s:Not valid ctrl\n", __func__);
149 static const struct v4l2_ctrl_ops vi_ctrl_ops = {
153 void tegra_vi_v4l2_cleanup(struct tegra_mc_vi *vi)
155 v4l2_ctrl_handler_free(&vi->ctrl_handler);
156 v4l2_device_unregister(&vi->v4l2_dev);
158 media_device_unregister(&vi->media_dev);
160 EXPORT_SYMBOL(tegra_vi_v4l2_cleanup);
162 static void tegra_vi_notify(struct v4l2_subdev *sd,
163 unsigned int notification, void *arg)
165 struct tegra_mc_vi *vi = container_of(sd->v4l2_dev,
166 struct tegra_mc_vi, v4l2_dev);
169 if (notification != V4L2_DEVICE_NOTIFY_EVENT)
172 for (ch = 0; ch < vi->num_channels; ch++) {
173 struct tegra_channel *chan = &vi->chans[ch];
175 for (i = 0; i < chan->num_subdevs; i++)
176 if (sd == chan->subdev[i])
177 v4l2_event_queue(&chan->video, arg);
181 int tegra_vi_v4l2_init(struct tegra_mc_vi *vi)
185 vi_tpg_fmts_bitmap_init(vi);
188 * TPG mode need to reuse the real media_device struct of tegra_vi,
189 * so bypass the media_device_register() here.
192 struct vi *tegra_vi = tegra_vi_get();
194 memcpy(&vi->media_dev, &tegra_vi->mc_vi.media_dev,
195 sizeof(struct media_device));
197 vi->media_dev.dev = vi->dev;
198 strlcpy(vi->media_dev.model, "NVIDIA Tegra Video Input Device",
199 sizeof(vi->media_dev.model));
200 vi->media_dev.hw_revision = 3;
202 ret = media_device_register(&vi->media_dev);
204 dev_err(vi->dev, "media device registration failed (%d)\n",
209 mutex_init(&vi->bw_update_lock);
210 mutex_init(&vi->mipical_lock);
211 vi->v4l2_dev.mdev = &vi->media_dev;
212 vi->v4l2_dev.notify = tegra_vi_notify;
213 ret = v4l2_device_register(vi->dev, &vi->v4l2_dev);
215 dev_err(vi->dev, "V4L2 device registration failed (%d)\n",
220 v4l2_ctrl_handler_init(&vi->ctrl_handler, 1);
221 vi->pattern = v4l2_ctrl_new_std_menu_items(&vi->ctrl_handler,
222 &vi_ctrl_ops, V4L2_CID_TEST_PATTERN,
223 ARRAY_SIZE(vi_pattern_strings) - 1,
224 0, vi->pg_mode, vi_pattern_strings);
226 if (vi->ctrl_handler.error) {
227 dev_err(vi->dev, "failed to add controls\n");
228 ret = vi->ctrl_handler.error;
231 vi->v4l2_dev.ctrl_handler = &vi->ctrl_handler;
233 ret = v4l2_ctrl_handler_setup(&vi->ctrl_handler);
235 dev_err(vi->dev, "failed to set controls\n");
242 v4l2_ctrl_handler_free(&vi->ctrl_handler);
243 v4l2_device_unregister(&vi->v4l2_dev);
246 media_device_unregister(&vi->media_dev);
250 static int vi_get_clks(struct tegra_mc_vi *vi, struct platform_device *pdev)
254 vi->clk = devm_clk_get(&pdev->dev, "vi_v4l2");
255 if (IS_ERR(vi->clk)) {
256 dev_err(&pdev->dev, "Failed to get vi clock\n");
257 return PTR_ERR(vi->clk);
263 static int vi_parse_dt(struct tegra_mc_vi *vi, struct platform_device *dev)
266 int num_channels = 0;
267 struct device_node *node = dev->dev.of_node;
269 err = of_property_read_u32(node, "num-channels", &num_channels);
272 "Failed to find num of channels, set TPG mode\n");
273 vi->pg_mode = TEGRA_VI_PG_PATCH;
276 vi->num_channels = num_channels;
277 vi->chans = devm_kzalloc(&dev->dev,
278 (sizeof(struct tegra_channel) * num_channels),
286 static void set_vi_register_base(struct tegra_mc_vi *mc_vi,
287 void __iomem *regbase)
289 mc_vi->iomem = regbase;
292 int tegra_vi_media_controller_init(struct tegra_mc_vi *mc_vi,
293 struct platform_device *pdev)
296 struct nvhost_device_data *pdata = pdev->dev.platform_data;
298 set_vi_register_base(mc_vi, pdata->aperture[0]);
300 err = vi_get_clks(mc_vi, pdev);
304 if (mc_vi->pg_mode) {
305 mc_vi->chans = devm_kzalloc(&pdev->dev,
306 sizeof(struct tegra_channel) *
312 err = vi_parse_dt(mc_vi, pdev);
318 mc_vi->dev = &pdev->dev;
319 INIT_LIST_HEAD(&mc_vi->entities);
321 err = tegra_vi_v4l2_init(mc_vi);
325 /* Init Tegra VI channels */
326 err = tegra_vi_channels_init(mc_vi);
330 /* Setup media links between VI and external sensor subdev. */
332 err = tegra_vi_tpg_graph_init(mc_vi);
334 err = tegra_vi_graph_init(mc_vi);
341 tegra_vi_channels_cleanup(mc_vi);
343 tegra_vi_v4l2_cleanup(mc_vi);
345 dev_err(&pdev->dev, "%s: failed\n", __func__);
348 EXPORT_SYMBOL(tegra_vi_media_controller_init);
350 void tegra_vi_media_controller_cleanup(struct tegra_mc_vi *mc_vi)
352 tegra_vi_graph_cleanup(mc_vi);
353 tegra_vi_channels_cleanup(mc_vi);
354 tegra_vi_v4l2_cleanup(mc_vi);
356 EXPORT_SYMBOL(tegra_vi_media_controller_cleanup);