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
8 int flexcop_dma_allocate(struct pci_dev
*pdev
,
9 struct flexcop_dma
*dma
, u32 size
)
15 err("dma buffersize has to be even.");
19 if ((tcpu
= pci_alloc_consistent(pdev
, size
, &tdma
)) != NULL
) {
21 dma
->cpu_addr0
= tcpu
;
22 dma
->dma_addr0
= tdma
;
23 dma
->cpu_addr1
= tcpu
+ size
/2;
24 dma
->dma_addr1
= tdma
+ size
/2;
30 EXPORT_SYMBOL(flexcop_dma_allocate
);
32 void flexcop_dma_free(struct flexcop_dma
*dma
)
34 pci_free_consistent(dma
->pdev
, dma
->size
*2,
35 dma
->cpu_addr0
, dma
->dma_addr0
);
36 memset(dma
,0,sizeof(struct flexcop_dma
));
38 EXPORT_SYMBOL(flexcop_dma_free
);
40 int flexcop_dma_config(struct flexcop_device
*fc
,
41 struct flexcop_dma
*dma
,
42 flexcop_dma_index_t dma_idx
)
44 flexcop_ibi_value v0x0
,v0x4
,v0xc
;
45 v0x0
.raw
= v0x4
.raw
= v0xc
.raw
= 0;
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;
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
);
60 err("either DMA1 or DMA2 can be configured within one "
61 "flexcop_dma_config call.");
67 EXPORT_SYMBOL(flexcop_dma_config
);
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
,
75 flexcop_ibi_value v0x0
,v0xc
;
76 flexcop_ibi_register r0x0
,r0xc
;
78 if ((dma_idx
& FC_DMA_1
) == dma_idx
) {
81 } else if ((dma_idx
& FC_DMA_2
) == dma_idx
) {
85 err("either transfer DMA1 or DMA2 can be started within one "
86 "flexcop_dma_xfer_control call.");
90 v0x0
= fc
->read_ibi_reg(fc
,r0x0
);
91 v0xc
= fc
->read_ibi_reg(fc
,r0xc
);
93 deb_rdump("reg: %03x: %x\n",r0x0
,v0x0
.raw
);
94 deb_rdump("reg: %03x: %x\n",r0xc
,v0xc
.raw
);
96 if (index
& FC_DMA_SUBADDR_0
)
97 v0x0
.dma_0x0
.dma_0start
= onoff
;
99 if (index
& FC_DMA_SUBADDR_1
)
100 v0xc
.dma_0xc
.dma_1start
= onoff
;
102 fc
->write_ibi_reg(fc
,r0x0
,v0x0
);
103 fc
->write_ibi_reg(fc
,r0xc
,v0xc
);
105 deb_rdump("reg: %03x: %x\n",r0x0
,v0x0
.raw
);
106 deb_rdump("reg: %03x: %x\n",r0xc
,v0xc
.raw
);
109 EXPORT_SYMBOL(flexcop_dma_xfer_control
);
111 static int flexcop_dma_remap(struct flexcop_device
*fc
,
112 flexcop_dma_index_t dma_idx
,
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
);
123 int flexcop_dma_control_size_irq(struct flexcop_device
*fc
,
124 flexcop_dma_index_t no
,
127 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,ctrl_208
);
130 v
.ctrl_208
.DMA1_IRQ_Enable_sig
= onoff
;
133 v
.ctrl_208
.DMA2_IRQ_Enable_sig
= onoff
;
135 fc
->write_ibi_reg(fc
,ctrl_208
,v
);
138 EXPORT_SYMBOL(flexcop_dma_control_size_irq
);
140 int flexcop_dma_control_timer_irq(struct flexcop_device
*fc
,
141 flexcop_dma_index_t no
,
144 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,ctrl_208
);
147 v
.ctrl_208
.DMA1_Timer_Enable_sig
= onoff
;
150 v
.ctrl_208
.DMA2_Timer_Enable_sig
= onoff
;
152 fc
->write_ibi_reg(fc
,ctrl_208
,v
);
155 EXPORT_SYMBOL(flexcop_dma_control_timer_irq
);
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
)
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
);
164 flexcop_dma_remap(fc
,dma_idx
,0);
166 deb_info("%s\n",__func__
);
167 v
.dma_0x4_write
.dmatimer
= cycles
;
168 fc
->write_ibi_reg(fc
,r
,v
);
171 EXPORT_SYMBOL(flexcop_dma_config_timer
);