blob: 4c29ffd6e8a12ce1afb8cd2e3121e0e96dc1b0ca [file] [log] [blame]
Pavan Kumar Chilamkurthi5719f212017-07-20 15:02:21 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15
16#include "cam_debug_util.h"
17#include "cam_fd_context.h"
18
19/* Functions in Available state */
20static int __cam_fd_ctx_acquire_dev_in_available(struct cam_context *ctx,
21 struct cam_acquire_dev_cmd *cmd)
22{
23 int rc;
24
25 rc = cam_context_acquire_dev_to_hw(ctx, cmd);
26 if (rc) {
27 CAM_ERR(CAM_FD, "Failed in Acquire dev, rc=%d", rc);
28 return rc;
29 }
30
31 ctx->state = CAM_CTX_ACQUIRED;
32
33 return rc;
34}
35
36/* Functions in Acquired state */
37static int __cam_fd_ctx_release_dev_in_acquired(struct cam_context *ctx,
38 struct cam_release_dev_cmd *cmd)
39{
40 int rc;
41
42 rc = cam_context_release_dev_to_hw(ctx, cmd);
43 if (rc) {
44 CAM_ERR(CAM_FD, "Failed in Release dev, rc=%d", rc);
45 return rc;
46 }
47
48 ctx->state = CAM_CTX_AVAILABLE;
49
50 return rc;
51}
52
53static int __cam_fd_ctx_config_dev_in_acquired(struct cam_context *ctx,
54 struct cam_config_dev_cmd *cmd)
55{
56 int rc;
57
58 rc = cam_context_prepare_dev_to_hw(ctx, cmd);
59 if (rc) {
60 CAM_ERR(CAM_FD, "Failed in Prepare dev, rc=%d", rc);
61 return rc;
62 }
63
64 return rc;
65}
66
67static int __cam_fd_ctx_start_dev_in_acquired(struct cam_context *ctx,
68 struct cam_start_stop_dev_cmd *cmd)
69{
70 int rc;
71
72 rc = cam_context_start_dev_to_hw(ctx, cmd);
73 if (rc) {
74 CAM_ERR(CAM_FD, "Failed in Start dev, rc=%d", rc);
75 return rc;
76 }
77
78 ctx->state = CAM_CTX_ACTIVATED;
79
80 return rc;
81}
82
83/* Functions in Activated state */
84static int __cam_fd_ctx_stop_dev_in_activated(struct cam_context *ctx,
85 struct cam_start_stop_dev_cmd *cmd)
86{
87 int rc;
88
89 rc = cam_context_stop_dev_to_hw(ctx);
90 if (rc) {
91 CAM_ERR(CAM_FD, "Failed in Stop dev, rc=%d", rc);
92 return rc;
93 }
94
95 ctx->state = CAM_CTX_ACQUIRED;
96
97 return rc;
98}
99
100static int __cam_fd_ctx_release_dev_in_activated(struct cam_context *ctx,
101 struct cam_release_dev_cmd *cmd)
102{
103 int rc;
104
105 rc = __cam_fd_ctx_stop_dev_in_activated(ctx, NULL);
106 if (rc) {
107 CAM_ERR(CAM_FD, "Failed in Stop dev, rc=%d", rc);
108 return rc;
109 }
110
111 rc = __cam_fd_ctx_release_dev_in_acquired(ctx, cmd);
112 if (rc) {
113 CAM_ERR(CAM_FD, "Failed in Release dev, rc=%d", rc);
114 return rc;
115 }
116
117 return rc;
118}
119
120static int __cam_fd_ctx_config_dev_in_activated(
121 struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
122{
123 int rc;
124
125 rc = cam_context_prepare_dev_to_hw(ctx, cmd);
126 if (rc) {
127 CAM_ERR(CAM_FD, "Failed in Prepare dev, rc=%d", rc);
128 return rc;
129 }
130
131 return rc;
132}
133
134static int __cam_fd_ctx_handle_irq_in_activated(void *context,
135 uint32_t evt_id, void *evt_data)
136{
137 int rc;
138
139 rc = cam_context_buf_done_from_hw(context, evt_data, evt_id);
140 if (rc) {
141 CAM_ERR(CAM_FD, "Failed in buf done, rc=%d", rc);
142 return rc;
143 }
144
145 return rc;
146}
147
148/* top state machine */
149static struct cam_ctx_ops
150 cam_fd_ctx_state_machine[CAM_CTX_STATE_MAX] = {
151 /* Uninit */
152 {
153 .ioctl_ops = {},
154 .crm_ops = {},
155 .irq_ops = NULL,
156 },
157 /* Available */
158 {
159 .ioctl_ops = {
160 .acquire_dev = __cam_fd_ctx_acquire_dev_in_available,
161 },
162 .crm_ops = {},
163 .irq_ops = NULL,
164 },
165 /* Acquired */
166 {
167 .ioctl_ops = {
168 .release_dev = __cam_fd_ctx_release_dev_in_acquired,
169 .config_dev = __cam_fd_ctx_config_dev_in_acquired,
170 .start_dev = __cam_fd_ctx_start_dev_in_acquired,
171 },
172 .crm_ops = {},
173 .irq_ops = NULL,
174 },
175 /* Ready */
176 {
177 .ioctl_ops = { },
178 .crm_ops = {},
179 .irq_ops = NULL,
180 },
181 /* Activated */
182 {
183 .ioctl_ops = {
184 .stop_dev = __cam_fd_ctx_stop_dev_in_activated,
185 .release_dev = __cam_fd_ctx_release_dev_in_activated,
186 .config_dev = __cam_fd_ctx_config_dev_in_activated,
187 },
188 .crm_ops = {},
189 .irq_ops = __cam_fd_ctx_handle_irq_in_activated,
190 },
191};
192
193
194int cam_fd_context_init(struct cam_fd_context *fd_ctx,
195 struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf)
196{
197 int rc;
198
199 if (!base_ctx || !fd_ctx) {
200 CAM_ERR(CAM_FD, "Invalid Context %pK %pK", base_ctx, fd_ctx);
201 return -EINVAL;
202 }
203
204 memset(fd_ctx, 0, sizeof(*fd_ctx));
205
206 rc = cam_context_init(base_ctx, NULL, hw_intf, fd_ctx->req_base,
207 CAM_CTX_REQ_MAX);
208 if (rc) {
209 CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc);
210 return rc;
211 }
212
213 fd_ctx->base = base_ctx;
214 base_ctx->ctx_priv = fd_ctx;
215 base_ctx->state_machine = cam_fd_ctx_state_machine;
216
217 return rc;
218}
219
220int cam_fd_context_deinit(struct cam_fd_context *fd_ctx)
221{
222 int rc = 0;
223
224 if (!fd_ctx || !fd_ctx->base) {
225 CAM_ERR(CAM_FD, "Invalid inputs %pK", fd_ctx);
226 return -EINVAL;
227 }
228
229 rc = cam_context_deinit(fd_ctx->base);
230 if (rc)
231 CAM_ERR(CAM_FD, "Error in base deinit, rc=%d", rc);
232
233 memset(fd_ctx, 0, sizeof(*fd_ctx));
234
235 return rc;
236}