1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2021 Intel Corporation */
4 #include <linux/module.h>
5 #include <linux/mutex.h>
6 #include <linux/sched.h>
8 #include <linux/wait.h>
10 #include "intel_vsc.h"
12 #define ACE_PRIVACY_ON 2
18 struct vsc_csi_ops
*csi_ops
;
19 uint16_t csi_registerred
;
20 wait_queue_head_t csi_waitq
;
23 struct vsc_ace_ops
*ace_ops
;
24 uint16_t ace_registerred
;
25 wait_queue_head_t ace_waitq
;
28 static struct intel_vsc vsc
;
30 static int wait_component_ready(void)
34 ret
= wait_event_interruptible(vsc
.ace_waitq
,
37 pr_err("wait ace register failed\n");
41 ret
= wait_event_interruptible(vsc
.csi_waitq
,
44 pr_err("wait csi register failed\n");
51 static void update_camera_status(struct vsc_camera_status
*status
,
52 struct camera_status
*s
)
55 status
->owner
= s
->camera_owner
;
56 status
->exposure_level
= s
->exposure_level
;
57 status
->status
= VSC_PRIVACY_OFF
;
59 if (s
->privacy_stat
== ACE_PRIVACY_ON
)
60 status
->status
= VSC_PRIVACY_ON
;
64 int vsc_register_ace(void *ace
, struct vsc_ace_ops
*ops
)
67 if (ops
->ipu_own_camera
&& ops
->ace_own_camera
) {
68 mutex_lock(&vsc
.mutex
);
71 vsc
.ace_registerred
= true;
72 mutex_unlock(&vsc
.mutex
);
74 wake_up_interruptible_all(&vsc
.ace_waitq
);
78 pr_err("register ace failed\n");
81 EXPORT_SYMBOL_GPL(vsc_register_ace
);
83 void vsc_unregister_ace(void)
85 mutex_lock(&vsc
.mutex
);
86 vsc
.ace_registerred
= false;
87 mutex_unlock(&vsc
.mutex
);
89 EXPORT_SYMBOL_GPL(vsc_unregister_ace
);
91 int vsc_register_csi(void *csi
, struct vsc_csi_ops
*ops
)
94 if (ops
->set_privacy_callback
&&
95 ops
->set_owner
&& ops
->set_mipi_conf
) {
96 mutex_lock(&vsc
.mutex
);
99 vsc
.csi_registerred
= true;
100 mutex_unlock(&vsc
.mutex
);
102 wake_up_interruptible_all(&vsc
.csi_waitq
);
106 pr_err("register csi failed\n");
109 EXPORT_SYMBOL_GPL(vsc_register_csi
);
111 void vsc_unregister_csi(void)
113 mutex_lock(&vsc
.mutex
);
114 vsc
.csi_registerred
= false;
115 mutex_unlock(&vsc
.mutex
);
117 EXPORT_SYMBOL_GPL(vsc_unregister_csi
);
119 int vsc_acquire_camera_sensor(struct vsc_mipi_config
*config
,
120 vsc_privacy_callback_t callback
,
122 struct vsc_camera_status
*status
)
125 struct camera_status s
;
126 struct mipi_conf conf
= { 0 };
128 struct vsc_csi_ops
*csi_ops
;
129 struct vsc_ace_ops
*ace_ops
;
134 ret
= wait_component_ready();
138 mutex_lock(&vsc
.mutex
);
139 if (!vsc
.csi_registerred
|| !vsc
.ace_registerred
) {
144 csi_ops
= vsc
.csi_ops
;
145 ace_ops
= vsc
.ace_ops
;
147 csi_ops
->set_privacy_callback(vsc
.csi
, callback
, handle
);
149 ret
= ace_ops
->ipu_own_camera(vsc
.ace
, &s
);
151 pr_err("ipu own camera failed\n");
154 update_camera_status(status
, &s
);
156 ret
= csi_ops
->set_owner(vsc
.csi
, CSI_IPU
);
158 pr_err("ipu own csi failed\n");
162 conf
.lane_num
= config
->lane_num
;
163 conf
.freq
= config
->freq
;
164 ret
= csi_ops
->set_mipi_conf(vsc
.csi
, &conf
);
166 pr_err("config mipi failed\n");
171 mutex_unlock(&vsc
.mutex
);
174 EXPORT_SYMBOL_GPL(vsc_acquire_camera_sensor
);
176 int vsc_release_camera_sensor(struct vsc_camera_status
*status
)
179 struct camera_status s
;
181 struct vsc_csi_ops
*csi_ops
;
182 struct vsc_ace_ops
*ace_ops
;
184 ret
= wait_component_ready();
188 mutex_lock(&vsc
.mutex
);
189 if (!vsc
.csi_registerred
|| !vsc
.ace_registerred
) {
194 csi_ops
= vsc
.csi_ops
;
195 ace_ops
= vsc
.ace_ops
;
197 csi_ops
->set_privacy_callback(vsc
.csi
, NULL
, NULL
);
199 ret
= csi_ops
->set_owner(vsc
.csi
, CSI_FW
);
201 pr_err("vsc own csi failed\n");
205 ret
= ace_ops
->ace_own_camera(vsc
.ace
, &s
);
207 pr_err("vsc own camera failed\n");
210 update_camera_status(status
, &s
);
213 mutex_unlock(&vsc
.mutex
);
216 EXPORT_SYMBOL_GPL(vsc_release_camera_sensor
);
218 static int __init
intel_vsc_init(void)
220 memset(&vsc
, 0, sizeof(struct intel_vsc
));
222 mutex_init(&vsc
.mutex
);
224 vsc
.csi_registerred
= false;
225 vsc
.ace_registerred
= false;
227 init_waitqueue_head(&vsc
.ace_waitq
);
228 init_waitqueue_head(&vsc
.csi_waitq
);
233 static void __exit
intel_vsc_exit(void)
235 if (wq_has_sleeper(&vsc
.ace_waitq
))
236 wake_up_all(&vsc
.ace_waitq
);
238 if (wq_has_sleeper(&vsc
.csi_waitq
))
239 wake_up_all(&vsc
.csi_waitq
);
242 module_init(intel_vsc_init
);
243 module_exit(intel_vsc_exit
);
245 MODULE_AUTHOR("Intel Corporation");
246 MODULE_LICENSE("GPL v2");
247 MODULE_DESCRIPTION("Device driver for Intel VSC");