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
media
pci
b2c2
flexcop-dma.c
Go to the documentation of this file.
1
/*
2
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3
* flexcop-dma.c - configuring and controlling the DMA of the FlexCop
4
* see flexcop.c for copyright information
5
*/
6
#include "
flexcop.h
"
7
8
int
flexcop_dma_allocate
(
struct
pci_dev
*pdev,
9
struct
flexcop_dma
*
dma
,
u32
size
)
10
{
11
u8
*tcpu;
12
dma_addr_t
tdma = 0;
13
14
if
(size % 2) {
15
err
(
"dma buffersize has to be even."
);
16
return
-
EINVAL
;
17
}
18
19
if
((tcpu =
pci_alloc_consistent
(pdev, size, &tdma)) !=
NULL
) {
20
dma->
pdev
= pdev;
21
dma->
cpu_addr0
= tcpu;
22
dma->
dma_addr0
= tdma;
23
dma->
cpu_addr1
= tcpu + size/2;
24
dma->
dma_addr1
= tdma + size/2;
25
dma->
size
= size/2;
26
return
0;
27
}
28
return
-
ENOMEM
;
29
}
30
EXPORT_SYMBOL
(
flexcop_dma_allocate
);
31
32
void
flexcop_dma_free
(
struct
flexcop_dma
*
dma
)
33
{
34
pci_free_consistent
(dma->
pdev
, dma->
size
*2,
35
dma->
cpu_addr0
, dma->
dma_addr0
);
36
memset
(dma,0,
sizeof
(
struct
flexcop_dma
));
37
}
38
EXPORT_SYMBOL
(
flexcop_dma_free
);
39
40
int
flexcop_dma_config
(
struct
flexcop_device
*
fc
,
41
struct
flexcop_dma
*
dma
,
42
flexcop_dma_index_t
dma_idx)
43
{
44
flexcop_ibi_value
v0x0,v0x4,v0xc;
45
v0x0.
raw
= v0x4.
raw
= v0xc.
raw
= 0;
46
47
v0x0.
dma_0x0
.dma_address0 = dma->
dma_addr0
>> 2;
48
v0xc.
dma_0xc
.dma_address1 = dma->
dma_addr1
>> 2;
49
v0x4.
dma_0x4_write
.dma_addr_size = dma->
size
/ 4;
50
51
if
((dma_idx &
FC_DMA_1
) == dma_idx) {
52
fc->
write_ibi_reg
(fc,
dma1_000
,v0x0);
53
fc->
write_ibi_reg
(fc,
dma1_004
,v0x4);
54
fc->
write_ibi_reg
(fc,
dma1_00c
,v0xc);
55
}
else
if
((dma_idx &
FC_DMA_2
) == dma_idx) {
56
fc->
write_ibi_reg
(fc,
dma2_010
,v0x0);
57
fc->
write_ibi_reg
(fc,
dma2_014
,v0x4);
58
fc->
write_ibi_reg
(fc,
dma2_01c
,v0xc);
59
}
else
{
60
err
(
"either DMA1 or DMA2 can be configured within one "
61
"flexcop_dma_config call."
);
62
return
-
EINVAL
;
63
}
64
65
return
0;
66
}
67
EXPORT_SYMBOL
(
flexcop_dma_config
);
68
69
/* start the DMA transfers, but not the DMA IRQs */
70
int
flexcop_dma_xfer_control
(
struct
flexcop_device
*
fc
,
71
flexcop_dma_index_t
dma_idx,
72
flexcop_dma_addr_index_t
index
,
73
int
onoff
)
74
{
75
flexcop_ibi_value
v0x0,v0xc;
76
flexcop_ibi_register
r0x0,r0xc;
77
78
if
((dma_idx &
FC_DMA_1
) == dma_idx) {
79
r0x0 =
dma1_000
;
80
r0xc =
dma1_00c
;
81
}
else
if
((dma_idx &
FC_DMA_2
) == dma_idx) {
82
r0x0 =
dma2_010
;
83
r0xc =
dma2_01c
;
84
}
else
{
85
err
(
"either transfer DMA1 or DMA2 can be started within one "
86
"flexcop_dma_xfer_control call."
);
87
return
-
EINVAL
;
88
}
89
90
v0x0 = fc->
read_ibi_reg
(fc,r0x0);
91
v0xc = fc->
read_ibi_reg
(fc,r0xc);
92
93
deb_rdump
(
"reg: %03x: %x\n"
,r0x0,v0x0.
raw
);
94
deb_rdump
(
"reg: %03x: %x\n"
,r0xc,v0xc.
raw
);
95
96
if
(index &
FC_DMA_SUBADDR_0
)
97
v0x0.
dma_0x0
.dma_0start =
onoff
;
98
99
if
(index &
FC_DMA_SUBADDR_1
)
100
v0xc.
dma_0xc
.dma_1start =
onoff
;
101
102
fc->
write_ibi_reg
(fc,r0x0,v0x0);
103
fc->
write_ibi_reg
(fc,r0xc,v0xc);
104
105
deb_rdump
(
"reg: %03x: %x\n"
,r0x0,v0x0.
raw
);
106
deb_rdump
(
"reg: %03x: %x\n"
,r0xc,v0xc.
raw
);
107
return
0;
108
}
109
EXPORT_SYMBOL
(
flexcop_dma_xfer_control
);
110
111
static
int
flexcop_dma_remap(
struct
flexcop_device
*
fc
,
112
flexcop_dma_index_t
dma_idx,
113
int
onoff
)
114
{
115
flexcop_ibi_register
r
= (dma_idx &
FC_DMA_1
) ?
dma1_00c
:
dma2_01c
;
116
flexcop_ibi_value
v
= fc->
read_ibi_reg
(fc,r);
117
deb_info
(
"%s\n"
,__func__);
118
v.
dma_0xc
.remap_enable =
onoff
;
119
fc->
write_ibi_reg
(fc,r,v);
120
return
0;
121
}
122
123
int
flexcop_dma_control_size_irq
(
struct
flexcop_device
*fc,
124
flexcop_dma_index_t
no
,
125
int
onoff)
126
{
127
flexcop_ibi_value
v = fc->
read_ibi_reg
(fc,
ctrl_208
);
128
129
if
(no &
FC_DMA_1
)
130
v.
ctrl_208
.DMA1_IRQ_Enable_sig =
onoff
;
131
132
if
(no &
FC_DMA_2
)
133
v.
ctrl_208
.DMA2_IRQ_Enable_sig =
onoff
;
134
135
fc->
write_ibi_reg
(fc,
ctrl_208
,v);
136
return
0;
137
}
138
EXPORT_SYMBOL
(
flexcop_dma_control_size_irq
);
139
140
int
flexcop_dma_control_timer_irq
(
struct
flexcop_device
*fc,
141
flexcop_dma_index_t
no
,
142
int
onoff)
143
{
144
flexcop_ibi_value
v = fc->
read_ibi_reg
(fc,
ctrl_208
);
145
146
if
(no &
FC_DMA_1
)
147
v.
ctrl_208
.DMA1_Timer_Enable_sig =
onoff
;
148
149
if
(no &
FC_DMA_2
)
150
v.
ctrl_208
.DMA2_Timer_Enable_sig =
onoff
;
151
152
fc->
write_ibi_reg
(fc,
ctrl_208
,v);
153
return
0;
154
}
155
EXPORT_SYMBOL
(
flexcop_dma_control_timer_irq
);
156
157
/* 1 cycles = 1.97 msec */
158
int
flexcop_dma_config_timer
(
struct
flexcop_device
*fc,
159
flexcop_dma_index_t
dma_idx,
u8
cycles)
160
{
161
flexcop_ibi_register
r = (dma_idx &
FC_DMA_1
) ?
dma1_004
:
dma2_014
;
162
flexcop_ibi_value
v = fc->
read_ibi_reg
(fc,r);
163
164
flexcop_dma_remap(fc,dma_idx,0);
165
166
deb_info
(
"%s\n"
,__func__);
167
v.
dma_0x4_write
.dmatimer = cycles;
168
fc->
write_ibi_reg
(fc,r,v);
169
return
0;
170
}
171
EXPORT_SYMBOL
(
flexcop_dma_config_timer
);
172
Generated on Thu Jan 10 2013 13:47:09 for Linux Kernel by
1.8.2