Ultima attività 1 month ago

Raw Frame Passthrough from TBS6903 board by faking a TS Frame.

racerxdl's Avatar Lucas Teske ha revisionato questo gist 6 years ago. Vai alla revisione

2 files changed, 444 insertions

tbsecp3-dma.c(file creato)

@@ -0,0 +1,208 @@
1 + /*
2 + TBS ECP3 FPGA based cards PCIe driver
3 +
4 + This program is free software: you can redistribute it and/or modify
5 + it under the terms of the GNU General Public License as published by
6 + the Free Software Foundation, either version 3 of the License, or
7 + (at your option) any later version.
8 +
9 + This program is distributed in the hope that it will be useful,
10 + but WITHOUT ANY WARRANTY; without even the implied warranty of
11 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 + GNU General Public License for more details.
13 +
14 + You should have received a copy of the GNU General Public License
15 + along with this program. If not, see <http://www.gnu.org/licenses/>.
16 + */
17 +
18 + #include "tbsecp3.h"
19 +
20 + static unsigned int dma_pkts[8] = {128, 128, 128, 128, 128, 128, 128, 128};
21 + module_param_array(dma_pkts, int, NULL, 0444); /* No /sys/module write access */
22 + MODULE_PARM_DESC(dma_pkts, "DMA buffer size in TS packets (16-256), default 128");
23 +
24 + #define TS_PACKET_SIZE 188
25 +
26 + static void tbsecp3_dma_tasklet(unsigned long adap)
27 + {
28 + struct tbsecp3_adapter *adapter = (struct tbsecp3_adapter *) adap;
29 + struct tbsecp3_dev *dev = adapter->dev;
30 + u32 read_buffer, next_buffer;
31 + u8* data;
32 + u8* dataraw;
33 + int i;
34 +
35 + spin_lock(&adapter->adap_lock);
36 +
37 + if (adapter->dma.cnt < TBSECP3_DMA_PRE_BUFFERS)
38 + {
39 + next_buffer = (tbs_read(adapter->dma.base, TBSECP3_DMA_STAT) - TBSECP3_DMA_PRE_BUFFERS + 1) & (TBSECP3_DMA_BUFFERS - 1);
40 + adapter->dma.cnt++;
41 + }
42 + else
43 + {
44 + next_buffer = (tbs_read(adapter->dma.base, TBSECP3_DMA_STAT) - TBSECP3_DMA_PRE_BUFFERS + 1) & (TBSECP3_DMA_BUFFERS - 1);
45 + read_buffer = (u32)adapter->dma.next_buffer;
46 +
47 + while (read_buffer != next_buffer)
48 + {
49 + data = adapter->dma.buf[read_buffer];
50 + dataraw = adapter->dma.buf4raw[read_buffer];
51 + // Let's fake our MPEG-TS Header
52 + for (i = 0; i < adapter->dma.buffer_pkts; i++) {
53 + dataraw[i*TS_PACKET_SIZE] = 0x47;
54 + dataraw[i*TS_PACKET_SIZE+1] = 64 + 0x1F;
55 + dataraw[i*TS_PACKET_SIZE+2] = 0xFE; // PID 0xFF
56 + dataraw[i*TS_PACKET_SIZE+3] = 0x10; // AFC = 1
57 + memcpy(&dataraw[i*TS_PACKET_SIZE+4], &data[i*(TS_PACKET_SIZE-4)], TS_PACKET_SIZE-4);
58 + }
59 +
60 + data = dataraw;
61 +
62 + // if (data[adapter->dma.offset] != 0x47) {
63 + // /* Find sync byte offset with crude force (this might fail!) */
64 + // for (i = 0; i < TS_PACKET_SIZE; i++)
65 + // if ((data[i] == 0x47) &&
66 + // (data[i + TS_PACKET_SIZE] == 0x47) &&
67 + // (data[i + 2 * TS_PACKET_SIZE] == 0x47) &&
68 + // (data[i + 4 * TS_PACKET_SIZE] == 0x47)) {
69 + // adapter->dma.offset = i;
70 + // break;
71 + // }
72 + // }
73 +
74 + // if (adapter->dma.offset != 0) {
75 + // data += adapter->dma.offset;
76 + // /* Copy remains of last packet from buffer 0 behind last one */
77 + // if (read_buffer == (TBSECP3_DMA_BUFFERS - 1)) {
78 + // memcpy( adapter->dma.buf[TBSECP3_DMA_BUFFERS],
79 + // adapter->dma.buf[0], adapter->dma.offset);
80 + // }
81 + // }
82 + dvb_dmx_swfilter_packets(&adapter->demux, data, adapter->dma.buffer_pkts);
83 + read_buffer = (read_buffer + 1) & (TBSECP3_DMA_BUFFERS - 1);
84 + }
85 + }
86 +
87 + adapter->dma.next_buffer = (u8)next_buffer;
88 +
89 + spin_unlock(&adapter->adap_lock);
90 +
91 + }
92 +
93 + void tbsecp3_dma_enable(struct tbsecp3_adapter *adap)
94 + {
95 + struct tbsecp3_dev *dev = adap->dev;
96 +
97 + spin_lock_irq(&adap->adap_lock);
98 + adap->dma.offset = 0;
99 + adap->dma.cnt = 0;
100 + adap->dma.next_buffer= 0;
101 + tbs_read(adap->dma.base, TBSECP3_DMA_STAT);
102 + tbs_write(TBSECP3_INT_BASE, TBSECP3_DMA_IE(adap->cfg->ts_in), 1);
103 + tbs_write(adap->dma.base, TBSECP3_DMA_EN, 1);
104 + spin_unlock_irq(&adap->adap_lock);
105 + }
106 +
107 + void tbsecp3_dma_disable(struct tbsecp3_adapter *adap)
108 + {
109 + struct tbsecp3_dev *dev = adap->dev;
110 +
111 + spin_lock_irq(&adap->adap_lock);
112 + tbs_read(adap->dma.base, TBSECP3_DMA_STAT);
113 + tbs_write(TBSECP3_INT_BASE, TBSECP3_DMA_IE(adap->cfg->ts_in), 0);
114 + tbs_write(adap->dma.base, TBSECP3_DMA_EN, 0);
115 + spin_unlock_irq(&adap->adap_lock);
116 + }
117 +
118 + void tbsecp3_dma_reg_init(struct tbsecp3_dev *dev)
119 + {
120 + int i;
121 + struct tbsecp3_adapter *adapter = dev->adapter;
122 +
123 + for (i = 0; i < dev->info->adapters; i++) {
124 + tbs_write(adapter->dma.base, TBSECP3_DMA_EN, 0);
125 + tbs_write(adapter->dma.base, TBSECP3_DMA_ADDRH, 0);
126 + tbs_write(adapter->dma.base, TBSECP3_DMA_ADDRL, (u32) adapter->dma.dma_addr);
127 + tbs_write(adapter->dma.base, TBSECP3_DMA_TSIZE, adapter->dma.page_size);
128 + tbs_write(adapter->dma.base, TBSECP3_DMA_BSIZE, adapter->dma.buffer_size);
129 + adapter++;
130 + }
131 + }
132 +
133 + void tbsecp3_dma_free(struct tbsecp3_dev *dev)
134 + {
135 + struct tbsecp3_adapter *adapter = dev->adapter;
136 + int i;
137 + for (i = 0; i < dev->info->adapters; i++) {
138 + if (adapter->dma.buf[0] != NULL) {
139 + pci_free_consistent(dev->pci_dev,
140 + adapter->dma.page_size + 0x100,
141 + adapter->dma.buf[0], adapter->dma.dma_addr);
142 + adapter->dma.buf[0] = NULL;
143 + }
144 +
145 + if (adapter->dma.buf4raw[0] != NULL) {
146 + pci_free_consistent(dev->pci_dev,
147 + adapter->dma.page_size_raw + 0x100,
148 + adapter->dma.buf4raw[0], adapter->dma.dma_addr2);
149 + adapter->dma.buf4raw[0] = NULL;
150 + }
151 + adapter++;
152 + }
153 + }
154 +
155 + int tbsecp3_dma_init(struct tbsecp3_dev *dev)
156 + {
157 + struct tbsecp3_adapter *adapter = dev->adapter;
158 + int i, j;
159 +
160 + for (i = 0; i < dev->info->adapters; i++) {
161 + if (dma_pkts[i] < 16)
162 + dma_pkts[i] = 16;
163 + if (dma_pkts[i] > 256)
164 + dma_pkts[i] = 256;
165 +
166 + adapter->dma.buffer_pkts = dma_pkts[i];
167 + adapter->dma.buffer_size = dma_pkts[i] * (TS_PACKET_SIZE-4);
168 + adapter->dma.page_size = adapter->dma.buffer_size * TBSECP3_DMA_BUFFERS;
169 +
170 + adapter->dma.buffer_size_raw = dma_pkts[i] * (TS_PACKET_SIZE);
171 + adapter->dma.page_size_raw = adapter->dma.buffer_size_raw * TBSECP3_DMA_BUFFERS;
172 +
173 + adapter->dma.buf[0] = pci_alloc_consistent(dev->pci_dev,
174 + adapter->dma.page_size + 0x100,
175 + &adapter->dma.dma_addr);
176 + if (!adapter->dma.buf[0])
177 + goto err;
178 +
179 + adapter->dma.buf4raw[0] = pci_alloc_consistent(dev->pci_dev,
180 + adapter->dma.page_size_raw + 0x100,
181 + &adapter->dma.dma_addr2);
182 +
183 + if (!adapter->dma.buf4raw[0])
184 + goto err;
185 +
186 + dev_dbg(&dev->pci_dev->dev,
187 + "TS in %d: DMA page %d bytes, %d bytes (%d TS packets) per %d buffers\n", adapter->cfg->ts_in,
188 + adapter->dma.page_size, adapter->dma.buffer_size, adapter->dma.buffer_pkts, TBSECP3_DMA_BUFFERS);
189 +
190 + adapter->dma.base = TBSECP3_DMA_BASE(adapter->cfg->ts_in);
191 + adapter->dma.cnt = 0;
192 + adapter->dma.next_buffer = 0;
193 + for (j = 1; j < TBSECP3_DMA_BUFFERS + 1; j++) {
194 + adapter->dma.buf[j] = adapter->dma.buf[j-1] + adapter->dma.buffer_size;
195 + adapter->dma.buf4raw[j] = adapter->dma.buf4raw[j-1] + adapter->dma.buffer_size_raw;
196 + }
197 +
198 + tasklet_init(&adapter->tasklet, tbsecp3_dma_tasklet, (unsigned long) adapter);
199 + spin_lock_init(&adapter->adap_lock);
200 + adapter++;
201 + }
202 + tbsecp3_dma_reg_init(dev);
203 + return 0;
204 + err:
205 + dev_err(&dev->pci_dev->dev, "dma: memory alloc failed\n");
206 + tbsecp3_dma_free(dev);
207 + return -ENOMEM;
208 + }

tbsecp3.h(file creato)

@@ -0,0 +1,236 @@
1 + /*
2 + TBS ECP3 FPGA based cards PCIe driver
3 +
4 + This program is free software: you can redistribute it and/or modify
5 + it under the terms of the GNU General Public License as published by
6 + the Free Software Foundation, either version 3 of the License, or
7 + (at your option) any later version.
8 +
9 + This program is distributed in the hope that it will be useful,
10 + but WITHOUT ANY WARRANTY; without even the implied warranty of
11 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 + GNU General Public License for more details.
13 +
14 + You should have received a copy of the GNU General Public License
15 + along with this program. If not, see <http://www.gnu.org/licenses/>.
16 + */
17 +
18 + #ifndef _TBSECP3_H_
19 + #define _TBSECP3_H_
20 +
21 + #include <linux/i2c.h>
22 + #include <linux/init.h>
23 + #include <linux/interrupt.h>
24 + #include <linux/kernel.h>
25 + #include <linux/module.h>
26 + #include <linux/proc_fs.h>
27 + #include <linux/pci.h>
28 + #include <linux/dma-mapping.h>
29 + #include <linux/slab.h>
30 +
31 + #include <media/dmxdev.h>
32 + #include <media/dvbdev.h>
33 + #include <media/dvb_demux.h>
34 + #include <media/dvb_frontend.h>
35 + #include <media/dvb_ringbuffer.h>
36 + #include <media/dvb_ca_en50221.h>
37 + #include <media/dvb_net.h>
38 +
39 + #include "tbsecp3-regs.h"
40 +
41 + #define TBSECP3_VID 0x544d
42 + #define TBSECP3_PID 0x6178
43 +
44 + #define TBSECP3_BOARD_TBS6205 0
45 + #define TBSECP3_BOARD_TBS6281SE 1
46 + #define TBSECP3_BOARD_TBS6290SE 2
47 + #define TBSECP3_BOARD_TBS6209 3
48 + #define TBSECP3_BOARD_TBS6522 4
49 + #define TBSECP3_BOARD_TBS6528 5
50 + #define TBSECP3_BOARD_TBS6590 6
51 + #define TBSECP3_BOARD_TBS6902 7
52 + #define TBSECP3_BOARD_TBS6903 8
53 + #define TBSECP3_BOARD_TBS6904 9
54 + #define TBSECP3_BOARD_TBS6905 10
55 + #define TBSECP3_BOARD_TBS6908 11
56 + #define TBSECP3_BOARD_TBS6909 12
57 + #define TBSECP3_BOARD_TBS6910 13
58 + #define TBSECP3_BOARD_TBS6704 14
59 + #define TBSECP3_BOARD_TBS6814 15
60 + #define TBSECP3_BOARD_TBS6514 16
61 + #define TBSECP3_BOARD_TBS690a 17
62 + #define TBSECP3_BOARD_TBS6301 18
63 + #define TBSECP3_BOARD_TBS6304 19
64 + #define TBSECP3_BOARD_TBS6308 20
65 + #define TBSECP3_BOARD_TBS6903X 21
66 + #define TBSECP3_BOARD_TBS6909X 22
67 + #define TBSECP3_BOARD_TBS6904X 23
68 +
69 + #define TBSECP3_MAX_ADAPTERS (8)
70 + #define TBSECP3_MAX_I2C_BUS (4)
71 +
72 + #define TBSECP3_GPIODEF_NONE (0)
73 + #define TBSECP3_GPIODEF_HIGH (1)
74 + #define TBSECP3_GPIODEF_LOW (2)
75 +
76 + #define TBSECP3_DMA_BUFFERS 16
77 + #define TBSECP3_DMA_PRE_BUFFERS 2
78 +
79 +
80 + struct tbsecp3_dev;
81 +
82 +
83 + struct tbsecp3_gpio_pin {
84 + u8 lvl;
85 + u8 nr;
86 + };
87 +
88 + struct tbsecp3_gpio_config {
89 + struct tbsecp3_gpio_pin lnb_power;
90 + struct tbsecp3_gpio_pin lnb_voltage;
91 + struct tbsecp3_gpio_pin demod_reset;
92 + };
93 +
94 + struct tbsecp3_adap_config {
95 + u32 ts_in;
96 + u8 i2c_bus_nr;
97 + struct tbsecp3_gpio_config gpio;
98 + };
99 +
100 + struct tbsecp3_board {
101 + u16 board_id;
102 + char *name;
103 + int adapters;
104 + u32 i2c_speed;
105 + u8 eeprom_i2c;
106 + u8 eeprom_addr;
107 + struct tbsecp3_adap_config adap_config[8];
108 + };
109 +
110 + struct tbsecp3_i2c {
111 + struct tbsecp3_dev *dev;
112 + u32 base;
113 +
114 + struct i2c_adapter i2c_adap;
115 + struct i2c_client i2c_client;
116 +
117 + struct mutex lock;
118 + wait_queue_head_t wq;
119 + bool done;
120 + };
121 +
122 + struct tbsecp3_dma_channel {
123 + u32 base;
124 + dma_addr_t dma_addr;
125 + dma_addr_t dma_addr2;
126 + u32 page_size;
127 + u32 buffer_size;
128 + u32 buffer_pkts;
129 + u32 page_size_raw;
130 + u32 buffer_size_raw;
131 + u8 *buf[TBSECP3_DMA_BUFFERS + 1];
132 + u8 *buf4raw[TBSECP3_DMA_BUFFERS + 1];
133 + u8 offset;
134 + u8 cnt;
135 + u8 next_buffer;
136 + };
137 +
138 + struct tbsecp3_ca {
139 + int nr;
140 + u32 base;
141 + struct dvb_ca_en50221 ca;
142 +
143 + struct tbsecp3_adapter *adapter;
144 + struct mutex lock;
145 + int status;
146 + };
147 +
148 + struct tbsecp3_adapter {
149 + int nr;
150 + struct tbsecp3_adap_config *cfg;
151 +
152 + /* parent device */
153 + struct tbsecp3_dev *dev;
154 +
155 + /* i2c */
156 + struct tbsecp3_i2c *i2c;
157 + struct i2c_client *i2c_client_demod;
158 + struct i2c_client *i2c_client_tuner;
159 +
160 + /* dvb */
161 + struct dvb_adapter dvb_adapter;
162 + struct dvb_frontend *fe;
163 + struct dvb_frontend *fe2;
164 + struct dvb_frontend _fe2;
165 + struct dvb_demux demux;
166 + struct dmxdev dmxdev;
167 + struct dvb_net dvbnet;
168 + struct dmx_frontend fe_hw;
169 + struct dmx_frontend fe_mem;
170 + int feeds;
171 +
172 + /* dma */
173 + spinlock_t adap_lock;
174 + struct tasklet_struct tasklet;
175 + struct tbsecp3_dma_channel dma;
176 +
177 + /* ca interface */
178 + struct tbsecp3_ca *tbsca;
179 + };
180 +
181 + struct tbsecp3_dev {
182 + struct tbsecp3_board *info;
183 +
184 + /* pcie */
185 + struct pci_dev *pci_dev;
186 + void __iomem *lmmio;
187 + bool msi;
188 +
189 + /* dvb adapters */
190 + struct tbsecp3_adapter adapter[TBSECP3_MAX_ADAPTERS];
191 +
192 + /* i2c */
193 + struct tbsecp3_i2c i2c_bus[TBSECP3_MAX_I2C_BUS];
194 +
195 + u8 mac_num;
196 + };
197 +
198 + #define tbs_read(_b, _o) readl(dev->lmmio + (_b + _o))
199 + #define tbs_write(_b, _o, _v) writel((_v), dev->lmmio + (_b + _o))
200 +
201 +
202 + /* tbsecp3-core.c */
203 + void tbsecp3_gpio_set_pin(struct tbsecp3_dev *dev,
204 + struct tbsecp3_gpio_pin *pin, int state);
205 +
206 + /* tbspcie-i2c.c */
207 + extern int tbsecp3_i2c_init(struct tbsecp3_dev *dev);
208 + extern void tbsecp3_i2c_exit(struct tbsecp3_dev *dev);
209 + extern void tbsecp3_i2c_reg_init(struct tbsecp3_dev *dev);
210 + extern void tbsecp3_i2c_remove_clients(struct tbsecp3_adapter *adapter);
211 +
212 + /* tbspcie-cards.c */
213 + extern struct tbsecp3_board tbsecp3_boards[];
214 +
215 + /* tbspcie-dvb.c */
216 + extern int tbsecp3_dvb_init(struct tbsecp3_adapter *adapter);
217 + extern void tbsecp3_dvb_exit(struct tbsecp3_adapter *adapter);
218 +
219 + /* tbsecp3-asi.c */
220 + extern u8 asi_CheckFree(struct tbsecp3_dev *dev,int asi_base_addr, unsigned char OpbyteNum);
221 + extern bool asi_chip_reset(struct tbsecp3_dev *dev,int asi_base_addr);
222 + extern int asi_read16bit(struct tbsecp3_dev *dev,int asi_base_addr,int reg_addr);
223 + extern bool asi_write16bit(struct tbsecp3_dev *dev,int asi_base_addr, int reg_addr, int data16bit);
224 +
225 + /* tbsecp3-dma.c */
226 + extern int tbsecp3_dma_init(struct tbsecp3_dev *dev);
227 + extern void tbsecp3_dma_free(struct tbsecp3_dev *dev);
228 + extern void tbsecp3_dma_reg_init(struct tbsecp3_dev *dev);
229 + extern void tbsecp3_dma_enable(struct tbsecp3_adapter *adap);
230 + extern void tbsecp3_dma_disable(struct tbsecp3_adapter *adap);
231 +
232 + /* tbsecp3-ca.c */
233 + int tbsecp3_ca_init(struct tbsecp3_adapter *adap, int nr);
234 + void tbsecp3_ca_release(struct tbsecp3_adapter *adap);
235 +
236 + #endif
Più nuovi Più vecchi