Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
uio
uio_aec.c
Go to the documentation of this file.
1
/*
2
* uio_aec.c -- simple driver for Adrienne Electronics Corp time code PCI device
3
*
4
* Copyright (C) 2008 Brandon Philips <
[email protected]
>
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 as published
8
* by the Free Software Foundation.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License along
16
* with this program; if not, write to the Free Software Foundation, Inc., 59
17
* Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18
*/
19
20
#include <linux/kernel.h>
21
#include <linux/module.h>
22
#include <linux/pci.h>
23
#include <
linux/init.h
>
24
#include <
linux/interrupt.h
>
25
#include <
linux/cdev.h
>
26
#include <linux/fs.h>
27
#include <
linux/io.h
>
28
#include <
linux/uaccess.h
>
29
#include <
linux/uio_driver.h
>
30
#include <linux/slab.h>
31
32
#define PCI_VENDOR_ID_AEC 0xaecb
33
#define PCI_DEVICE_ID_AEC_VITCLTC 0x6250
34
35
#define INT_ENABLE_ADDR 0xFC
36
#define INT_ENABLE 0x10
37
#define INT_DISABLE 0x0
38
39
#define INT_MASK_ADDR 0x2E
40
#define INT_MASK_ALL 0x3F
41
42
#define INTA_DRVR_ADDR 0xFE
43
#define INTA_ENABLED_FLAG 0x08
44
#define INTA_FLAG 0x01
45
46
#define MAILBOX 0x0F
47
48
static
struct
pci_device_id
ids[] = {
49
{
PCI_DEVICE
(
PCI_VENDOR_ID_AEC
,
PCI_DEVICE_ID_AEC_VITCLTC
), },
50
{ 0, }
51
};
52
MODULE_DEVICE_TABLE
(pci, ids);
53
54
static
irqreturn_t
aectc_irq(
int
irq,
struct
uio_info
*
dev_info
)
55
{
56
void
__iomem
*int_flag = dev_info->
priv
+
INTA_DRVR_ADDR
;
57
unsigned
char
status
=
ioread8
(int_flag);
58
59
60
if
((status &
INTA_ENABLED_FLAG
) && (status &
INTA_FLAG
)) {
61
/* application writes 0x00 to 0x2F to get next interrupt */
62
status =
ioread8
(dev_info->
priv
+
MAILBOX
);
63
return
IRQ_HANDLED
;
64
}
65
66
return
IRQ_NONE
;
67
}
68
69
static
void
print_board_data(
struct
pci_dev
*pdev,
struct
uio_info
*
i
)
70
{
71
dev_info
(&pdev->
dev
,
"PCI-TC board vendor: %x%x number: %x%x"
72
" revision: %c%c\n"
,
73
ioread8
(i->
priv
+ 0x01),
74
ioread8
(i->
priv
+ 0x00),
75
ioread8
(i->
priv
+ 0x03),
76
ioread8
(i->
priv
+ 0x02),
77
ioread8
(i->
priv
+ 0x06),
78
ioread8
(i->
priv
+ 0x07));
79
}
80
81
static
int
__devinit
probe(
struct
pci_dev
*pdev,
const
struct
pci_device_id
*
id
)
82
{
83
struct
uio_info
*
info
;
84
int
ret
;
85
86
info = kzalloc(
sizeof
(
struct
uio_info
),
GFP_KERNEL
);
87
if
(!info)
88
return
-
ENOMEM
;
89
90
if
(
pci_enable_device
(pdev))
91
goto
out_free;
92
93
if
(
pci_request_regions
(pdev,
"aectc"
))
94
goto
out_disable;
95
96
info->
name
=
"aectc"
;
97
info->
port
[0].start =
pci_resource_start
(pdev, 0);
98
if
(!info->
port
[0].start)
99
goto
out_release;
100
info->
priv
= pci_iomap(pdev, 0, 0);
101
if
(!info->
priv
)
102
goto
out_release;
103
info->
port
[0].size =
pci_resource_len
(pdev, 0);
104
info->
port
[0].porttype =
UIO_PORT_GPIO
;
105
106
info->
version
=
"0.0.1"
;
107
info->
irq
= pdev->
irq
;
108
info->
irq_flags
=
IRQF_SHARED
;
109
info->
handler
= aectc_irq;
110
111
print_board_data(pdev, info);
112
ret =
uio_register_device
(&pdev->
dev
, info);
113
if
(ret)
114
goto
out_unmap;
115
116
iowrite32
(
INT_ENABLE
, info->
priv
+
INT_ENABLE_ADDR
);
117
iowrite8
(
INT_MASK_ALL
, info->
priv
+
INT_MASK_ADDR
);
118
if
(!(
ioread8
(info->
priv
+
INTA_DRVR_ADDR
)
119
& INTA_ENABLED_FLAG))
120
dev_err
(&pdev->
dev
,
"aectc: interrupts not enabled\n"
);
121
122
pci_set_drvdata(pdev, info);
123
124
return
0;
125
126
out_unmap:
127
pci_iounmap
(pdev, info->
priv
);
128
out_release:
129
pci_release_regions
(pdev);
130
out_disable:
131
pci_disable_device
(pdev);
132
out_free:
133
kfree
(info);
134
return
-
ENODEV
;
135
}
136
137
static
void
remove
(
struct
pci_dev
*pdev)
138
{
139
struct
uio_info
*info = pci_get_drvdata(pdev);
140
141
/* disable interrupts */
142
iowrite8
(
INT_DISABLE
, info->
priv
+
INT_MASK_ADDR
);
143
iowrite32
(
INT_DISABLE
, info->
priv
+
INT_ENABLE_ADDR
);
144
/* read mailbox to ensure board drops irq */
145
ioread8
(info->
priv
+
MAILBOX
);
146
147
uio_unregister_device
(info);
148
pci_release_regions
(pdev);
149
pci_disable_device
(pdev);
150
pci_set_drvdata(pdev,
NULL
);
151
iounmap
(info->
priv
);
152
153
kfree
(info);
154
}
155
156
static
struct
pci_driver
pci_driver
= {
157
.
name
=
"aectc"
,
158
.id_table = ids,
159
.probe =
probe
,
160
.remove =
remove
,
161
};
162
163
static
int
__init
aectc_init(
void
)
164
{
165
return
pci_register_driver(&pci_driver);
166
}
167
168
static
void
__exit
aectc_exit(
void
)
169
{
170
pci_unregister_driver
(&pci_driver);
171
}
172
173
MODULE_LICENSE
(
"GPL"
);
174
175
module_init
(aectc_init);
176
module_exit
(aectc_exit);
Generated on Thu Jan 10 2013 14:35:22 for Linux Kernel by
1.8.2