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