Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/bt8xx/bttv-gpio.c
10785 views
1
/*
2
3
bttv-gpio.c -- gpio sub drivers
4
5
sysfs-based sub driver interface for bttv
6
mainly intended for gpio access
7
8
9
Copyright (C) 1996,97,98 Ralph Metzler ([email protected])
10
& Marcus Metzler ([email protected])
11
(c) 1999-2003 Gerd Knorr <[email protected]>
12
13
This program is free software; you can redistribute it and/or modify
14
it under the terms of the GNU General Public License as published by
15
the Free Software Foundation; either version 2 of the License, or
16
(at your option) any later version.
17
18
This program is distributed in the hope that it will be useful,
19
but WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
GNU General Public License for more details.
22
23
You should have received a copy of the GNU General Public License
24
along with this program; if not, write to the Free Software
25
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27
*/
28
29
#include <linux/module.h>
30
#include <linux/init.h>
31
#include <linux/delay.h>
32
#include <linux/device.h>
33
#include <linux/slab.h>
34
#include <asm/io.h>
35
36
#include "bttvp.h"
37
38
/* ----------------------------------------------------------------------- */
39
/* internal: the bttv "bus" */
40
41
static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
42
{
43
struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
44
int len = strlen(sub->wanted);
45
46
if (0 == strncmp(dev_name(dev), sub->wanted, len))
47
return 1;
48
return 0;
49
}
50
51
static int bttv_sub_probe(struct device *dev)
52
{
53
struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
54
struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
55
56
return sub->probe ? sub->probe(sdev) : -ENODEV;
57
}
58
59
static int bttv_sub_remove(struct device *dev)
60
{
61
struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
62
struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
63
64
if (sub->remove)
65
sub->remove(sdev);
66
return 0;
67
}
68
69
struct bus_type bttv_sub_bus_type = {
70
.name = "bttv-sub",
71
.match = &bttv_sub_bus_match,
72
.probe = bttv_sub_probe,
73
.remove = bttv_sub_remove,
74
};
75
76
static void release_sub_device(struct device *dev)
77
{
78
struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
79
kfree(sub);
80
}
81
82
int bttv_sub_add_device(struct bttv_core *core, char *name)
83
{
84
struct bttv_sub_device *sub;
85
int err;
86
87
sub = kzalloc(sizeof(*sub),GFP_KERNEL);
88
if (NULL == sub)
89
return -ENOMEM;
90
91
sub->core = core;
92
sub->dev.parent = &core->pci->dev;
93
sub->dev.bus = &bttv_sub_bus_type;
94
sub->dev.release = release_sub_device;
95
dev_set_name(&sub->dev, "%s%d", name, core->nr);
96
97
err = device_register(&sub->dev);
98
if (0 != err) {
99
kfree(sub);
100
return err;
101
}
102
printk("bttv%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev));
103
list_add_tail(&sub->list,&core->subs);
104
return 0;
105
}
106
107
int bttv_sub_del_devices(struct bttv_core *core)
108
{
109
struct bttv_sub_device *sub, *save;
110
111
list_for_each_entry_safe(sub, save, &core->subs, list) {
112
list_del(&sub->list);
113
device_unregister(&sub->dev);
114
}
115
return 0;
116
}
117
118
/* ----------------------------------------------------------------------- */
119
/* external: sub-driver register/unregister */
120
121
int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
122
{
123
sub->drv.bus = &bttv_sub_bus_type;
124
snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
125
return driver_register(&sub->drv);
126
}
127
EXPORT_SYMBOL(bttv_sub_register);
128
129
int bttv_sub_unregister(struct bttv_sub_driver *sub)
130
{
131
driver_unregister(&sub->drv);
132
return 0;
133
}
134
EXPORT_SYMBOL(bttv_sub_unregister);
135
136
/* ----------------------------------------------------------------------- */
137
/* external: gpio access functions */
138
139
void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
140
{
141
struct bttv *btv = container_of(core, struct bttv, c);
142
unsigned long flags;
143
u32 data;
144
145
spin_lock_irqsave(&btv->gpio_lock,flags);
146
data = btread(BT848_GPIO_OUT_EN);
147
data = data & ~mask;
148
data = data | (mask & outbits);
149
btwrite(data,BT848_GPIO_OUT_EN);
150
spin_unlock_irqrestore(&btv->gpio_lock,flags);
151
}
152
153
u32 bttv_gpio_read(struct bttv_core *core)
154
{
155
struct bttv *btv = container_of(core, struct bttv, c);
156
u32 value;
157
158
value = btread(BT848_GPIO_DATA);
159
return value;
160
}
161
162
void bttv_gpio_write(struct bttv_core *core, u32 value)
163
{
164
struct bttv *btv = container_of(core, struct bttv, c);
165
166
btwrite(value,BT848_GPIO_DATA);
167
}
168
169
void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
170
{
171
struct bttv *btv = container_of(core, struct bttv, c);
172
unsigned long flags;
173
u32 data;
174
175
spin_lock_irqsave(&btv->gpio_lock,flags);
176
data = btread(BT848_GPIO_DATA);
177
data = data & ~mask;
178
data = data | (mask & bits);
179
btwrite(data,BT848_GPIO_DATA);
180
spin_unlock_irqrestore(&btv->gpio_lock,flags);
181
}
182
183
/*
184
* Local variables:
185
* c-basic-offset: 8
186
* End:
187
*/
188
189