Zuletzt aktiv 1 month ago

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

tbsecp3-dma.c Originalformat
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
20static unsigned int dma_pkts[8] = {128, 128, 128, 128, 128, 128, 128, 128};
21module_param_array(dma_pkts, int, NULL, 0444); /* No /sys/module write access */
22MODULE_PARM_DESC(dma_pkts, "DMA buffer size in TS packets (16-256), default 128");
23
24#define TS_PACKET_SIZE 188
25
26static 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
93void 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
107void 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
118void 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
133void 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
155int 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;
204err:
205 dev_err(&dev->pci_dev->dev, "dma: memory alloc failed\n");
206 tbsecp3_dma_free(dev);
207 return -ENOMEM;
208}
209
tbsecp3.h Originalformat
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
80struct tbsecp3_dev;
81
82
83struct tbsecp3_gpio_pin {
84 u8 lvl;
85 u8 nr;
86};
87
88struct 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
94struct tbsecp3_adap_config {
95 u32 ts_in;
96 u8 i2c_bus_nr;
97 struct tbsecp3_gpio_config gpio;
98};
99
100struct 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
110struct 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
122struct 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
138struct 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
148struct 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
181struct 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 */
203void tbsecp3_gpio_set_pin(struct tbsecp3_dev *dev,
204 struct tbsecp3_gpio_pin *pin, int state);
205
206/* tbspcie-i2c.c */
207extern int tbsecp3_i2c_init(struct tbsecp3_dev *dev);
208extern void tbsecp3_i2c_exit(struct tbsecp3_dev *dev);
209extern void tbsecp3_i2c_reg_init(struct tbsecp3_dev *dev);
210extern void tbsecp3_i2c_remove_clients(struct tbsecp3_adapter *adapter);
211
212/* tbspcie-cards.c */
213extern struct tbsecp3_board tbsecp3_boards[];
214
215/* tbspcie-dvb.c */
216extern int tbsecp3_dvb_init(struct tbsecp3_adapter *adapter);
217extern void tbsecp3_dvb_exit(struct tbsecp3_adapter *adapter);
218
219/* tbsecp3-asi.c */
220extern u8 asi_CheckFree(struct tbsecp3_dev *dev,int asi_base_addr, unsigned char OpbyteNum);
221extern bool asi_chip_reset(struct tbsecp3_dev *dev,int asi_base_addr);
222extern int asi_read16bit(struct tbsecp3_dev *dev,int asi_base_addr,int reg_addr);
223extern bool asi_write16bit(struct tbsecp3_dev *dev,int asi_base_addr, int reg_addr, int data16bit);
224
225/* tbsecp3-dma.c */
226extern int tbsecp3_dma_init(struct tbsecp3_dev *dev);
227extern void tbsecp3_dma_free(struct tbsecp3_dev *dev);
228extern void tbsecp3_dma_reg_init(struct tbsecp3_dev *dev);
229extern void tbsecp3_dma_enable(struct tbsecp3_adapter *adap);
230extern void tbsecp3_dma_disable(struct tbsecp3_adapter *adap);
231
232/* tbsecp3-ca.c */
233int tbsecp3_ca_init(struct tbsecp3_adapter *adap, int nr);
234void tbsecp3_ca_release(struct tbsecp3_adapter *adap);
235
236#endif
237