aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/b2c2/Kconfig13
-rw-r--r--drivers/media/dvb/b2c2/Makefile3
-rw-r--r--drivers/media/dvb/b2c2/b2c2-common.c214
-rw-r--r--drivers/media/dvb/b2c2/b2c2-usb-core.c549
4 files changed, 0 insertions, 779 deletions
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 52596907a0be..f1f6187b7c1e 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -11,16 +11,3 @@ config DVB_B2C2_SKYSTAR
11 for the B2C2/BBTI Air2PC-ATSC card. 11 for the B2C2/BBTI Air2PC-ATSC card.
12 12
13 Say Y if you own such a device and want to use it. 13 Say Y if you own such a device and want to use it.
14
15config DVB_B2C2_USB
16 tristate "B2C2/Technisat Air/Sky/Cable2PC USB"
17 depends on DVB_CORE && USB && EXPERIMENTAL
18 select DVB_STV0299
19 select DVB_MT352
20 help
21 Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently
22 the does nothing, but providing basic function for the used usb
23 protocol.
24
25 Say Y if you own such a device and want to use it.
26
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 9fb1247bfab8..f9cdc6f052d7 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -1,6 +1,3 @@
1obj-b2c2-usb = b2c2-usb-core.o b2c2-common.o
2
3obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o 1obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
4obj-$(CONFIG_DVB_B2C2_USB) + = b2c2-usb.o
5 2
6EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/b2c2-common.c b/drivers/media/dvb/b2c2/b2c2-common.c
deleted file mode 100644
index 000d60c405e3..000000000000
--- a/drivers/media/dvb/b2c2/b2c2-common.c
+++ /dev/null
@@ -1,214 +0,0 @@
1/*
2 * b2c2-common.c - common methods for the B2C2/Technisat SkyStar2 PCI DVB card and
3 * for the B2C2/Technisat Sky/Cable/AirStar USB devices
4 * based on the FlexCopII/FlexCopIII by B2C2, Inc.
5 *
6 * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
7 *
8 * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
9 * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
10 * Vincenzo Di Massa, hawk.it at tiscalinet.it
11 *
12 * Converted to Linux coding style
13 * Misc reorganization, polishing, restyling
14 * Roberto Ragusa, r.ragusa at libero.it
15 *
16 * Added hardware filtering support,
17 * Niklas Peinecke, peinecke at gdv.uni-hannover.de
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 *
33 */
34#include "stv0299.h"
35#include "mt352.h"
36#include "mt312.h"
37
38static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
39{
40 u8 aclk = 0;
41 u8 bclk = 0;
42
43 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
44 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
45 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
46 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
47 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
48 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
49
50 stv0299_writereg (fe, 0x13, aclk);
51 stv0299_writereg (fe, 0x14, bclk);
52 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
53 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
54 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
55
56 return 0;
57}
58
59static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
60{
61 u8 buf[4];
62 u32 div;
63 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
64// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
65
66 div = params->frequency / 125;
67
68 buf[0] = (div >> 8) & 0x7f;
69 buf[1] = div & 0xff;
70 buf[2] = 0x84; // 0xC4
71 buf[3] = 0x08;
72
73 if (params->frequency < 1500000) buf[3] |= 0x10;
74
75// if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
76 return 0;
77}
78
79static u8 samsung_tbmu24112_inittab[] = {
80 0x01, 0x15,
81 0x02, 0x30,
82 0x03, 0x00,
83 0x04, 0x7D,
84 0x05, 0x35,
85 0x06, 0x02,
86 0x07, 0x00,
87 0x08, 0xC3,
88 0x0C, 0x00,
89 0x0D, 0x81,
90 0x0E, 0x23,
91 0x0F, 0x12,
92 0x10, 0x7E,
93 0x11, 0x84,
94 0x12, 0xB9,
95 0x13, 0x88,
96 0x14, 0x89,
97 0x15, 0xC9,
98 0x16, 0x00,
99 0x17, 0x5C,
100 0x18, 0x00,
101 0x19, 0x00,
102 0x1A, 0x00,
103 0x1C, 0x00,
104 0x1D, 0x00,
105 0x1E, 0x00,
106 0x1F, 0x3A,
107 0x20, 0x2E,
108 0x21, 0x80,
109 0x22, 0xFF,
110 0x23, 0xC1,
111 0x28, 0x00,
112 0x29, 0x1E,
113 0x2A, 0x14,
114 0x2B, 0x0F,
115 0x2C, 0x09,
116 0x2D, 0x05,
117 0x31, 0x1F,
118 0x32, 0x19,
119 0x33, 0xFE,
120 0x34, 0x93,
121 0xff, 0xff,
122};
123
124static struct stv0299_config samsung_tbmu24112_config = {
125 .demod_address = 0x68,
126 .inittab = samsung_tbmu24112_inittab,
127 .mclk = 88000000UL,
128 .invert = 0,
129 .enhanced_tuning = 0,
130 .skip_reinit = 0,
131 .lock_output = STV0229_LOCKOUTPUT_LK,
132 .volt13_op0_op1 = STV0299_VOLT13_OP1,
133 .min_delay_ms = 100,
134 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
135 .pll_set = samsung_tbmu24112_pll_set,
136};
137
138
139
140
141
142static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
143{
144 static u8 mt352_clock_config [] = { 0x89, 0x10, 0x2d };
145 static u8 mt352_reset [] = { 0x50, 0x80 };
146 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
147 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
148 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
149
150 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
151 udelay(2000);
152 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
153 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
154
155 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
156 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
157
158 return 0;
159}
160
161static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
162{
163 u32 div;
164 unsigned char bs = 0;
165
166 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
167 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
168
169 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
170 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
171 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
172
173 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
174 pllbuf[1] = div >> 8;
175 pllbuf[2] = div & 0xff;
176 pllbuf[3] = 0xcc;
177 pllbuf[4] = bs;
178
179 return 0;
180}
181
182static struct mt352_config samsung_tdtc9251dh0_config = {
183
184 .demod_address = 0x0f,
185 .demod_init = samsung_tdtc9251dh0_demod_init,
186 .pll_set = samsung_tdtc9251dh0_pll_set,
187};
188
189static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
190{
191 u8 buf[4];
192 u32 div;
193 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
194// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
195
196 div = (params->frequency + (125/2)) / 125;
197
198 buf[0] = (div >> 8) & 0x7f;
199 buf[1] = (div >> 0) & 0xff;
200 buf[2] = 0x84 | ((div >> 10) & 0x60);
201 buf[3] = 0x80;
202
203 if (params->frequency < 1550000)
204 buf[3] |= 0x02;
205
206 //if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
207 return 0;
208}
209
210static struct mt312_config skystar23_samsung_tbdu18132_config = {
211
212 .demod_address = 0x0e,
213 .pll_set = skystar23_samsung_tbdu18132_pll_set,
214};
diff --git a/drivers/media/dvb/b2c2/b2c2-usb-core.c b/drivers/media/dvb/b2c2/b2c2-usb-core.c
deleted file mode 100644
index 9306da046c91..000000000000
--- a/drivers/media/dvb/b2c2/b2c2-usb-core.c
+++ /dev/null
@@ -1,549 +0,0 @@
1/*
2 * Copyright (C) 2004 Patrick Boettcher <patrick.boettcher@desy.de>,
3 * Luca Bertagnolio <>,
4 *
5 * based on information provided by John Jurrius from BBTI, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2.
10 *
11 */
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/usb.h>
16#include <linux/moduleparam.h>
17#include <linux/pci.h>
18#include <linux/version.h>
19
20#include "dmxdev.h"
21#include "dvb_demux.h"
22#include "dvb_filter.h"
23#include "dvb_net.h"
24#include "dvb_frontend.h"
25
26/* debug */
27#define dprintk(level,args...) \
28 do { if ((debug & level)) { printk(args); } } while (0)
29#define debug_dump(b,l) if (debug) {\
30 int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \
31 for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
32 deb_xfer("\n");\
33}
34
35static int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able)).");
38
39#define deb_info(args...) dprintk(0x01,args)
40#define deb_ts(args...) dprintk(0x02,args)
41#define deb_ctrl(args...) dprintk(0x04,args)
42
43/* Version information */
44#define DRIVER_VERSION "0.0"
45#define DRIVER_DESC "Driver for B2C2/Technisat Air/Cable/Sky-2-PC USB devices"
46#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
47
48/* transfer parameters */
49#define B2C2_USB_FRAMES_PER_ISO 4
50#define B2C2_USB_NUM_ISO_URB 4 /* TODO check out a good value */
51
52#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(b2c2->udev,0)
53#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(b2c2->udev,0)
54#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(b2c2->udev,0x81)
55
56struct usb_b2c2_usb {
57 struct usb_device *udev;
58 struct usb_interface *uintf;
59
60 u8 *iso_buffer;
61 int buffer_size;
62 dma_addr_t iso_dma_handle;
63 struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
64};
65
66
67/*
68 * USB
69 * 10 90 34 12 78 56 04 00
70 * usb_control_msg(udev, usb_sndctrlpipe(udev,0),
71 * 0x90,
72 * 0x10,
73 * 0x1234,
74 * 0x5678,
75 * buf,
76 * 4,
77 * 5*HZ);
78 *
79 * extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
80 * __u8 request,
81 * __u8 requesttype,
82 * __u16 value,
83 * __u16 index,
84 * void *data,
85 * __u16 size,
86 * int timeout);
87 *
88 */
89
90/* request types */
91typedef enum {
92
93/* something is wrong with this part
94 RTYPE_READ_DW = (1 << 6),
95 RTYPE_WRITE_DW_1 = (3 << 6),
96 RTYPE_READ_V8_MEMORY = (6 << 6),
97 RTYPE_WRITE_V8_MEMORY = (7 << 6),
98 RTYPE_WRITE_V8_FLASH = (8 << 6),
99 RTYPE_GENERIC = (9 << 6),
100*/
101 RTYPE_READ_DW = (3 << 6),
102 RTYPE_WRITE_DW_1 = (1 << 6),
103
104 RTYPE_READ_V8_MEMORY = (6 << 6),
105 RTYPE_WRITE_V8_MEMORY = (7 << 6),
106 RTYPE_WRITE_V8_FLASH = (8 << 6),
107 RTYPE_GENERIC = (9 << 6),
108} b2c2_usb_request_type_t;
109
110/* request */
111typedef enum {
112 B2C2_USB_WRITE_V8_MEM = 0x04,
113 B2C2_USB_READ_V8_MEM = 0x05,
114 B2C2_USB_READ_REG = 0x08,
115 B2C2_USB_WRITE_REG = 0x0A,
116/* B2C2_USB_WRITEREGLO = 0x0A, */
117 B2C2_USB_WRITEREGHI = 0x0B,
118 B2C2_USB_FLASH_BLOCK = 0x10,
119 B2C2_USB_I2C_REQUEST = 0x11,
120 B2C2_USB_UTILITY = 0x12,
121} b2c2_usb_request_t;
122
123/* function definition for I2C_REQUEST */
124typedef enum {
125 USB_FUNC_I2C_WRITE = 0x01,
126 USB_FUNC_I2C_MULTIWRITE = 0x02,
127 USB_FUNC_I2C_READ = 0x03,
128 USB_FUNC_I2C_REPEATWRITE = 0x04,
129 USB_FUNC_GET_DESCRIPTOR = 0x05,
130 USB_FUNC_I2C_REPEATREAD = 0x06,
131/* DKT 020208 - add this to support special case of DiSEqC */
132 USB_FUNC_I2C_CHECKWRITE = 0x07,
133 USB_FUNC_I2C_CHECKRESULT = 0x08,
134} b2c2_usb_i2c_function_t;
135
136/*
137 * function definition for UTILITY request 0x12
138 * DKT 020304 - new utility function
139 */
140typedef enum {
141 UTILITY_SET_FILTER = 0x01,
142 UTILITY_DATA_ENABLE = 0x02,
143 UTILITY_FLEX_MULTIWRITE = 0x03,
144 UTILITY_SET_BUFFER_SIZE = 0x04,
145 UTILITY_FLEX_OPERATOR = 0x05,
146 UTILITY_FLEX_RESET300_START = 0x06,
147 UTILITY_FLEX_RESET300_STOP = 0x07,
148 UTILITY_FLEX_RESET300 = 0x08,
149 UTILITY_SET_ISO_SIZE = 0x09,
150 UTILITY_DATA_RESET = 0x0A,
151 UTILITY_GET_DATA_STATUS = 0x10,
152 UTILITY_GET_V8_REG = 0x11,
153/* DKT 020326 - add function for v1.14 */
154 UTILITY_SRAM_WRITE = 0x12,
155 UTILITY_SRAM_READ = 0x13,
156 UTILITY_SRAM_TESTFILL = 0x14,
157 UTILITY_SRAM_TESTSET = 0x15,
158 UTILITY_SRAM_TESTVERIFY = 0x16,
159} b2c2_usb_utility_function_t;
160
161#define B2C2_WAIT_FOR_OPERATION_RW 1 // 1 s
162#define B2C2_WAIT_FOR_OPERATION_RDW 3 // 3 s
163#define B2C2_WAIT_FOR_OPERATION_WDW 1 // 1 s
164
165#define B2C2_WAIT_FOR_OPERATION_V8READ 3 // 3 s
166#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3 // 3 s
167#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3 // 3 s
168
169/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
170 * in the IBI address, to make the V8 code simpler.
171 * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
172 * in general: 0000 0HHH 000L LL00
173 * IBI ADDRESS FORMAT: RHHH BLLL
174 *
175 * where R is the read(1)/write(0) bit, B is the busy bit
176 * and HHH and LLL are the two sets of three bits from the PCI address.
177 */
178#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
179#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
180
181/*
182 * DKT 020228 - forget about this VENDOR_BUFFER_SIZE, read and write register
183 * deal with DWORD or 4 bytes, that should be should from now on
184 */
185static u32 b2c2_usb_read_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI)
186{
187 u32 val;
188 u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | 0x0080;
189 int len = usb_control_msg(b2c2->udev,
190 B2C2_USB_CTRL_PIPE_IN,
191 B2C2_USB_READ_REG,
192 RTYPE_READ_DW,
193 wAddress,
194 0,
195 &val,
196 sizeof(u32),
197 B2C2_WAIT_FOR_OPERATION_RDW * 1000);
198
199 if (len != sizeof(u32)) {
200 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
201 return -EIO;
202 } else
203 return val;
204}
205
206/*
207 * DKT 020228 - from now on, we don't support anything older than firm 1.00
208 * I eliminated the write register as a 2 trip of writing hi word and lo word
209 * and force this to write only 4 bytes at a time.
210 * NOTE: this should work with all the firmware from 1.00 and newer
211 */
212static int b2c2_usb_write_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI, u32 val)
213{
214 u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI);
215 int len = usb_control_msg(b2c2->udev,
216 B2C2_USB_CTRL_PIPE_OUT,
217 B2C2_USB_WRITE_REG,
218 RTYPE_WRITE_DW_1,
219 wAddress,
220 0,
221 &val,
222 sizeof(u32),
223 B2C2_WAIT_FOR_OPERATION_RDW * 1000);
224
225 if (len != sizeof(u32)) {
226 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
227 return -EIO;
228 } else
229 return 0;
230}
231
232/*
233 * DKT 010817 - add support for V8 memory read/write and flash update
234 */
235static int b2c2_usb_v8_memory_req(struct usb_b2c2_usb *b2c2,
236 b2c2_usb_request_t req, u8 page, u16 wAddress,
237 u16 buflen, u8 *pbBuffer)
238{
239 u8 dwRequestType;
240 u16 wIndex;
241 int nWaitTime,pipe,len;
242
243 wIndex = page << 8;
244
245 switch (req) {
246 case B2C2_USB_READ_V8_MEM:
247 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
248 dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
249 pipe = B2C2_USB_CTRL_PIPE_IN;
250 break;
251 case B2C2_USB_WRITE_V8_MEM:
252 wIndex |= pbBuffer[0];
253 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
254 dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
255 pipe = B2C2_USB_CTRL_PIPE_OUT;
256 break;
257 case B2C2_USB_FLASH_BLOCK:
258 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
259 dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
260 pipe = B2C2_USB_CTRL_PIPE_OUT;
261 break;
262 default:
263 deb_info("unsupported request for v8_mem_req %x.\n",req);
264 return -EINVAL;
265 }
266 len = usb_control_msg(b2c2->udev,pipe,
267 req,
268 dwRequestType,
269 wAddress,
270 wIndex,
271 pbBuffer,
272 buflen,
273 nWaitTime * 1000);
274 return len == buflen ? 0 : -EIO;
275}
276
277static int b2c2_usb_i2c_req(struct usb_b2c2_usb *b2c2,
278 b2c2_usb_request_t req, b2c2_usb_i2c_function_t func,
279 u8 port, u8 chipaddr, u8 addr, u8 buflen, u8 *buf)
280{
281 u16 wValue, wIndex;
282 int nWaitTime,pipe,len;
283 u8 dwRequestType;
284
285 switch (func) {
286 case USB_FUNC_I2C_WRITE:
287 case USB_FUNC_I2C_MULTIWRITE:
288 case USB_FUNC_I2C_REPEATWRITE:
289 /* DKT 020208 - add this to support special case of DiSEqC */
290 case USB_FUNC_I2C_CHECKWRITE:
291 pipe = B2C2_USB_CTRL_PIPE_OUT;
292 nWaitTime = 2;
293 dwRequestType = (u8) RTYPE_GENERIC;
294 break;
295 case USB_FUNC_I2C_READ:
296 case USB_FUNC_I2C_REPEATREAD:
297 pipe = B2C2_USB_CTRL_PIPE_IN;
298 nWaitTime = 2;
299 dwRequestType = (u8) RTYPE_GENERIC;
300 break;
301 default:
302 deb_info("unsupported function for i2c_req %x\n",func);
303 return -EINVAL;
304 }
305 wValue = (func << 8 ) | port;
306 wIndex = (chipaddr << 8 ) | addr;
307
308 len = usb_control_msg(b2c2->udev,pipe,
309 req,
310 dwRequestType,
311 addr,
312 wIndex,
313 buf,
314 buflen,
315 nWaitTime * 1000);
316 return len == buflen ? 0 : -EIO;
317}
318
319int static b2c2_usb_utility_req(struct usb_b2c2_usb *b2c2, int set,
320 b2c2_usb_utility_function_t func, u8 extra, u16 wIndex,
321 u16 buflen, u8 *pvBuffer)
322{
323 u16 wValue;
324 int nWaitTime = 2,
325 pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
326 len;
327
328 wValue = (func << 8) | extra;
329
330 len = usb_control_msg(b2c2->udev,pipe,
331 B2C2_USB_UTILITY,
332 (u8) RTYPE_GENERIC,
333 wValue,
334 wIndex,
335 pvBuffer,
336 buflen,
337 nWaitTime * 1000);
338 return len == buflen ? 0 : -EIO;
339}
340
341
342
343static void b2c2_dumpfourreg(struct usb_b2c2_usb *b2c2, u16 offs)
344{
345 u32 r0,r1,r2,r3;
346 r0 = r1 = r2 = r3 = 0;
347 r0 = b2c2_usb_read_dw(b2c2,offs);
348 r1 = b2c2_usb_read_dw(b2c2,offs + 0x04);
349 r2 = b2c2_usb_read_dw(b2c2,offs + 0x08);
350 r3 = b2c2_usb_read_dw(b2c2,offs + 0x0c);
351 deb_ctrl("dump: offset: %03x, %08x, %08x, %08x, %08x\n",offs,r0,r1,r2,r3);
352}
353
354static void b2c2_urb_complete(struct urb *urb, struct pt_regs *ptregs)
355{
356 struct usb_b2c2_usb *b2c2 = urb->context;
357 deb_ts("urb completed, bufsize: %d\n",urb->transfer_buffer_length);
358
359// urb_submit_urb(urb,GFP_ATOMIC); enable for real action
360}
361
362static void b2c2_exit_usb(struct usb_b2c2_usb *b2c2)
363{
364 int i;
365 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
366 if (b2c2->iso_urb[i] != NULL) { /* not sure about unlink_urb and iso-urbs TODO */
367 deb_info("unlinking/killing urb no. %d\n",i);
368#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
369 usb_unlink_urb(b2c2->iso_urb[i]);
370#else
371 usb_kill_urb(b2c2->iso_urb[i]);
372#endif
373 usb_free_urb(b2c2->iso_urb[i]);
374 }
375
376 if (b2c2->iso_buffer != NULL)
377 pci_free_consistent(NULL,b2c2->buffer_size, b2c2->iso_buffer, b2c2->iso_dma_handle);
378
379}
380
381static int b2c2_init_usb(struct usb_b2c2_usb *b2c2)
382{
383 u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
384 int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
385 int buffer_offset = 0;
386
387 deb_info("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
388 B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
389
390 b2c2->iso_buffer = pci_alloc_consistent(NULL,bufsize,&b2c2->iso_dma_handle);
391 if (b2c2->iso_buffer == NULL)
392 return -ENOMEM;
393 memset(b2c2->iso_buffer, 0, bufsize);
394 b2c2->buffer_size = bufsize;
395
396 /* creating iso urbs */
397 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
398 if (!(b2c2->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
399 ret = -ENOMEM;
400 goto urb_error;
401 }
402 /* initialising and submitting iso urbs */
403 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
404 int frame_offset = 0;
405 struct urb *urb = b2c2->iso_urb[i];
406 deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
407
408 urb->dev = b2c2->udev;
409 urb->context = b2c2;
410 urb->complete = b2c2_urb_complete;
411 urb->pipe = B2C2_USB_DATA_PIPE;
412 urb->transfer_flags = URB_ISO_ASAP;
413 urb->interval = 1;
414 urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
415 urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
416 urb->transfer_buffer = b2c2->iso_buffer + buffer_offset;
417
418 buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
419 for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
420 deb_info("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
421 urb->iso_frame_desc[j].offset = frame_offset;
422 urb->iso_frame_desc[j].length = frame_size;
423 frame_offset += frame_size;
424 }
425
426 if ((ret = usb_submit_urb(b2c2->iso_urb[i],GFP_ATOMIC))) {
427 err("submitting urb %d failed with %d.",i,ret);
428 goto urb_error;
429 }
430 deb_info("submitted urb no. %d.\n",i);
431 }
432
433 ret = 0;
434 goto success;
435urb_error:
436 b2c2_exit_usb(b2c2);
437success:
438 return ret;
439}
440
441static int b2c2_usb_probe(struct usb_interface *intf,
442 const struct usb_device_id *id)
443{
444 struct usb_device *udev = interface_to_usbdev(intf);
445 struct usb_b2c2_usb *b2c2 = NULL;
446 int ret;
447
448 b2c2 = kmalloc(sizeof(struct usb_b2c2_usb),GFP_KERNEL);
449 if (b2c2 == NULL) {
450 err("no memory");
451 return -ENOMEM;
452 }
453 b2c2->udev = udev;
454 b2c2->uintf = intf;
455
456 /* use the alternate setting with the larges buffer */
457 usb_set_interface(udev,0,1);
458
459 if ((ret = b2c2_init_usb(b2c2)))
460 goto usb_init_error;
461
462 usb_set_intfdata(intf,b2c2);
463
464 switch (udev->speed) {
465 case USB_SPEED_LOW:
466 err("cannot handle USB speed because it is to sLOW.");
467 break;
468 case USB_SPEED_FULL:
469 info("running at FULL speed.");
470 break;
471 case USB_SPEED_HIGH:
472 info("running at HIGH speed.");
473 break;
474 case USB_SPEED_UNKNOWN: /* fall through */
475 default:
476 err("cannot handle USB speed because it is unkown.");
477 break;
478 }
479
480 b2c2_dumpfourreg(b2c2,0x200);
481 b2c2_dumpfourreg(b2c2,0x300);
482 b2c2_dumpfourreg(b2c2,0x400);
483 b2c2_dumpfourreg(b2c2,0x700);
484
485
486 if (ret == 0)
487 info("%s successfully initialized and connected.",DRIVER_DESC);
488 else
489 info("%s error while loading driver (%d)",DRIVER_DESC,ret);
490
491 ret = 0;
492 goto success;
493
494usb_init_error:
495 kfree(b2c2);
496success:
497 return ret;
498}
499
500static void b2c2_usb_disconnect(struct usb_interface *intf)
501{
502 struct usb_b2c2_usb *b2c2 = usb_get_intfdata(intf);
503 usb_set_intfdata(intf,NULL);
504 if (b2c2 != NULL) {
505 b2c2_exit_usb(b2c2);
506 kfree(b2c2);
507 }
508 info("%s successfully deinitialized and disconnected.",DRIVER_DESC);
509
510}
511
512static struct usb_device_id b2c2_usb_table [] = {
513 { USB_DEVICE(0x0af7, 0x0101) }
514};
515
516/* usb specific object needed to register this driver with the usb subsystem */
517static struct usb_driver b2c2_usb_driver = {
518 .owner = THIS_MODULE,
519 .name = "dvb_b2c2_usb",
520 .probe = b2c2_usb_probe,
521 .disconnect = b2c2_usb_disconnect,
522 .id_table = b2c2_usb_table,
523};
524
525/* module stuff */
526static int __init b2c2_usb_init(void)
527{
528 int result;
529 if ((result = usb_register(&b2c2_usb_driver))) {
530 err("usb_register failed. Error number %d",result);
531 return result;
532 }
533
534 return 0;
535}
536
537static void __exit b2c2_usb_exit(void)
538{
539 /* deregister this driver from the USB subsystem */
540 usb_deregister(&b2c2_usb_driver);
541}
542
543module_init (b2c2_usb_init);
544module_exit (b2c2_usb_exit);
545
546MODULE_AUTHOR(DRIVER_AUTHOR);
547MODULE_DESCRIPTION(DRIVER_DESC);
548MODULE_LICENSE("GPL");
549MODULE_DEVICE_TABLE(usb, b2c2_usb_table);