OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [v4l2-int-device.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * drivers/media/video/v4l2-int-device.c
3
 *
4
 * V4L2 internal ioctl interface.
5
 *
6
 * Copyright (C) 2007 Nokia Corporation.
7
 *
8
 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
9
 *
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU General Public License
12
 * version 2 as published by the Free Software Foundation.
13
 *
14
 * This program is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22
 * 02110-1301 USA
23
 */
24
 
25
#include <linux/kernel.h>
26
#include <linux/list.h>
27
#include <linux/sort.h>
28
#include <linux/string.h>
29
 
30
#include <media/v4l2-int-device.h>
31
 
32
static DEFINE_MUTEX(mutex);
33
static LIST_HEAD(int_list);
34
 
35
static void v4l2_int_device_try_attach_all(void)
36
{
37
        struct v4l2_int_device *m, *s;
38
 
39
        list_for_each_entry(m, &int_list, head) {
40
                if (m->type != v4l2_int_type_master)
41
                        continue;
42
 
43
                list_for_each_entry(s, &int_list, head) {
44
                        if (s->type != v4l2_int_type_slave)
45
                                continue;
46
 
47
                        /* Slave is connected? */
48
                        if (s->u.slave->master)
49
                                continue;
50
 
51
                        /* Slave wants to attach to master? */
52
                        if (s->u.slave->attach_to[0] != 0
53
                            && strncmp(m->name, s->u.slave->attach_to,
54
                                       V4L2NAMESIZE))
55
                                continue;
56
 
57
                        if (!try_module_get(m->module))
58
                                continue;
59
 
60
                        if (m->u.master->attach(m, s)) {
61
                                module_put(m->module);
62
                                continue;
63
                        }
64
 
65
                        s->u.slave->master = m;
66
                }
67
        }
68
}
69
 
70
static int ioctl_sort_cmp(const void *a, const void *b)
71
{
72
        const struct v4l2_int_ioctl_desc *d1 = a, *d2 = b;
73
 
74
        if (d1->num > d2->num)
75
                return 1;
76
 
77
        if (d1->num < d2->num)
78
                return -1;
79
 
80
        return 0;
81
}
82
 
83
int v4l2_int_device_register(struct v4l2_int_device *d)
84
{
85
        if (d->type == v4l2_int_type_slave)
86
                sort(d->u.slave->ioctls, d->u.slave->num_ioctls,
87
                     sizeof(struct v4l2_int_ioctl_desc),
88
                     &ioctl_sort_cmp, NULL);
89
        mutex_lock(&mutex);
90
        list_add(&d->head, &int_list);
91
        v4l2_int_device_try_attach_all();
92
        mutex_unlock(&mutex);
93
 
94
        return 0;
95
}
96
EXPORT_SYMBOL_GPL(v4l2_int_device_register);
97
 
98
void v4l2_int_device_unregister(struct v4l2_int_device *d)
99
{
100
        mutex_lock(&mutex);
101
        list_del(&d->head);
102
        if (d->type == v4l2_int_type_slave
103
            && d->u.slave->master != NULL) {
104
                d->u.slave->master->u.master->detach(d);
105
                module_put(d->u.slave->master->module);
106
                d->u.slave->master = NULL;
107
        }
108
        mutex_unlock(&mutex);
109
}
110
EXPORT_SYMBOL_GPL(v4l2_int_device_unregister);
111
 
112
/* Adapted from search_extable in extable.c. */
113
static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd,
114
                                       v4l2_int_ioctl_func *no_such_ioctl)
115
{
116
        const struct v4l2_int_ioctl_desc *first = slave->ioctls;
117
        const struct v4l2_int_ioctl_desc *last =
118
                first + slave->num_ioctls - 1;
119
 
120
        while (first <= last) {
121
                const struct v4l2_int_ioctl_desc *mid;
122
 
123
                mid = (last - first) / 2 + first;
124
 
125
                if (mid->num < cmd)
126
                        first = mid + 1;
127
                else if (mid->num > cmd)
128
                        last = mid - 1;
129
                else
130
                        return mid->func;
131
        }
132
 
133
        return no_such_ioctl;
134
}
135
 
136
static int no_such_ioctl_0(struct v4l2_int_device *d)
137
{
138
        return -ENOIOCTLCMD;
139
}
140
 
141
int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd)
142
{
143
        return ((v4l2_int_ioctl_func_0 *)
144
                find_ioctl(d->u.slave, cmd,
145
                           (v4l2_int_ioctl_func *)no_such_ioctl_0))(d);
146
}
147
 
148
static int no_such_ioctl_1(struct v4l2_int_device *d, void *arg)
149
{
150
        return -ENOIOCTLCMD;
151
}
152
 
153
int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg)
154
{
155
        return ((v4l2_int_ioctl_func_1 *)
156
                find_ioctl(d->u.slave, cmd,
157
                           (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg);
158
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.