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 void vi_write(struct tegra_mc_vi *vi, unsigned int addr, u32 val)
32 writel(val, vi->iomem + addr);
35 /* In TPG mode, VI only support 2 formats */
36 static void vi_tpg_fmts_bitmap_init(struct tegra_mc_vi *vi)
40 bitmap_zero(vi->tpg_fmts_bitmap, MAX_FORMAT_NUM);
42 index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_SRGGB10_1X10);
43 bitmap_set(vi->tpg_fmts_bitmap, index, 1);
45 index = tegra_core_get_idx_by_code(MEDIA_BUS_FMT_RGB888_1X32_PADHI);
46 bitmap_set(vi->tpg_fmts_bitmap, index, 1);
49 int tegra_vi_power_on(struct tegra_mc_vi *vi)
53 if (atomic_add_return(1, &vi->power_on_refcnt) > 1)
56 ret = nvhost_module_busy_ext(vi->ndev);
58 dev_err(vi->dev, "%s:nvhost module is busy\n", __func__);
63 ret = regulator_enable(vi->reg);
65 dev_err(vi->dev, "%s: enable csi regulator failed.\n",
67 goto error_regulator_fail;
71 vi_write(vi, TEGRA_VI_CFG_CG_CTRL, 1);
74 ret = tegra_unpowergate_partition(TEGRA_POWERGATE_VENC);
76 dev_err(vi->dev, "failed to unpower gate VI\n");
77 goto error_unpowergate;
81 clk_prepare_enable(vi->clk);
82 ret = clk_set_rate(vi->clk, 0);
84 dev_err(vi->dev, "failed to set vi clock\n");
85 goto error_clk_set_rate;
88 ret = tegra_camera_emc_clk_enable();
94 clk_disable_unprepare(vi->clk);
96 tegra_powergate_partition(TEGRA_POWERGATE_VENC);
98 regulator_disable(vi->reg);
100 nvhost_module_idle_ext(vi->ndev);
105 void tegra_vi_power_off(struct tegra_mc_vi *vi)
107 if (!atomic_dec_and_test(&vi->power_on_refcnt))
110 tegra_channel_ec_close(vi);
111 tegra_camera_emc_clk_disable();
112 clk_disable_unprepare(vi->clk);
113 tegra_powergate_partition(TEGRA_POWERGATE_VENC);
114 regulator_disable(vi->reg);
115 nvhost_module_idle_ext(vi->ndev);
118 /* -----------------------------------------------------------------------------
119 * Media Controller and V4L2
122 static const char *const vi_pattern_strings[] = {
124 "Black/White Direct Mode",
128 static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
130 struct tegra_mc_vi *vi = container_of(ctrl->handler, struct tegra_mc_vi,
134 case V4L2_CID_TEST_PATTERN:
136 * TPG control is only avaiable to TPG driver,
137 * it can't be changed to 0 to disable TPG mode.
143 dev_info(&vi->ndev->dev, "Set TPG mode to %d\n",
145 vi->pg_mode = ctrl->val;
146 vi->csi->pg_mode = vi->pg_mode;
148 dev_warn(&vi->ndev->dev,
149 "TPG mode can't be disabled for TPG driver\n");
152 dev_err(vi->dev, "%s:Not valid ctrl\n", __func__);
159 static const struct v4l2_ctrl_ops vi_ctrl_ops = {
163 void tegra_vi_v4l2_cleanup(struct tegra_mc_vi *vi)
165 v4l2_ctrl_handler_free(&vi->ctrl_handler);
166 v4l2_device_unregister(&vi->v4l2_dev);
168 media_device_unregister(&vi->media_dev);
170 EXPORT_SYMBOL(tegra_vi_v4l2_cleanup);
172 static void tegra_vi_notify(struct v4l2_subdev *sd,
173 unsigned int notification, void *arg)
175 struct tegra_mc_vi *vi = container_of(sd->v4l2_dev,
176 struct tegra_mc_vi, v4l2_dev);
179 if (notification != V4L2_DEVICE_NOTIFY_EVENT)
182 for (ch = 0; ch < vi->num_channels; ch++) {
183 struct tegra_channel *chan = &vi->chans[ch];
185 for (i = 0; i < chan->num_subdevs; i++)
186 if (sd == chan->subdev[i])
187 v4l2_event_queue(&chan->video, arg);
191 int tegra_vi_v4l2_init(struct tegra_mc_vi *vi)
195 vi_tpg_fmts_bitmap_init(vi);
198 * TPG mode need to reuse the real media_device struct of tegra_vi,
199 * so bypass the media_device_register() here.
202 struct vi *tegra_vi = tegra_vi_get();
204 memcpy(&vi->media_dev, &tegra_vi->mc_vi.media_dev,
205 sizeof(struct media_device));
207 vi->media_dev.dev = vi->dev;
208 strlcpy(vi->media_dev.model, "NVIDIA Tegra Video Input Device",
209 sizeof(vi->media_dev.model));
210 vi->media_dev.hw_revision = 3;
212 ret = media_device_register(&vi->media_dev);
214 dev_err(vi->dev, "media device registration failed (%d)\n",
219 mutex_init(&vi->bw_update_lock);
220 mutex_init(&vi->mipical_lock);
221 vi->v4l2_dev.mdev = &vi->media_dev;
222 vi->v4l2_dev.notify = tegra_vi_notify;
223 ret = v4l2_device_register(vi->dev, &vi->v4l2_dev);
225 dev_err(vi->dev, "V4L2 device registration failed (%d)\n",
230 v4l2_ctrl_handler_init(&vi->ctrl_handler, 1);
231 vi->pattern = v4l2_ctrl_new_std_menu_items(&vi->ctrl_handler,
232 &vi_ctrl_ops, V4L2_CID_TEST_PATTERN,
233 ARRAY_SIZE(vi_pattern_strings) - 1,
234 0, vi->pg_mode, vi_pattern_strings);
236 if (vi->ctrl_handler.error) {
237 dev_err(vi->dev, "failed to add controls\n");
238 ret = vi->ctrl_handler.error;
241 vi->v4l2_dev.ctrl_handler = &vi->ctrl_handler;
243 ret = v4l2_ctrl_handler_setup(&vi->ctrl_handler);
245 dev_err(vi->dev, "failed to set controls\n");
252 v4l2_ctrl_handler_free(&vi->ctrl_handler);
253 v4l2_device_unregister(&vi->v4l2_dev);
256 media_device_unregister(&vi->media_dev);
260 static int vi_get_clks(struct tegra_mc_vi *vi, struct platform_device *pdev)
264 vi->clk = devm_clk_get(&pdev->dev, "vi_v4l2");
265 if (IS_ERR(vi->clk)) {
266 dev_err(&pdev->dev, "Failed to get vi clock\n");
267 return PTR_ERR(vi->clk);
273 static int vi_parse_dt(struct tegra_mc_vi *vi, struct platform_device *dev)
276 int num_channels = 0;
277 struct device_node *node = dev->dev.of_node;
279 err = of_property_read_u32(node, "num-channels", &num_channels);
282 "Failed to find num of channels, set TPG mode\n");
283 vi->pg_mode = TEGRA_VI_PG_PATCH;
286 vi->num_channels = num_channels;
287 vi->chans = devm_kzalloc(&dev->dev,
288 (sizeof(struct tegra_channel) * num_channels),
296 static void set_vi_register_base(struct tegra_mc_vi *mc_vi,
297 void __iomem *regbase)
299 mc_vi->iomem = regbase;
302 int tegra_vi_media_controller_init(struct tegra_mc_vi *mc_vi,
303 struct platform_device *pdev)
306 struct nvhost_device_data *pdata = pdev->dev.platform_data;
308 set_vi_register_base(mc_vi, pdata->aperture[0]);
310 err = vi_get_clks(mc_vi, pdev);
314 if (mc_vi->pg_mode) {
315 mc_vi->chans = devm_kzalloc(&pdev->dev,
316 sizeof(struct tegra_channel) *
322 err = vi_parse_dt(mc_vi, pdev);
328 mc_vi->dev = &pdev->dev;
329 INIT_LIST_HEAD(&mc_vi->entities);
331 err = tegra_vi_v4l2_init(mc_vi);
335 /* Init Tegra VI channels */
336 err = tegra_vi_channels_init(mc_vi);
340 /* Setup media links between VI and external sensor subdev. */
342 err = tegra_vi_tpg_graph_init(mc_vi);
344 err = tegra_vi_graph_init(mc_vi);
351 tegra_vi_channels_cleanup(mc_vi);
353 tegra_vi_v4l2_cleanup(mc_vi);
355 dev_err(&pdev->dev, "%s: failed\n", __func__);
358 EXPORT_SYMBOL(tegra_vi_media_controller_init);
360 void tegra_vi_media_controller_cleanup(struct tegra_mc_vi *mc_vi)
362 tegra_vi_graph_cleanup(mc_vi);
363 tegra_vi_channels_cleanup(mc_vi);
364 tegra_vi_v4l2_cleanup(mc_vi);
366 EXPORT_SYMBOL(tegra_vi_media_controller_cleanup);