1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * VIDEO MOTION CODECs internal API for video devices
5 * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
6 * bound to a master device.
8 * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/types.h>
15 #include <linux/slab.h>
17 #include "videocodec.h"
19 struct attached_list
{
20 struct videocodec
*codec
;
21 struct attached_list
*next
;
25 const struct videocodec
*codec
;
27 struct attached_list
*list
;
28 struct codec_list
*next
;
31 static struct codec_list
*codeclist_top
;
33 /* ================================================= */
34 /* function prototypes of the master/slave interface */
35 /* ================================================= */
37 struct videocodec
*videocodec_attach(struct videocodec_master
*master
)
39 struct codec_list
*h
= codeclist_top
;
41 struct attached_list
*a
, *ptr
;
42 struct videocodec
*codec
;
46 pr_err("%s: no data\n", __func__
);
50 zr
= videocodec_master_to_zoran(master
);
52 zrdev_dbg(zr
, "%s: '%s', flags %lx, magic %lx\n", __func__
,
53 master
->name
, master
->flags
, master
->magic
);
56 zrdev_err(zr
, "%s: no device available\n", __func__
);
61 // attach only if the slave has at least the flags
62 // expected by the master
63 if ((master
->flags
& h
->codec
->flags
) == master
->flags
) {
64 zrdev_dbg(zr
, "%s: try '%s'\n", __func__
, h
->codec
->name
);
66 codec
= kmemdup(h
->codec
, sizeof(struct videocodec
), GFP_KERNEL
);
70 res
= strlen(codec
->name
);
71 snprintf(codec
->name
+ res
, sizeof(codec
->name
) - res
, "[%d]", h
->attached
);
72 codec
->master_data
= master
;
73 res
= codec
->setup(codec
);
75 zrdev_dbg(zr
, "%s: '%s'\n", __func__
, codec
->name
);
76 ptr
= kzalloc(sizeof(*ptr
), GFP_KERNEL
);
84 zrdev_dbg(zr
, "videocodec: first element\n");
87 a
= a
->next
; // find end
89 zrdev_dbg(zr
, "videocodec: in after '%s'\n",
101 zrdev_err(zr
, "%s: no codec found!\n", __func__
);
109 int videocodec_detach(struct videocodec
*codec
)
111 struct codec_list
*h
= codeclist_top
;
113 struct attached_list
*a
, *prev
;
117 pr_err("%s: no data\n", __func__
);
121 zr
= videocodec_to_zoran(codec
);
123 zrdev_dbg(zr
, "%s: '%s', type: %x, flags %lx, magic %lx\n", __func__
,
124 codec
->name
, codec
->type
, codec
->flags
, codec
->magic
);
127 zrdev_err(zr
, "%s: no device left...\n", __func__
);
135 if (codec
== a
->codec
) {
136 res
= a
->codec
->unset(a
->codec
);
138 zrdev_dbg(zr
, "%s: '%s'\n", __func__
,
140 a
->codec
->master_data
= NULL
;
142 zrdev_err(zr
, "%s: '%s'\n", __func__
, a
->codec
->name
);
143 a
->codec
->master_data
= NULL
;
147 zrdev_dbg(zr
, "videocodec: delete first\n");
149 prev
->next
= a
->next
;
150 zrdev_dbg(zr
, "videocodec: delete middle\n");
163 zrdev_err(zr
, "%s: given codec not found!\n", __func__
);
167 int videocodec_register(const struct videocodec
*codec
)
169 struct codec_list
*ptr
, *h
= codeclist_top
;
173 pr_err("%s: no data!\n", __func__
);
177 zr
= videocodec_to_zoran((struct videocodec
*)codec
);
180 "videocodec: register '%s', type: %x, flags %lx, magic %lx\n",
181 codec
->name
, codec
->type
, codec
->flags
, codec
->magic
);
183 ptr
= kzalloc(sizeof(*ptr
), GFP_KERNEL
);
190 zrdev_dbg(zr
, "videocodec: hooked in as first element\n");
193 h
= h
->next
; // find the end
195 zrdev_dbg(zr
, "videocodec: hooked in after '%s'\n",
202 int videocodec_unregister(const struct videocodec
*codec
)
204 struct codec_list
*prev
= NULL
, *h
= codeclist_top
;
208 pr_err("%s: no data!\n", __func__
);
212 zr
= videocodec_to_zoran((struct videocodec
*)codec
);
215 "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n",
216 codec
->name
, codec
->type
, codec
->flags
, codec
->magic
);
219 zrdev_err(zr
, "%s: no device left...\n", __func__
);
224 if (codec
== h
->codec
) {
226 zrdev_err(zr
, "videocodec: '%s' is used\n",
230 zrdev_dbg(zr
, "videocodec: unregister '%s' is ok.\n",
233 codeclist_top
= h
->next
;
235 "videocodec: delete first element\n");
237 prev
->next
= h
->next
;
239 "videocodec: delete middle element\n");
248 zrdev_err(zr
, "%s: given codec not found!\n", __func__
);
252 int videocodec_debugfs_show(struct seq_file
*m
)
254 struct codec_list
*h
= codeclist_top
;
255 struct attached_list
*a
;
257 seq_puts(m
, "<S>lave or attached <M>aster name type flags magic ");
258 seq_puts(m
, "(connected as)\n");
261 seq_printf(m
, "S %32s %04x %08lx %08lx (TEMPLATE)\n",
262 h
->codec
->name
, h
->codec
->type
,
263 h
->codec
->flags
, h
->codec
->magic
);
266 seq_printf(m
, "M %32s %04x %08lx %08lx (%s)\n",
267 a
->codec
->master_data
->name
,
268 a
->codec
->master_data
->type
,
269 a
->codec
->master_data
->flags
,
270 a
->codec
->master_data
->magic
,