1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Support for Medifield PNW Camera Imaging ISP subsystem.
4 *
5 * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
6 *
7 * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 *
19 */
20
21#include <media/v4l2-event.h>
22#include <media/v4l2-mediabus.h>
23#include "atomisp_internal.h"
24#include "atomisp_tpg.h"
25
26static int tpg_s_stream(struct v4l2_subdev *sd, int enable)
27{
28	return 0;
29}
30
31static int tpg_get_fmt(struct v4l2_subdev *sd,
32		       struct v4l2_subdev_state *sd_state,
33		       struct v4l2_subdev_format *format)
34{
35	/*to fake*/
36	return 0;
37}
38
39static int tpg_set_fmt(struct v4l2_subdev *sd,
40		       struct v4l2_subdev_state *sd_state,
41		       struct v4l2_subdev_format *format)
42{
43	struct v4l2_mbus_framefmt *fmt = &format->format;
44
45	if (format->pad)
46		return -EINVAL;
47	/* only raw8 grbg is supported by TPG */
48	fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
49	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
50		*v4l2_subdev_state_get_format(sd_state, 0) = *fmt;
51		return 0;
52	}
53	return 0;
54}
55
56static int tpg_log_status(struct v4l2_subdev *sd)
57{
58	/*to fake*/
59	return 0;
60}
61
62static int tpg_s_power(struct v4l2_subdev *sd, int on)
63{
64	return 0;
65}
66
67static int tpg_enum_mbus_code(struct v4l2_subdev *sd,
68			      struct v4l2_subdev_state *sd_state,
69			      struct v4l2_subdev_mbus_code_enum *code)
70{
71	/*to fake*/
72	return 0;
73}
74
75static int tpg_enum_frame_size(struct v4l2_subdev *sd,
76			       struct v4l2_subdev_state *sd_state,
77			       struct v4l2_subdev_frame_size_enum *fse)
78{
79	/*to fake*/
80	return 0;
81}
82
83static int tpg_enum_frame_ival(struct v4l2_subdev *sd,
84			       struct v4l2_subdev_state *sd_state,
85			       struct v4l2_subdev_frame_interval_enum *fie)
86{
87	/*to fake*/
88	return 0;
89}
90
91static const struct v4l2_subdev_video_ops tpg_video_ops = {
92	.s_stream = tpg_s_stream,
93};
94
95static const struct v4l2_subdev_core_ops tpg_core_ops = {
96	.log_status = tpg_log_status,
97	.s_power = tpg_s_power,
98};
99
100static const struct v4l2_subdev_pad_ops tpg_pad_ops = {
101	.enum_mbus_code = tpg_enum_mbus_code,
102	.enum_frame_size = tpg_enum_frame_size,
103	.enum_frame_interval = tpg_enum_frame_ival,
104	.get_fmt = tpg_get_fmt,
105	.set_fmt = tpg_set_fmt,
106};
107
108static const struct v4l2_subdev_ops tpg_ops = {
109	.core = &tpg_core_ops,
110	.video = &tpg_video_ops,
111	.pad = &tpg_pad_ops,
112};
113
114void atomisp_tpg_unregister_entities(struct atomisp_tpg_device *tpg)
115{
116	media_entity_cleanup(&tpg->sd.entity);
117	v4l2_device_unregister_subdev(&tpg->sd);
118}
119
120int atomisp_tpg_register_entities(struct atomisp_tpg_device *tpg,
121				  struct v4l2_device *vdev)
122{
123	int ret;
124	/* Register the subdev and video nodes. */
125	ret = v4l2_device_register_subdev(vdev, &tpg->sd);
126	if (ret < 0)
127		goto error;
128
129	return 0;
130
131error:
132	atomisp_tpg_unregister_entities(tpg);
133	return ret;
134}
135
136void atomisp_tpg_cleanup(struct atomisp_device *isp)
137{
138}
139
140int atomisp_tpg_init(struct atomisp_device *isp)
141{
142	struct atomisp_tpg_device *tpg = &isp->tpg;
143	struct v4l2_subdev *sd = &tpg->sd;
144	struct media_pad *pads = tpg->pads;
145	struct media_entity *me = &sd->entity;
146	int ret;
147
148	tpg->isp = isp;
149	v4l2_subdev_init(sd, &tpg_ops);
150	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
151	strscpy(sd->name, "tpg_subdev", sizeof(sd->name));
152	v4l2_set_subdevdata(sd, tpg);
153
154	pads[0].flags = MEDIA_PAD_FL_SINK;
155	me->function = MEDIA_ENT_F_PROC_VIDEO_ISP;
156
157	ret = media_entity_pads_init(me, 1, pads);
158	if (ret < 0)
159		goto fail;
160	return 0;
161fail:
162	atomisp_tpg_cleanup(isp);
163	return ret;
164}
165