Switch to kernel 3.3.8(solo2)
[vuplus_openvuplus_3.0] / meta-bsp / common / recipes / linux / linux-vuplus-3.3.8 / dvb_backport.patch
1 diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
2 index e9c1893..2477aba 100644
3 --- a/drivers/i2c/i2c-core.c
4 +++ b/drivers/i2c/i2c-core.c
5 @@ -1292,6 +1292,37 @@ module_exit(i2c_exit);
6   * the functional interface to the i2c busses.
7   * ----------------------------------------------------
8   */
9 +/**
10 + * __i2c_transfer - unlocked flavor of i2c_transfer
11 + * @adap: Handle to I2C bus
12 + * @msgs: One or more messages to execute before STOP is issued to
13 + *      terminate the operation; each message begins with a START.
14 + * @num: Number of messages to be executed.
15 + *
16 + * Returns negative errno, else the number of messages executed.
17 + *
18 + * Adapter lock must be held when calling this function. No debug logging
19 + * takes place. adap->algo->master_xfer existence isn't checked.
20 + */
21 +int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
22 +{
23 +        unsigned long orig_jiffies;
24 +        int ret, try;
25 +
26 +        /* Retry automatically on arbitration loss */
27 +        orig_jiffies = jiffies;
28 +        for (ret = 0, try = 0; try <= adap->retries; try++) {
29 +                ret = adap->algo->master_xfer(adap, msgs, num);
30 +                if (ret != -EAGAIN)
31 +                        break;
32 +                if (time_after(jiffies, orig_jiffies + adap->timeout))
33 +                        break;
34 +        }
35 +
36 +        return ret;
37 +}
38 +EXPORT_SYMBOL(__i2c_transfer);
39 +
40  
41  /**
42   * i2c_transfer - execute a single or combined I2C message
43 diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
44 index 9575db4..84d85b9 100644
45 --- a/drivers/media/Kconfig
46 +++ b/drivers/media/Kconfig
47 @@ -6,20 +6,82 @@ menuconfig MEDIA_SUPPORT
48         tristate "Multimedia support"
49         depends on HAS_IOMEM
50         help
51 -         If you want to use Video for Linux, DVB for Linux, or DAB adapters,
52 +         If you want to use Webcams, Video grabber devices and/or TV devices
53           enable this option and other options below.
54 +         Additional info and docs are available on the web at
55 +         <http://linuxtv.org>
56  
57  if MEDIA_SUPPORT
58  
59  comment "Multimedia core support"
60  
61  #
62 +# Multimedia support - automatically enable V4L2 and DVB core
63 +#
64 +config MEDIA_CAMERA_SUPPORT
65 +       bool "Cameras/video grabbers support"
66 +       ---help---
67 +         Enable support for webcams and video grabbers.
68 +
69 +         Say Y when you have a webcam or a video capture grabber board.
70 +
71 +config MEDIA_ANALOG_TV_SUPPORT
72 +       bool "Analog TV support"
73 +       ---help---
74 +         Enable analog TV support.
75 +
76 +         Say Y when you have a TV board with analog support or with a
77 +         hybrid analog/digital TV chipset.
78 +
79 +         Note: There are several DVB cards that are based on chips that
80 +               support both analog and digital TV. Disabling this option
81 +               will disable support for them.
82 +
83 +config MEDIA_DIGITAL_TV_SUPPORT
84 +       bool "Digital TV support"
85 +       ---help---
86 +         Enable digital TV support.
87 +
88 +         Say Y when you have a board with digital support or a board with
89 +         hybrid digital TV and analog TV.
90 +
91 +config MEDIA_RADIO_SUPPORT
92 +       bool "AM/FM radio receivers/transmitters support"
93 +       ---help---
94 +         Enable AM/FM radio support.
95 +
96 +         Additional info and docs are available on the web at
97 +         <http://linuxtv.org>
98 +
99 +         Say Y when you have a board with radio support.
100 +
101 +         Note: There are several TV cards that are based on chips that
102 +               support radio reception. Disabling this option will
103 +               disable support for them.
104 +
105 +config MEDIA_RC_SUPPORT
106 +       bool "Remote Controller support"
107 +       depends on INPUT
108 +       ---help---
109 +         Enable support for Remote Controllers on Linux. This is
110 +         needed in order to support several video capture adapters,
111 +         standalone IR receivers/transmitters, and RF receivers.
112 +
113 +         Enable this option if you have a video capture board even
114 +         if you don't need IR, as otherwise, you may not be able to
115 +         compile the driver for your adapter.
116 +
117 +         Say Y when you have a TV or an IR device.
118 +
119 +#
120  # Media controller
121 +#      Selectable only for webcam/grabbers, as other drivers don't use it
122  #
123  
124  config MEDIA_CONTROLLER
125         bool "Media Controller API (EXPERIMENTAL)"
126         depends on EXPERIMENTAL
127 +       depends on MEDIA_CAMERA_SUPPORT
128         ---help---
129           Enable the media controller API used to query media devices internal
130           topology and configure it dynamically.
131 @@ -27,31 +89,15 @@ config MEDIA_CONTROLLER
132           This API is mostly used by camera interfaces in embedded platforms.
133  
134  #
135 -# V4L core and enabled API's
136 +# Video4Linux support
137 +#      Only enables if one of the V4L2 types (ATV, webcam, radio) is selected
138  #
139  
140  config VIDEO_DEV
141 -       tristate "Video For Linux"
142 -       ---help---
143 -         V4L core support for video capture and overlay devices, webcams and
144 -         AM/FM radio cards.
145 -
146 -         This kernel includes support for the new Video for Linux Two API,
147 -         (V4L2).
148 -
149 -         Additional info and docs are available on the web at
150 -         <http://linuxtv.org>
151 -
152 -         Documentation for V4L2 is also available on the web at
153 -         <http://bytesex.org/v4l/>.
154 -
155 -         To compile this driver as a module, choose M here: the
156 -         module will be called videodev.
157 -
158 -config VIDEO_V4L2_COMMON
159         tristate
160 -       depends on (I2C || I2C=n) && VIDEO_DEV
161 -       default (I2C || I2C=n) && VIDEO_DEV
162 +       depends on MEDIA_SUPPORT
163 +       depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT
164 +       default y
165  
166  config VIDEO_V4L2_SUBDEV_API
167         bool "V4L2 sub-device userspace API (EXPERIMENTAL)"
168 @@ -62,27 +108,19 @@ config VIDEO_V4L2_SUBDEV_API
169  
170           This API is mostly used by camera interfaces in embedded platforms.
171  
172 +source "drivers/media/v4l2-core/Kconfig"
173 +
174  #
175  # DVB Core
176 +#      Only enables if one of DTV is selected
177  #
178  
179  config DVB_CORE
180 -       tristate "DVB for Linux"
181 +       tristate
182 +       depends on MEDIA_SUPPORT
183 +       depends on MEDIA_DIGITAL_TV_SUPPORT
184 +       default y
185         select CRC32
186 -       help
187 -         DVB core utility functions for device handling, software fallbacks etc.
188 -
189 -         Enable this if you own a DVB/ATSC adapter and want to use it or if
190 -         you compile Linux for a digital SetTopBox.
191 -
192 -         Say Y when you have a DVB or an ATSC card and want to use it.
193 -
194 -         API specs and user tools are available from <http://www.linuxtv.org/>.
195 -
196 -         Please report problems regarding this support to the LinuxDVB
197 -         mailing list.
198 -
199 -         If unsure say N.
200  
201  config DVB_NET
202         bool "DVB Network Support"
203 @@ -97,33 +135,63 @@ config DVB_NET
204           You may want to disable the network support on embedded devices. If
205           unsure say Y.
206  
207 -config VIDEO_MEDIA
208 -       tristate
209 -       default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV)
210 +# This Kconfig option is used by both PCI and USB drivers
211 +config TTPCI_EEPROM
212 +        tristate
213 +        depends on I2C
214 +        default n
215  
216 -comment "Multimedia drivers"
217 +source "drivers/media/dvb-core/Kconfig"
218  
219 -source "drivers/media/common/Kconfig"
220 +comment "Media drivers"
221  source "drivers/media/rc/Kconfig"
222  
223  #
224 -# Tuner drivers for DVB and V4L
225 +# V4L platform/mem2mem drivers
226  #
227  
228 -source "drivers/media/common/tuners/Kconfig"
229 +source "drivers/media/usb/Kconfig"
230 +source "drivers/media/pci/Kconfig"
231 +source "drivers/media/platform/Kconfig"
232 +source "drivers/media/mmc/Kconfig"
233 +source "drivers/media/parport/Kconfig"
234 +source "drivers/media/radio/Kconfig"
235  
236 -#
237 -# Video/Radio/Hybrid adapters
238 -#
239 +comment "Supported FireWire (IEEE 1394) Adapters"
240 +       depends on DVB_CORE && FIREWIRE
241 +source "drivers/media/firewire/Kconfig"
242  
243 -source "drivers/media/video/Kconfig"
244 +# Common driver options
245 +source "drivers/media/common/Kconfig"
246  
247 -source "drivers/media/radio/Kconfig"
248 +comment "Media ancillary drivers (tuners, sensors, i2c, frontends)"
249  
250  #
251 -# DVB adapters
252 +# Ancillary drivers (tuners, i2c, frontends)
253  #
254  
255 -source "drivers/media/dvb/Kconfig"
256 +config MEDIA_SUBDRV_AUTOSELECT
257 +       bool "Autoselect ancillary drivers (tuners, sensors, i2c, frontends)"
258 +       depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT
259 +       default y
260 +       help
261 +         By default, a media driver auto-selects all possible ancillary
262 +         devices such as tuners, sensors, video encoders/decoders and
263 +         frontends, that are used by any of the supported devices.
264 +
265 +         This is generally the right thing to do, except when there
266 +         are strict constraints with regards to the kernel size,
267 +         like on embedded systems.
268 +
269 +         Use this option with care, as deselecting ancillary drivers which
270 +         are, in fact, necessary will result in the lack of the needed
271 +         functionality for your device (it may not tune or may not have
272 +         the needed demodulators).
273 +
274 +         If unsure say Y.
275 +
276 +source "drivers/media/i2c/Kconfig"
277 +source "drivers/media/tuners/Kconfig"
278 +source "drivers/media/dvb-frontends/Kconfig"
279  
280  endif # MEDIA_SUPPORT
281 diff --git a/drivers/media/Makefile b/drivers/media/Makefile
282 index 64755c9..620f275 100644
283 --- a/drivers/media/Makefile
284 +++ b/drivers/media/Makefile
285 @@ -4,11 +4,30 @@
286  
287  media-objs     := media-device.o media-devnode.o media-entity.o
288  
289 +#
290 +# I2C drivers should come before other drivers, otherwise they'll fail
291 +# when compiled as builtin drivers
292 +#
293 +obj-y += i2c/ tuners/
294 +obj-$(CONFIG_DVB_CORE)  += dvb-frontends/
295 +
296 +#
297 +# Now, let's link-in the media core
298 +#
299  ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
300    obj-$(CONFIG_MEDIA_SUPPORT) += media.o
301  endif
302  
303 -obj-y += common/ rc/ video/
304 +obj-$(CONFIG_VIDEO_DEV) += v4l2-core/
305 +obj-$(CONFIG_DVB_CORE)  += dvb-core/
306  
307 +# There are both core and drivers at RC subtree - merge before drivers
308 +obj-y += rc/
309 +
310 +#
311 +# Finally, merge the drivers that require the core
312 +#
313 +
314 +obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ parport/
315  obj-$(CONFIG_VIDEO_DEV) += radio/
316 -obj-$(CONFIG_DVB_CORE)  += dvb/
317 +
318 diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
319 index 769c6f8..d2a436c 100644
320 --- a/drivers/media/common/Kconfig
321 +++ b/drivers/media/common/Kconfig
322 @@ -1,9 +1,10 @@
323 -config VIDEO_SAA7146
324 -       tristate
325 -       depends on I2C && PCI
326 +# Used by common drivers, when they need to ask questions
327 +config MEDIA_COMMON_OPTIONS
328 +       bool
329  
330 -config VIDEO_SAA7146_VV
331 -       tristate
332 -       depends on VIDEO_V4L2
333 -       select VIDEOBUF_DMA_SG
334 -       select VIDEO_SAA7146
335 +comment "common driver options"
336 +       depends on MEDIA_COMMON_OPTIONS
337 +
338 +source "drivers/media/common/b2c2/Kconfig"
339 +source "drivers/media/common/saa7146/Kconfig"
340 +source "drivers/media/common/siano/Kconfig"
341 diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
342 index e3ec963..b8e2e3a 100644
343 --- a/drivers/media/common/Makefile
344 +++ b/drivers/media/common/Makefile
345 @@ -1,6 +1 @@
346 -saa7146-objs    := saa7146_i2c.o saa7146_core.o
347 -saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
348 -
349 -obj-y += tuners/
350 -obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
351 -obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
352 +obj-y += b2c2/ saa7146/ siano/
353 diff --git a/drivers/media/common/b2c2/Kconfig b/drivers/media/common/b2c2/Kconfig
354 new file mode 100644
355 index 0000000..a8c6cdf
356 --- /dev/null
357 +++ b/drivers/media/common/b2c2/Kconfig
358 @@ -0,0 +1,23 @@
359 +config DVB_B2C2_FLEXCOP
360 +       tristate
361 +       depends on DVB_CORE && I2C
362 +       depends on DVB_B2C2_FLEXCOP_PCI || DVB_B2C2_FLEXCOP_USB
363 +       default y
364 +       select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
365 +       select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
366 +       select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
367 +       select DVB_MT312 if MEDIA_SUBDRV_AUTOSELECT
368 +       select DVB_NXT200X if MEDIA_SUBDRV_AUTOSELECT
369 +       select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT
370 +       select DVB_BCM3510 if MEDIA_SUBDRV_AUTOSELECT
371 +       select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
372 +       select DVB_S5H1420 if MEDIA_SUBDRV_AUTOSELECT
373 +       select DVB_TUNER_ITD1000 if MEDIA_SUBDRV_AUTOSELECT
374 +       select DVB_ISL6421 if MEDIA_SUBDRV_AUTOSELECT
375 +       select DVB_CX24123 if MEDIA_SUBDRV_AUTOSELECT
376 +       select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
377 +       select DVB_TUNER_CX24113 if MEDIA_SUBDRV_AUTOSELECT
378 +
379 +# Selected via the PCI or USB flexcop drivers
380 +config DVB_B2C2_FLEXCOP_DEBUG
381 +       bool
382 diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
383 new file mode 100644
384 index 0000000..24993a5
385 --- /dev/null
386 +++ b/drivers/media/common/b2c2/Makefile
387 @@ -0,0 +1,8 @@
388 +b2c2-flexcop-objs += flexcop.o flexcop-fe-tuner.o flexcop-i2c.o
389 +b2c2-flexcop-objs += flexcop-sram.o flexcop-eeprom.o flexcop-misc.o
390 +b2c2-flexcop-objs += flexcop-hw-filter.o
391 +obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
392 +
393 +ccflags-y += -Idrivers/media/dvb-core/
394 +ccflags-y += -Idrivers/media/dvb-frontends/
395 +ccflags-y += -Idrivers/media/tuners/
396 diff --git a/drivers/media/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h
397 new file mode 100644
398 index 0000000..437912e
399 --- /dev/null
400 +++ b/drivers/media/common/b2c2/flexcop-common.h
401 @@ -0,0 +1,185 @@
402 +/*
403 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
404 + * flexcop-common.h - common header file for device-specific source files
405 + * see flexcop.c for copyright information
406 + */
407 +#ifndef __FLEXCOP_COMMON_H__
408 +#define __FLEXCOP_COMMON_H__
409 +
410 +#include <linux/interrupt.h>
411 +#include <linux/pci.h>
412 +#include <linux/mutex.h>
413 +
414 +#include "flexcop-reg.h"
415 +
416 +#include "dmxdev.h"
417 +#include "dvb_demux.h"
418 +#include "dvb_filter.h"
419 +#include "dvb_net.h"
420 +#include "dvb_frontend.h"
421 +
422 +#define FC_MAX_FEED 256
423 +
424 +#ifndef FC_LOG_PREFIX
425 +#warning please define a log prefix for your file, using a default one
426 +#define FC_LOG_PREFIX "b2c2-undef"
427 +#endif
428 +
429 +/* Steal from usb.h */
430 +#undef err
431 +#define err(format, arg...) \
432 +       printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
433 +#undef info
434 +#define info(format, arg...) \
435 +       printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
436 +#undef warn
437 +#define warn(format, arg...) \
438 +       printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
439 +
440 +struct flexcop_dma {
441 +       struct pci_dev *pdev;
442 +
443 +       u8 *cpu_addr0;
444 +       dma_addr_t dma_addr0;
445 +       u8 *cpu_addr1;
446 +       dma_addr_t dma_addr1;
447 +       u32 size; /* size of each address in bytes */
448 +};
449 +
450 +struct flexcop_i2c_adapter {
451 +       struct flexcop_device *fc;
452 +       struct i2c_adapter i2c_adap;
453 +
454 +       u8 no_base_addr;
455 +       flexcop_i2c_port_t port;
456 +};
457 +
458 +/* Control structure for data definitions that are common to
459 + * the B2C2-based PCI and USB devices.
460 + */
461 +struct flexcop_device {
462 +       /* general */
463 +       struct device *dev; /* for firmware_class */
464 +
465 +#define FC_STATE_DVB_INIT 0x01
466 +#define FC_STATE_I2C_INIT 0x02
467 +#define FC_STATE_FE_INIT  0x04
468 +       int init_state;
469 +
470 +       /* device information */
471 +       int has_32_hw_pid_filter;
472 +       flexcop_revision_t rev;
473 +       flexcop_device_type_t dev_type;
474 +       flexcop_bus_t bus_type;
475 +
476 +       /* dvb stuff */
477 +       struct dvb_adapter dvb_adapter;
478 +       struct dvb_frontend *fe;
479 +       struct dvb_net dvbnet;
480 +       struct dvb_demux demux;
481 +       struct dmxdev dmxdev;
482 +       struct dmx_frontend hw_frontend;
483 +       struct dmx_frontend mem_frontend;
484 +       int (*fe_sleep) (struct dvb_frontend *);
485 +
486 +       struct flexcop_i2c_adapter fc_i2c_adap[3];
487 +       struct mutex i2c_mutex;
488 +       struct module *owner;
489 +
490 +       /* options and status */
491 +       int extra_feedcount;
492 +       int feedcount;
493 +       int pid_filtering;
494 +       int fullts_streaming_state;
495 +
496 +       /* bus specific callbacks */
497 +       flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
498 +                       flexcop_ibi_register);
499 +       int (*write_ibi_reg) (struct flexcop_device *,
500 +                       flexcop_ibi_register, flexcop_ibi_value);
501 +       int (*i2c_request) (struct flexcop_i2c_adapter *,
502 +               flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
503 +       int (*stream_control) (struct flexcop_device *, int);
504 +       int (*get_mac_addr) (struct flexcop_device *fc, int extended);
505 +       void *bus_specific;
506 +};
507 +
508 +/* exported prototypes */
509 +
510 +/* from flexcop.c */
511 +void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
512 +void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
513 +
514 +struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
515 +void flexcop_device_kfree(struct flexcop_device *);
516 +
517 +int flexcop_device_initialize(struct flexcop_device *);
518 +void flexcop_device_exit(struct flexcop_device *fc);
519 +void flexcop_reset_block_300(struct flexcop_device *fc);
520 +
521 +/* from flexcop-dma.c */
522 +int flexcop_dma_allocate(struct pci_dev *pdev,
523 +               struct flexcop_dma *dma, u32 size);
524 +void flexcop_dma_free(struct flexcop_dma *dma);
525 +
526 +int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
527 +               flexcop_dma_index_t no, int onoff);
528 +int flexcop_dma_control_size_irq(struct flexcop_device *fc,
529 +               flexcop_dma_index_t no, int onoff);
530 +int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
531 +               flexcop_dma_index_t dma_idx);
532 +int flexcop_dma_xfer_control(struct flexcop_device *fc,
533 +               flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
534 +               int onoff);
535 +int flexcop_dma_config_timer(struct flexcop_device *fc,
536 +               flexcop_dma_index_t dma_idx, u8 cycles);
537 +
538 +/* from flexcop-eeprom.c */
539 +/* the PCI part uses this call to get the MAC address, the USB part has its own */
540 +int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended);
541 +
542 +/* from flexcop-i2c.c */
543 +/* the PCI part uses this a i2c_request callback, whereas the usb part has its own
544 + * one. We have it in flexcop-i2c.c, because it is going via the actual
545 + * I2C-channel of the flexcop.
546 + */
547 +int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
548 +       u8 chipaddr, u8 addr, u8 *buf, u16 len);
549 +
550 +/* from flexcop-sram.c */
551 +int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
552 +       flexcop_sram_dest_target_t target);
553 +void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
554 +void flexcop_sram_ctrl(struct flexcop_device *fc,
555 +               int usb_wan, int sramdma, int maximumfill);
556 +
557 +/* global prototypes for the flexcop-chip */
558 +/* from flexcop-fe-tuner.c */
559 +int flexcop_frontend_init(struct flexcop_device *fc);
560 +void flexcop_frontend_exit(struct flexcop_device *fc);
561 +
562 +/* from flexcop-i2c.c */
563 +int flexcop_i2c_init(struct flexcop_device *fc);
564 +void flexcop_i2c_exit(struct flexcop_device *fc);
565 +
566 +/* from flexcop-sram.c */
567 +int flexcop_sram_init(struct flexcop_device *fc);
568 +
569 +/* from flexcop-misc.c */
570 +void flexcop_determine_revision(struct flexcop_device *fc);
571 +void flexcop_device_name(struct flexcop_device *fc,
572 +               const char *prefix, const char *suffix);
573 +void flexcop_dump_reg(struct flexcop_device *fc,
574 +               flexcop_ibi_register reg, int num);
575 +
576 +/* from flexcop-hw-filter.c */
577 +int flexcop_pid_feed_control(struct flexcop_device *fc,
578 +               struct dvb_demux_feed *dvbdmxfeed, int onoff);
579 +void flexcop_hw_filter_init(struct flexcop_device *fc);
580 +
581 +void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
582 +
583 +void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]);
584 +void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff);
585 +
586 +#endif
587 diff --git a/drivers/media/common/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c
588 new file mode 100644
589 index 0000000..a25373a
590 --- /dev/null
591 +++ b/drivers/media/common/b2c2/flexcop-eeprom.c
592 @@ -0,0 +1,147 @@
593 +/*
594 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
595 + * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
596 + * see flexcop.c for copyright information
597 + */
598 +#include "flexcop.h"
599 +
600 +#if 0
601 +/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
602 +static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
603 +{
604 +       return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
605 +}
606 +
607 +static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
608 +               u32 len, u8 *wbuf, u8 *rbuf, int retries)
609 +{
610 +int i;
611 +
612 +for (i = 0; i < retries; i++) {
613 +       if (eeprom_write(adapter, addr, wbuf, len) == len) {
614 +               if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
615 +                       return 1;
616 +               }
617 +       }
618 +       return 0;
619 +}
620 +
621 +/* These functions could be used to unlock SkyStar2 cards. */
622 +
623 +static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
624 +{
625 +       u8 rbuf[20];
626 +       u8 wbuf[20];
627 +
628 +       if (len != 16)
629 +               return 0;
630 +
631 +       memcpy(wbuf, key, len);
632 +       wbuf[16] = 0;
633 +       wbuf[17] = 0;
634 +       wbuf[18] = 0;
635 +       wbuf[19] = calc_lrc(wbuf, 19);
636 +       return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
637 +}
638 +
639 +static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
640 +{
641 +       u8 buf[20];
642 +
643 +       if (len != 16)
644 +               return 0;
645 +
646 +       if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
647 +               return 0;
648 +
649 +       memcpy(key, buf, len);
650 +       return 1;
651 +}
652 +
653 +static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
654 +{
655 +       u8 tmp[8];
656 +
657 +       if (type != 0) {
658 +               tmp[0] = mac[0];
659 +               tmp[1] = mac[1];
660 +               tmp[2] = mac[2];
661 +               tmp[3] = mac[5];
662 +               tmp[4] = mac[6];
663 +               tmp[5] = mac[7];
664 +       } else {
665 +               tmp[0] = mac[0];
666 +               tmp[1] = mac[1];
667 +               tmp[2] = mac[2];
668 +               tmp[3] = mac[3];
669 +               tmp[4] = mac[4];
670 +               tmp[5] = mac[5];
671 +       }
672 +
673 +       tmp[6] = 0;
674 +       tmp[7] = calc_lrc(tmp, 7);
675 +
676 +       if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
677 +               return 1;
678 +       return 0;
679 +}
680 +
681 +static int flexcop_eeprom_read(struct flexcop_device *fc,
682 +               u16 addr, u8 *buf, u16 len)
683 +{
684 +       return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
685 +}
686 +
687 +#endif
688 +
689 +static u8 calc_lrc(u8 *buf, int len)
690 +{
691 +       int i;
692 +       u8 sum = 0;
693 +       for (i = 0; i < len; i++)
694 +               sum = sum ^ buf[i];
695 +       return sum;
696 +}
697 +
698 +static int flexcop_eeprom_request(struct flexcop_device *fc,
699 +       flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
700 +{
701 +       int i,ret = 0;
702 +       u8 chipaddr =  0x50 | ((addr >> 8) & 3);
703 +       for (i = 0; i < retries; i++) {
704 +               ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr,
705 +                       addr & 0xff, buf, len);
706 +               if (ret == 0)
707 +                       break;
708 +       }
709 +       return ret;
710 +}
711 +
712 +static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
713 +               u8 *buf, u16 len, int retries)
714 +{
715 +       int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
716 +       if (ret == 0)
717 +               if (calc_lrc(buf, len - 1) != buf[len - 1])
718 +                       ret = -EINVAL;
719 +       return ret;
720 +}
721 +
722 +/* JJ's comment about extended == 1: it is not presently used anywhere but was
723 + * added to the low-level functions for possible support of EUI64 */
724 +int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
725 +{
726 +       u8 buf[8];
727 +       int ret = 0;
728 +
729 +       if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
730 +               if (extended != 0) {
731 +                       err("TODO: extended (EUI64) MAC addresses aren't "
732 +                               "completely supported yet");
733 +                       ret = -EINVAL;
734 +               } else
735 +                       memcpy(fc->dvb_adapter.proposed_mac,buf,6);
736 +       }
737 +       return ret;
738 +}
739 +EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
740 diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
741 new file mode 100644
742 index 0000000..850a6c6
743 --- /dev/null
744 +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
745 @@ -0,0 +1,678 @@
746 +/*
747 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
748 + * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
749 + * see flexcop.c for copyright information
750 + */
751 +#include <media/tuner.h>
752 +#include "flexcop.h"
753 +#include "mt312.h"
754 +#include "stv0299.h"
755 +#include "s5h1420.h"
756 +#include "itd1000.h"
757 +#include "cx24113.h"
758 +#include "cx24123.h"
759 +#include "isl6421.h"
760 +#include "mt352.h"
761 +#include "bcm3510.h"
762 +#include "nxt200x.h"
763 +#include "dvb-pll.h"
764 +#include "lgdt330x.h"
765 +#include "tuner-simple.h"
766 +#include "stv0297.h"
767 +
768 +
769 +/* Can we use the specified front-end?  Remember that if we are compiled
770 + * into the kernel we can't call code that's in modules.  */
771 +#define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \
772 +       (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE)))
773 +
774 +/* lnb control */
775 +#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
776 +static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
777 +{
778 +       struct flexcop_device *fc = fe->dvb->priv;
779 +       flexcop_ibi_value v;
780 +       deb_tuner("polarity/voltage = %u\n", voltage);
781 +
782 +       v = fc->read_ibi_reg(fc, misc_204);
783 +       switch (voltage) {
784 +       case SEC_VOLTAGE_OFF:
785 +               v.misc_204.ACPI1_sig = 1;
786 +               break;
787 +       case SEC_VOLTAGE_13:
788 +               v.misc_204.ACPI1_sig = 0;
789 +               v.misc_204.LNB_L_H_sig = 0;
790 +               break;
791 +       case SEC_VOLTAGE_18:
792 +               v.misc_204.ACPI1_sig = 0;
793 +               v.misc_204.LNB_L_H_sig = 1;
794 +               break;
795 +       default:
796 +               err("unknown SEC_VOLTAGE value");
797 +               return -EINVAL;
798 +       }
799 +       return fc->write_ibi_reg(fc, misc_204, v);
800 +}
801 +#endif
802 +
803 +#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
804 +static int flexcop_sleep(struct dvb_frontend* fe)
805 +{
806 +       struct flexcop_device *fc = fe->dvb->priv;
807 +       if (fc->fe_sleep)
808 +               return fc->fe_sleep(fe);
809 +       return 0;
810 +}
811 +#endif
812 +
813 +/* SkyStar2 DVB-S rev 2.3 */
814 +#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
815 +static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
816 +{
817 +/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
818 +       struct flexcop_device *fc = fe->dvb->priv;
819 +       flexcop_ibi_value v;
820 +       u16 ax;
821 +       v.raw = 0;
822 +       deb_tuner("tone = %u\n",tone);
823 +
824 +       switch (tone) {
825 +       case SEC_TONE_ON:
826 +               ax = 0x01ff;
827 +               break;
828 +       case SEC_TONE_OFF:
829 +               ax = 0;
830 +               break;
831 +       default:
832 +               err("unknown SEC_TONE value");
833 +               return -EINVAL;
834 +       }
835 +
836 +       v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
837 +       v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
838 +       v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
839 +       return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
840 +}
841 +
842 +static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
843 +{
844 +       flexcop_set_tone(fe, SEC_TONE_ON);
845 +       udelay(data ? 500 : 1000);
846 +       flexcop_set_tone(fe, SEC_TONE_OFF);
847 +       udelay(data ? 1000 : 500);
848 +}
849 +
850 +static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
851 +{
852 +       int i, par = 1, d;
853 +       for (i = 7; i >= 0; i--) {
854 +               d = (data >> i) & 1;
855 +               par ^= d;
856 +               flexcop_diseqc_send_bit(fe, d);
857 +       }
858 +       flexcop_diseqc_send_bit(fe, par);
859 +}
860 +
861 +static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
862 +       int len, u8 *msg, unsigned long burst)
863 +{
864 +       int i;
865 +
866 +       flexcop_set_tone(fe, SEC_TONE_OFF);
867 +       mdelay(16);
868 +
869 +       for (i = 0; i < len; i++)
870 +               flexcop_diseqc_send_byte(fe,msg[i]);
871 +       mdelay(16);
872 +
873 +       if (burst != -1) {
874 +               if (burst)
875 +                       flexcop_diseqc_send_byte(fe, 0xff);
876 +               else {
877 +                       flexcop_set_tone(fe, SEC_TONE_ON);
878 +                       mdelay(12);
879 +                       udelay(500);
880 +                       flexcop_set_tone(fe, SEC_TONE_OFF);
881 +               }
882 +               msleep(20);
883 +       }
884 +       return 0;
885 +}
886 +
887 +static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
888 +       struct dvb_diseqc_master_cmd *cmd)
889 +{
890 +       return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
891 +}
892 +
893 +static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
894 +       fe_sec_mini_cmd_t minicmd)
895 +{
896 +       return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
897 +}
898 +
899 +static struct mt312_config skystar23_samsung_tbdu18132_config = {
900 +       .demod_address = 0x0e,
901 +};
902 +
903 +static int skystar2_rev23_attach(struct flexcop_device *fc,
904 +       struct i2c_adapter *i2c)
905 +{
906 +       struct dvb_frontend_ops *ops;
907 +
908 +       fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
909 +       if (!fc->fe)
910 +               return 0;
911 +
912 +       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
913 +                       DVB_PLL_SAMSUNG_TBDU18132))
914 +               return 0;
915 +
916 +       ops = &fc->fe->ops;
917 +       ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
918 +       ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
919 +       ops->set_tone               = flexcop_set_tone;
920 +       ops->set_voltage            = flexcop_set_voltage;
921 +       fc->fe_sleep                = ops->sleep;
922 +       ops->sleep                  = flexcop_sleep;
923 +       return 1;
924 +}
925 +#else
926 +#define skystar2_rev23_attach NULL
927 +#endif
928 +
929 +/* SkyStar2 DVB-S rev 2.6 */
930 +#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
931 +static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
932 +       u32 srate, u32 ratio)
933 +{
934 +       u8 aclk = 0;
935 +       u8 bclk = 0;
936 +
937 +       if (srate < 1500000) {
938 +               aclk = 0xb7; bclk = 0x47;
939 +       } else if (srate < 3000000) {
940 +               aclk = 0xb7; bclk = 0x4b;
941 +       } else if (srate < 7000000) {
942 +               aclk = 0xb7; bclk = 0x4f;
943 +       } else if (srate < 14000000) {
944 +               aclk = 0xb7; bclk = 0x53;
945 +       } else if (srate < 30000000) {
946 +               aclk = 0xb6; bclk = 0x53;
947 +       } else if (srate < 45000000) {
948 +               aclk = 0xb4; bclk = 0x51;
949 +       }
950 +
951 +       stv0299_writereg(fe, 0x13, aclk);
952 +       stv0299_writereg(fe, 0x14, bclk);
953 +       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
954 +       stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
955 +       stv0299_writereg(fe, 0x21,  ratio        & 0xf0);
956 +       return 0;
957 +}
958 +
959 +static u8 samsung_tbmu24112_inittab[] = {
960 +       0x01, 0x15,
961 +       0x02, 0x30,
962 +       0x03, 0x00,
963 +       0x04, 0x7D,
964 +       0x05, 0x35,
965 +       0x06, 0x02,
966 +       0x07, 0x00,
967 +       0x08, 0xC3,
968 +       0x0C, 0x00,
969 +       0x0D, 0x81,
970 +       0x0E, 0x23,
971 +       0x0F, 0x12,
972 +       0x10, 0x7E,
973 +       0x11, 0x84,
974 +       0x12, 0xB9,
975 +       0x13, 0x88,
976 +       0x14, 0x89,
977 +       0x15, 0xC9,
978 +       0x16, 0x00,
979 +       0x17, 0x5C,
980 +       0x18, 0x00,
981 +       0x19, 0x00,
982 +       0x1A, 0x00,
983 +       0x1C, 0x00,
984 +       0x1D, 0x00,
985 +       0x1E, 0x00,
986 +       0x1F, 0x3A,
987 +       0x20, 0x2E,
988 +       0x21, 0x80,
989 +       0x22, 0xFF,
990 +       0x23, 0xC1,
991 +       0x28, 0x00,
992 +       0x29, 0x1E,
993 +       0x2A, 0x14,
994 +       0x2B, 0x0F,
995 +       0x2C, 0x09,
996 +       0x2D, 0x05,
997 +       0x31, 0x1F,
998 +       0x32, 0x19,
999 +       0x33, 0xFE,
1000 +       0x34, 0x93,
1001 +       0xff, 0xff,
1002 +};
1003 +
1004 +static struct stv0299_config samsung_tbmu24112_config = {
1005 +       .demod_address = 0x68,
1006 +       .inittab = samsung_tbmu24112_inittab,
1007 +       .mclk = 88000000UL,
1008 +       .invert = 0,
1009 +       .skip_reinit = 0,
1010 +       .lock_output = STV0299_LOCKOUTPUT_LK,
1011 +       .volt13_op0_op1 = STV0299_VOLT13_OP1,
1012 +       .min_delay_ms = 100,
1013 +       .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
1014 +};
1015 +
1016 +static int skystar2_rev26_attach(struct flexcop_device *fc,
1017 +       struct i2c_adapter *i2c)
1018 +{
1019 +       fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
1020 +       if (!fc->fe)
1021 +               return 0;
1022 +
1023 +       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
1024 +                       DVB_PLL_SAMSUNG_TBMU24112))
1025 +               return 0;
1026 +
1027 +       fc->fe->ops.set_voltage = flexcop_set_voltage;
1028 +       fc->fe_sleep = fc->fe->ops.sleep;
1029 +       fc->fe->ops.sleep = flexcop_sleep;
1030 +       return 1;
1031 +
1032 +}
1033 +#else
1034 +#define skystar2_rev26_attach NULL
1035 +#endif
1036 +
1037 +/* SkyStar2 DVB-S rev 2.7 */
1038 +#if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000)
1039 +static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
1040 +       .demod_address = 0x53,
1041 +       .invert = 1,
1042 +       .repeated_start_workaround = 1,
1043 +       .serial_mpeg = 1,
1044 +};
1045 +
1046 +static struct itd1000_config skystar2_rev2_7_itd1000_config = {
1047 +       .i2c_address = 0x61,
1048 +};
1049 +
1050 +static int skystar2_rev27_attach(struct flexcop_device *fc,
1051 +       struct i2c_adapter *i2c)
1052 +{
1053 +       flexcop_ibi_value r108;
1054 +       struct i2c_adapter *i2c_tuner;
1055 +
1056 +       /* enable no_base_addr - no repeated start when reading */
1057 +       fc->fc_i2c_adap[0].no_base_addr = 1;
1058 +       fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
1059 +                           i2c);
1060 +       if (!fc->fe)
1061 +               goto fail;
1062 +
1063 +       i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
1064 +       if (!i2c_tuner)
1065 +               goto fail;
1066 +
1067 +       fc->fe_sleep = fc->fe->ops.sleep;
1068 +       fc->fe->ops.sleep = flexcop_sleep;
1069 +
1070 +       /* enable no_base_addr - no repeated start when reading */
1071 +       fc->fc_i2c_adap[2].no_base_addr = 1;
1072 +       if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
1073 +                       0x08, 1, 1)) {
1074 +               err("ISL6421 could NOT be attached");
1075 +               goto fail_isl;
1076 +       }
1077 +       info("ISL6421 successfully attached");
1078 +
1079 +       /* the ITD1000 requires a lower i2c clock - is it a problem ? */
1080 +       r108.raw = 0x00000506;
1081 +       fc->write_ibi_reg(fc, tw_sm_c_108, r108);
1082 +       if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
1083 +                       &skystar2_rev2_7_itd1000_config)) {
1084 +               err("ITD1000 could NOT be attached");
1085 +               /* Should i2c clock be restored? */
1086 +               goto fail_isl;
1087 +       }
1088 +       info("ITD1000 successfully attached");
1089 +
1090 +       return 1;
1091 +
1092 +fail_isl:
1093 +       fc->fc_i2c_adap[2].no_base_addr = 0;
1094 +fail:
1095 +       /* for the next devices we need it again */
1096 +       fc->fc_i2c_adap[0].no_base_addr = 0;
1097 +       return 0;
1098 +}
1099 +#else
1100 +#define skystar2_rev27_attach NULL
1101 +#endif
1102 +
1103 +/* SkyStar2 rev 2.8 */
1104 +#if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113)
1105 +static struct cx24123_config skystar2_rev2_8_cx24123_config = {
1106 +       .demod_address = 0x55,
1107 +       .dont_use_pll = 1,
1108 +       .agc_callback = cx24113_agc_callback,
1109 +};
1110 +
1111 +static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
1112 +       .i2c_addr = 0x54,
1113 +       .xtal_khz = 10111,
1114 +};
1115 +
1116 +static int skystar2_rev28_attach(struct flexcop_device *fc,
1117 +       struct i2c_adapter *i2c)
1118 +{
1119 +       struct i2c_adapter *i2c_tuner;
1120 +
1121 +       fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
1122 +                           i2c);
1123 +       if (!fc->fe)
1124 +               return 0;
1125 +
1126 +       i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
1127 +       if (!i2c_tuner)
1128 +               return 0;
1129 +
1130 +       if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
1131 +                       i2c_tuner)) {
1132 +               err("CX24113 could NOT be attached");
1133 +               return 0;
1134 +       }
1135 +       info("CX24113 successfully attached");
1136 +
1137 +       fc->fc_i2c_adap[2].no_base_addr = 1;
1138 +       if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
1139 +                       0x08, 0, 0)) {
1140 +               err("ISL6421 could NOT be attached");
1141 +               fc->fc_i2c_adap[2].no_base_addr = 0;
1142 +               return 0;
1143 +       }
1144 +       info("ISL6421 successfully attached");
1145 +       /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
1146 +        * IR-receiver (PIC16F818) - but the card has no input for that ??? */
1147 +       return 1;
1148 +}
1149 +#else
1150 +#define skystar2_rev28_attach NULL
1151 +#endif
1152 +
1153 +/* AirStar DVB-T */
1154 +#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
1155 +static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
1156 +{
1157 +       static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
1158 +       static u8 mt352_reset[] = { 0x50, 0x80 };
1159 +       static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
1160 +       static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
1161 +       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
1162 +
1163 +       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
1164 +       udelay(2000);
1165 +       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
1166 +       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
1167 +       mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
1168 +       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
1169 +       return 0;
1170 +}
1171 +
1172 +static struct mt352_config samsung_tdtc9251dh0_config = {
1173 +       .demod_address = 0x0f,
1174 +       .demod_init    = samsung_tdtc9251dh0_demod_init,
1175 +};
1176 +
1177 +static int airstar_dvbt_attach(struct flexcop_device *fc,
1178 +       struct i2c_adapter *i2c)
1179 +{
1180 +       fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
1181 +       if (!fc->fe)
1182 +               return 0;
1183 +
1184 +       return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
1185 +                           DVB_PLL_SAMSUNG_TDTC9251DH0);
1186 +}
1187 +#else
1188 +#define airstar_dvbt_attach NULL
1189 +#endif
1190 +
1191 +/* AirStar ATSC 1st generation */
1192 +#if FE_SUPPORTED(BCM3510)
1193 +static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
1194 +       const struct firmware **fw, char* name)
1195 +{
1196 +       struct flexcop_device *fc = fe->dvb->priv;
1197 +       return request_firmware(fw, name, fc->dev);
1198 +}
1199 +
1200 +static struct bcm3510_config air2pc_atsc_first_gen_config = {
1201 +       .demod_address    = 0x0f,
1202 +       .request_firmware = flexcop_fe_request_firmware,
1203 +};
1204 +
1205 +static int airstar_atsc1_attach(struct flexcop_device *fc,
1206 +       struct i2c_adapter *i2c)
1207 +{
1208 +       fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
1209 +       return fc->fe != NULL;
1210 +}
1211 +#else
1212 +#define airstar_atsc1_attach NULL
1213 +#endif
1214 +
1215 +/* AirStar ATSC 2nd generation */
1216 +#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
1217 +static struct nxt200x_config samsung_tbmv_config = {
1218 +       .demod_address = 0x0a,
1219 +};
1220 +
1221 +static int airstar_atsc2_attach(struct flexcop_device *fc,
1222 +       struct i2c_adapter *i2c)
1223 +{
1224 +       fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
1225 +       if (!fc->fe)
1226 +               return 0;
1227 +
1228 +       return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
1229 +                           DVB_PLL_SAMSUNG_TBMV);
1230 +}
1231 +#else
1232 +#define airstar_atsc2_attach NULL
1233 +#endif
1234 +
1235 +/* AirStar ATSC 3rd generation */
1236 +#if FE_SUPPORTED(LGDT330X)
1237 +static struct lgdt330x_config air2pc_atsc_hd5000_config = {
1238 +       .demod_address       = 0x59,
1239 +       .demod_chip          = LGDT3303,
1240 +       .serial_mpeg         = 0x04,
1241 +       .clock_polarity_flip = 1,
1242 +};
1243 +
1244 +static int airstar_atsc3_attach(struct flexcop_device *fc,
1245 +       struct i2c_adapter *i2c)
1246 +{
1247 +       fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
1248 +       if (!fc->fe)
1249 +               return 0;
1250 +
1251 +       return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
1252 +                           TUNER_LG_TDVS_H06XF);
1253 +}
1254 +#else
1255 +#define airstar_atsc3_attach NULL
1256 +#endif
1257 +
1258 +/* CableStar2 DVB-C */
1259 +#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
1260 +static u8 alps_tdee4_stv0297_inittab[] = {
1261 +       0x80, 0x01,
1262 +       0x80, 0x00,
1263 +       0x81, 0x01,
1264 +       0x81, 0x00,
1265 +       0x00, 0x48,
1266 +       0x01, 0x58,
1267 +       0x03, 0x00,
1268 +       0x04, 0x00,
1269 +       0x07, 0x00,
1270 +       0x08, 0x00,
1271 +       0x30, 0xff,
1272 +       0x31, 0x9d,
1273 +       0x32, 0xff,
1274 +       0x33, 0x00,
1275 +       0x34, 0x29,
1276 +       0x35, 0x55,
1277 +       0x36, 0x80,
1278 +       0x37, 0x6e,
1279 +       0x38, 0x9c,
1280 +       0x40, 0x1a,
1281 +       0x41, 0xfe,
1282 +       0x42, 0x33,
1283 +       0x43, 0x00,
1284 +       0x44, 0xff,
1285 +       0x45, 0x00,
1286 +       0x46, 0x00,
1287 +       0x49, 0x04,
1288 +       0x4a, 0x51,
1289 +       0x4b, 0xf8,
1290 +       0x52, 0x30,
1291 +       0x53, 0x06,
1292 +       0x59, 0x06,
1293 +       0x5a, 0x5e,
1294 +       0x5b, 0x04,
1295 +       0x61, 0x49,
1296 +       0x62, 0x0a,
1297 +       0x70, 0xff,
1298 +       0x71, 0x04,
1299 +       0x72, 0x00,
1300 +       0x73, 0x00,
1301 +       0x74, 0x0c,
1302 +       0x80, 0x20,
1303 +       0x81, 0x00,
1304 +       0x82, 0x30,
1305 +       0x83, 0x00,
1306 +       0x84, 0x04,
1307 +       0x85, 0x22,
1308 +       0x86, 0x08,
1309 +       0x87, 0x1b,
1310 +       0x88, 0x00,
1311 +       0x89, 0x00,
1312 +       0x90, 0x00,
1313 +       0x91, 0x04,
1314 +       0xa0, 0x86,
1315 +       0xa1, 0x00,
1316 +       0xa2, 0x00,
1317 +       0xb0, 0x91,
1318 +       0xb1, 0x0b,
1319 +       0xc0, 0x5b,
1320 +       0xc1, 0x10,
1321 +       0xc2, 0x12,
1322 +       0xd0, 0x02,
1323 +       0xd1, 0x00,
1324 +       0xd2, 0x00,
1325 +       0xd3, 0x00,
1326 +       0xd4, 0x02,
1327 +       0xd5, 0x00,
1328 +       0xde, 0x00,
1329 +       0xdf, 0x01,
1330 +       0xff, 0xff,
1331 +};
1332 +
1333 +static struct stv0297_config alps_tdee4_stv0297_config = {
1334 +       .demod_address = 0x1c,
1335 +       .inittab = alps_tdee4_stv0297_inittab,
1336 +};
1337 +
1338 +static int cablestar2_attach(struct flexcop_device *fc,
1339 +       struct i2c_adapter *i2c)
1340 +{
1341 +       fc->fc_i2c_adap[0].no_base_addr = 1;
1342 +       fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
1343 +       if (!fc->fe)
1344 +               goto fail;
1345 +
1346 +       /* This tuner doesn't use the stv0297's I2C gate, but instead the
1347 +        * tuner is connected to a different flexcop I2C adapter.  */
1348 +       if (fc->fe->ops.i2c_gate_ctrl)
1349 +               fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
1350 +       fc->fe->ops.i2c_gate_ctrl = NULL;
1351 +
1352 +       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
1353 +                       &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
1354 +               goto fail;
1355 +
1356 +       return 1;
1357 +
1358 +fail:
1359 +       /* Reset for next frontend to try */
1360 +       fc->fc_i2c_adap[0].no_base_addr = 0;
1361 +       return 0;
1362 +}
1363 +#else
1364 +#define cablestar2_attach NULL
1365 +#endif
1366 +
1367 +static struct {
1368 +       flexcop_device_type_t type;
1369 +       int (*attach)(struct flexcop_device *, struct i2c_adapter *);
1370 +} flexcop_frontends[] = {
1371 +       { FC_SKY_REV27, skystar2_rev27_attach },
1372 +       { FC_SKY_REV28, skystar2_rev28_attach },
1373 +       { FC_SKY_REV26, skystar2_rev26_attach },
1374 +       { FC_AIR_DVBT, airstar_dvbt_attach },
1375 +       { FC_AIR_ATSC2, airstar_atsc2_attach },
1376 +       { FC_AIR_ATSC3, airstar_atsc3_attach },
1377 +       { FC_AIR_ATSC1, airstar_atsc1_attach },
1378 +       { FC_CABLE, cablestar2_attach },
1379 +       { FC_SKY_REV23, skystar2_rev23_attach },
1380 +};
1381 +
1382 +/* try to figure out the frontend */
1383 +int flexcop_frontend_init(struct flexcop_device *fc)
1384 +{
1385 +       int i;
1386 +       for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
1387 +               if (!flexcop_frontends[i].attach)
1388 +                       continue;
1389 +               /* type needs to be set before, because of some workarounds
1390 +                * done based on the probed card type */
1391 +               fc->dev_type = flexcop_frontends[i].type;
1392 +               if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
1393 +                       goto fe_found;
1394 +               /* Clean up partially attached frontend */
1395 +               if (fc->fe) {
1396 +                       dvb_frontend_detach(fc->fe);
1397 +                       fc->fe = NULL;
1398 +               }
1399 +       }
1400 +       fc->dev_type = FC_UNK;
1401 +       err("no frontend driver found for this B2C2/FlexCop adapter");
1402 +       return -ENODEV;
1403 +
1404 +fe_found:
1405 +       info("found '%s' .", fc->fe->ops.info.name);
1406 +       if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
1407 +               err("frontend registration failed!");
1408 +               dvb_frontend_detach(fc->fe);
1409 +               fc->fe = NULL;
1410 +               return -EINVAL;
1411 +       }
1412 +       fc->init_state |= FC_STATE_FE_INIT;
1413 +       return 0;
1414 +}
1415 +
1416 +void flexcop_frontend_exit(struct flexcop_device *fc)
1417 +{
1418 +       if (fc->init_state & FC_STATE_FE_INIT) {
1419 +               dvb_unregister_frontend(fc->fe);
1420 +               dvb_frontend_detach(fc->fe);
1421 +       }
1422 +       fc->init_state &= ~FC_STATE_FE_INIT;
1423 +}
1424 diff --git a/drivers/media/common/b2c2/flexcop-hw-filter.c b/drivers/media/common/b2c2/flexcop-hw-filter.c
1425 new file mode 100644
1426 index 0000000..77e4547
1427 --- /dev/null
1428 +++ b/drivers/media/common/b2c2/flexcop-hw-filter.c
1429 @@ -0,0 +1,232 @@
1430 +/*
1431 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
1432 + * flexcop-hw-filter.c - pid and mac address filtering and control functions
1433 + * see flexcop.c for copyright information
1434 + */
1435 +#include "flexcop.h"
1436 +
1437 +static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
1438 +{
1439 +       flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
1440 +       deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
1441 +}
1442 +
1443 +void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
1444 +{
1445 +       flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
1446 +}
1447 +
1448 +static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
1449 +{
1450 +       flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
1451 +}
1452 +
1453 +void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
1454 +{
1455 +       flexcop_ibi_value v418, v41c;
1456 +       v41c = fc->read_ibi_reg(fc, mac_address_41c);
1457 +
1458 +       v418.mac_address_418.MAC1 = mac[0];
1459 +       v418.mac_address_418.MAC2 = mac[1];
1460 +       v418.mac_address_418.MAC3 = mac[2];
1461 +       v418.mac_address_418.MAC6 = mac[3];
1462 +       v41c.mac_address_41c.MAC7 = mac[4];
1463 +       v41c.mac_address_41c.MAC8 = mac[5];
1464 +
1465 +       fc->write_ibi_reg(fc, mac_address_418, v418);
1466 +       fc->write_ibi_reg(fc, mac_address_41c, v41c);
1467 +}
1468 +
1469 +void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
1470 +{
1471 +       flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
1472 +}
1473 +
1474 +static void flexcop_pid_group_filter(struct flexcop_device *fc,
1475 +               u16 pid, u16 mask)
1476 +{
1477 +       /* index_reg_310.extra_index_reg need to 0 or 7 to work */
1478 +       flexcop_ibi_value v30c;
1479 +       v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
1480 +       v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
1481 +       fc->write_ibi_reg(fc, pid_filter_30c, v30c);
1482 +}
1483 +
1484 +static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
1485 +{
1486 +       flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
1487 +}
1488 +
1489 +/* this fancy define reduces the code size of the quite similar PID controlling of
1490 + * the first 6 PIDs
1491 + */
1492 +
1493 +#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
1494 +       flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
1495 +v208 = fc->read_ibi_reg(fc, ctrl_208); \
1496 +vpid.vregname.field = onoff ? pid : 0x1fff; \
1497 +vpid.vregname.trans_field = transval; \
1498 +v208.ctrl_208.enablefield = onoff; \
1499 +fc->write_ibi_reg(fc, vregname, vpid); \
1500 +fc->write_ibi_reg(fc, ctrl_208, v208);
1501 +
1502 +static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
1503 +               u16 pid, int onoff)
1504 +{
1505 +       pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
1506 +                       Stream1_trans, 0);
1507 +}
1508 +
1509 +static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
1510 +               u16 pid, int onoff)
1511 +{
1512 +       pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
1513 +                       Stream2_trans, 0);
1514 +}
1515 +
1516 +static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
1517 +               u16 pid, int onoff)
1518 +{
1519 +       pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
1520 +}
1521 +
1522 +static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
1523 +               u16 pid, int onoff)
1524 +{
1525 +       pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
1526 +}
1527 +
1528 +static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
1529 +               u16 pid, int onoff)
1530 +{
1531 +       pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
1532 +}
1533 +
1534 +static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
1535 +               u16 pid, int onoff)
1536 +{
1537 +       pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
1538 +}
1539 +
1540 +static void flexcop_pid_control(struct flexcop_device *fc,
1541 +               int index, u16 pid, int onoff)
1542 +{
1543 +       if (pid == 0x2000)
1544 +               return;
1545 +
1546 +       deb_ts("setting pid: %5d %04x at index %d '%s'\n",
1547 +                       pid, pid, index, onoff ? "on" : "off");
1548 +
1549 +       /* We could use bit magic here to reduce source code size.
1550 +        * I decided against it, but to use the real register names */
1551 +       switch (index) {
1552 +       case 0:
1553 +               flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
1554 +               break;
1555 +       case 1:
1556 +               flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
1557 +               break;
1558 +       case 2:
1559 +               flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
1560 +               break;
1561 +       case 3:
1562 +               flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
1563 +               break;
1564 +       case 4:
1565 +               flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
1566 +               break;
1567 +       case 5:
1568 +               flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
1569 +               break;
1570 +       default:
1571 +               if (fc->has_32_hw_pid_filter && index < 38) {
1572 +                       flexcop_ibi_value vpid, vid;
1573 +
1574 +                       /* set the index */
1575 +                       vid = fc->read_ibi_reg(fc, index_reg_310);
1576 +                       vid.index_reg_310.index_reg = index - 6;
1577 +                       fc->write_ibi_reg(fc, index_reg_310, vid);
1578 +
1579 +                       vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
1580 +                       vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
1581 +                       vpid.pid_n_reg_314.PID_enable_bit = onoff;
1582 +                       fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
1583 +               }
1584 +               break;
1585 +       }
1586 +}
1587 +
1588 +static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
1589 +{
1590 +       if (fc->fullts_streaming_state != onoff) {
1591 +               deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
1592 +               flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
1593 +               flexcop_pid_group_filter_ctrl(fc, onoff);
1594 +               fc->fullts_streaming_state = onoff;
1595 +       }
1596 +       return 0;
1597 +}
1598 +
1599 +int flexcop_pid_feed_control(struct flexcop_device *fc,
1600 +               struct dvb_demux_feed *dvbdmxfeed, int onoff)
1601 +{
1602 +       int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
1603 +
1604 +       fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
1605 +       if (dvbdmxfeed->index >= max_pid_filter)
1606 +               fc->extra_feedcount += onoff ? 1 : -1;
1607 +
1608 +       /* toggle complete-TS-streaming when:
1609 +        * - pid_filtering is not enabled and it is the first or last feed requested
1610 +        * - pid_filtering is enabled,
1611 +        *   - but the number of requested feeds is exceeded
1612 +        *   - or the requested pid is 0x2000 */
1613 +
1614 +       if (!fc->pid_filtering && fc->feedcount == onoff)
1615 +               flexcop_toggle_fullts_streaming(fc, onoff);
1616 +
1617 +       if (fc->pid_filtering) {
1618 +               flexcop_pid_control \
1619 +                       (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
1620 +
1621 +               if (fc->extra_feedcount > 0)
1622 +                       flexcop_toggle_fullts_streaming(fc, 1);
1623 +               else if (dvbdmxfeed->pid == 0x2000)
1624 +                       flexcop_toggle_fullts_streaming(fc, onoff);
1625 +               else
1626 +                       flexcop_toggle_fullts_streaming(fc, 0);
1627 +       }
1628 +
1629 +       /* if it was the first or last feed request change the stream-status */
1630 +       if (fc->feedcount == onoff) {
1631 +               flexcop_rcv_data_ctrl(fc, onoff);
1632 +               if (fc->stream_control) /* device specific stream control */
1633 +                       fc->stream_control(fc, onoff);
1634 +
1635 +               /* feeding stopped -> reset the flexcop filter*/
1636 +               if (onoff == 0) {
1637 +                       flexcop_reset_block_300(fc);
1638 +                       flexcop_hw_filter_init(fc);
1639 +               }
1640 +       }
1641 +       return 0;
1642 +}
1643 +EXPORT_SYMBOL(flexcop_pid_feed_control);
1644 +
1645 +void flexcop_hw_filter_init(struct flexcop_device *fc)
1646 +{
1647 +       int i;
1648 +       flexcop_ibi_value v;
1649 +       for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
1650 +               flexcop_pid_control(fc, i, 0x1fff, 0);
1651 +
1652 +       flexcop_pid_group_filter(fc, 0, 0x1fe0);
1653 +       flexcop_pid_group_filter_ctrl(fc, 0);
1654 +
1655 +       v = fc->read_ibi_reg(fc, pid_filter_308);
1656 +       v.pid_filter_308.EMM_filter_4 = 1;
1657 +       v.pid_filter_308.EMM_filter_6 = 0;
1658 +       fc->write_ibi_reg(fc, pid_filter_308, v);
1659 +
1660 +       flexcop_null_filter_ctrl(fc, 1);
1661 +}
1662 diff --git a/drivers/media/common/b2c2/flexcop-i2c.c b/drivers/media/common/b2c2/flexcop-i2c.c
1663 new file mode 100644
1664 index 0000000..965d5eb
1665 --- /dev/null
1666 +++ b/drivers/media/common/b2c2/flexcop-i2c.c
1667 @@ -0,0 +1,288 @@
1668 +/*
1669 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
1670 + * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
1671 + * see flexcop.c for copyright information
1672 + */
1673 +#include "flexcop.h"
1674 +
1675 +#define FC_MAX_I2C_RETRIES 100000
1676 +
1677 +static int flexcop_i2c_operation(struct flexcop_device *fc,
1678 +               flexcop_ibi_value *r100)
1679 +{
1680 +       int i;
1681 +       flexcop_ibi_value r;
1682 +
1683 +       r100->tw_sm_c_100.working_start = 1;
1684 +       deb_i2c("r100 before: %08x\n",r100->raw);
1685 +
1686 +       fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero);
1687 +       fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */
1688 +
1689 +       for (i = 0; i < FC_MAX_I2C_RETRIES; i++) {
1690 +               r = fc->read_ibi_reg(fc, tw_sm_c_100);
1691 +
1692 +               if (!r.tw_sm_c_100.no_base_addr_ack_error) {
1693 +                       if (r.tw_sm_c_100.st_done) {
1694 +                               *r100 = r;
1695 +                               deb_i2c("i2c success\n");
1696 +                               return 0;
1697 +                       }
1698 +               } else {
1699 +                       deb_i2c("suffering from an i2c ack_error\n");
1700 +                       return -EREMOTEIO;
1701 +               }
1702 +       }
1703 +       deb_i2c("tried %d times i2c operation, "
1704 +                       "never finished or too many ack errors.\n", i);
1705 +       return -EREMOTEIO;
1706 +}
1707 +
1708 +static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
1709 +               flexcop_ibi_value r100, u8 *buf)
1710 +{
1711 +       flexcop_ibi_value r104;
1712 +       int len = r100.tw_sm_c_100.total_bytes,
1713 +               /* remember total_bytes is buflen-1 */
1714 +               ret;
1715 +
1716 +       /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
1717 +        * correctly:
1718 +        *
1719 +        * the ITD1000 is behind an i2c-gate which closes automatically
1720 +        * after an i2c-transaction the STV0297 needs 2 consecutive reads
1721 +        * one with no_base_addr = 0 and one with 1
1722 +        *
1723 +        * those two work-arounds are conflictin: we check for the card
1724 +        * type, it is set when probing the ITD1000 */
1725 +       if (i2c->fc->dev_type == FC_SKY_REV27)
1726 +               r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
1727 +
1728 +       ret = flexcop_i2c_operation(i2c->fc, &r100);
1729 +       if (ret != 0) {
1730 +               deb_i2c("Retrying operation\n");
1731 +               r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
1732 +               ret = flexcop_i2c_operation(i2c->fc, &r100);
1733 +       }
1734 +       if (ret != 0) {
1735 +               deb_i2c("read failed. %d\n", ret);
1736 +               return ret;
1737 +       }
1738 +
1739 +       buf[0] = r100.tw_sm_c_100.data1_reg;
1740 +
1741 +       if (len > 0) {
1742 +               r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104);
1743 +               deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
1744 +
1745 +               /* there is at least one more byte, otherwise we wouldn't be here */
1746 +               buf[1] = r104.tw_sm_c_104.data2_reg;
1747 +               if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
1748 +               if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
1749 +       }
1750 +       return 0;
1751 +}
1752 +
1753 +static int flexcop_i2c_write4(struct flexcop_device *fc,
1754 +               flexcop_ibi_value r100, u8 *buf)
1755 +{
1756 +       flexcop_ibi_value r104;
1757 +       int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
1758 +       r104.raw = 0;
1759 +
1760 +       /* there is at least one byte, otherwise we wouldn't be here */
1761 +       r100.tw_sm_c_100.data1_reg = buf[0];
1762 +       r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
1763 +       r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
1764 +       r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
1765 +
1766 +       deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
1767 +
1768 +       /* write the additional i2c data before doing the actual i2c operation */
1769 +       fc->write_ibi_reg(fc, tw_sm_c_104, r104);
1770 +       return flexcop_i2c_operation(fc, &r100);
1771 +}
1772 +
1773 +int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
1774 +               flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
1775 +{
1776 +       int ret;
1777 +
1778 +#ifdef DUMP_I2C_MESSAGES
1779 +       int i;
1780 +#endif
1781 +
1782 +       u16 bytes_to_transfer;
1783 +       flexcop_ibi_value r100;
1784 +
1785 +       deb_i2c("op = %d\n",op);
1786 +       r100.raw = 0;
1787 +       r100.tw_sm_c_100.chipaddr = chipaddr;
1788 +       r100.tw_sm_c_100.twoWS_rw = op;
1789 +       r100.tw_sm_c_100.twoWS_port_reg = i2c->port;
1790 +
1791 +#ifdef DUMP_I2C_MESSAGES
1792 +       printk(KERN_DEBUG "%d ", i2c->port);
1793 +       if (op == FC_READ)
1794 +               printk("rd(");
1795 +       else
1796 +               printk("wr(");
1797 +       printk("%02x): %02x ", chipaddr, addr);
1798 +#endif
1799 +
1800 +       /* in that case addr is the only value ->
1801 +        * we write it twice as baseaddr and val0
1802 +        * BBTI is doing it like that for ISL6421 at least */
1803 +       if (i2c->no_base_addr && len == 0 && op == FC_WRITE) {
1804 +               buf = &addr;
1805 +               len = 1;
1806 +       }
1807 +
1808 +       while (len != 0) {
1809 +               bytes_to_transfer = len > 4 ? 4 : len;
1810 +
1811 +               r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1;
1812 +               r100.tw_sm_c_100.baseaddr = addr;
1813 +
1814 +               if (op == FC_READ)
1815 +                       ret = flexcop_i2c_read4(i2c, r100, buf);
1816 +               else
1817 +                       ret = flexcop_i2c_write4(i2c->fc, r100, buf);
1818 +
1819 +#ifdef DUMP_I2C_MESSAGES
1820 +               for (i = 0; i < bytes_to_transfer; i++)
1821 +                       printk("%02x ", buf[i]);
1822 +#endif
1823 +
1824 +               if (ret < 0)
1825 +                       return ret;
1826 +
1827 +               buf  += bytes_to_transfer;
1828 +               addr += bytes_to_transfer;
1829 +               len  -= bytes_to_transfer;
1830 +       }
1831 +
1832 +#ifdef DUMP_I2C_MESSAGES
1833 +       printk("\n");
1834 +#endif
1835 +
1836 +       return 0;
1837 +}
1838 +/* exported for PCI i2c */
1839 +EXPORT_SYMBOL(flexcop_i2c_request);
1840 +
1841 +/* master xfer callback for demodulator */
1842 +static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
1843 +               struct i2c_msg msgs[], int num)
1844 +{
1845 +       struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
1846 +       int i, ret = 0;
1847 +
1848 +       /* Some drivers use 1 byte or 0 byte reads as probes, which this
1849 +        * driver doesn't support.  These probes will always fail, so this
1850 +        * hack makes them always succeed.  If one knew how, it would of
1851 +        * course be better to actually do the read.  */
1852 +       if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1)
1853 +               return 1;
1854 +
1855 +       if (mutex_lock_interruptible(&i2c->fc->i2c_mutex))
1856 +               return -ERESTARTSYS;
1857 +
1858 +       for (i = 0; i < num; i++) {
1859 +               /* reading */
1860 +               if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
1861 +                       ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
1862 +                                       msgs[i].buf[0], msgs[i+1].buf,
1863 +                                       msgs[i+1].len);
1864 +                       i++; /* skip the following message */
1865 +               } else /* writing */
1866 +                       ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
1867 +                                       msgs[i].buf[0], &msgs[i].buf[1],
1868 +                                       msgs[i].len - 1);
1869 +               if (ret < 0) {
1870 +                       deb_i2c("i2c master_xfer failed");
1871 +                       break;
1872 +               }
1873 +       }
1874 +
1875 +       mutex_unlock(&i2c->fc->i2c_mutex);
1876 +
1877 +       if (ret == 0)
1878 +               ret = num;
1879 +       return ret;
1880 +}
1881 +
1882 +static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
1883 +{
1884 +       return I2C_FUNC_I2C;
1885 +}
1886 +
1887 +static struct i2c_algorithm flexcop_algo = {
1888 +       .master_xfer    = flexcop_master_xfer,
1889 +       .functionality  = flexcop_i2c_func,
1890 +};
1891 +
1892 +int flexcop_i2c_init(struct flexcop_device *fc)
1893 +{
1894 +       int ret;
1895 +       mutex_init(&fc->i2c_mutex);
1896 +
1897 +       fc->fc_i2c_adap[0].fc = fc;
1898 +       fc->fc_i2c_adap[1].fc = fc;
1899 +       fc->fc_i2c_adap[2].fc = fc;
1900 +       fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
1901 +       fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
1902 +       fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
1903 +
1904 +       strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
1905 +                       sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
1906 +       strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
1907 +                       sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
1908 +       strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
1909 +                       sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
1910 +
1911 +       i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
1912 +       i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
1913 +       i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
1914 +
1915 +       fc->fc_i2c_adap[0].i2c_adap.algo =
1916 +               fc->fc_i2c_adap[1].i2c_adap.algo =
1917 +               fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;
1918 +       fc->fc_i2c_adap[0].i2c_adap.algo_data =
1919 +               fc->fc_i2c_adap[1].i2c_adap.algo_data =
1920 +               fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL;
1921 +       fc->fc_i2c_adap[0].i2c_adap.dev.parent =
1922 +               fc->fc_i2c_adap[1].i2c_adap.dev.parent =
1923 +               fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev;
1924 +
1925 +       ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap);
1926 +       if (ret < 0)
1927 +               return ret;
1928 +
1929 +       ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
1930 +       if (ret < 0)
1931 +               goto adap_1_failed;
1932 +
1933 +       ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap);
1934 +       if (ret < 0)
1935 +               goto adap_2_failed;
1936 +
1937 +       fc->init_state |= FC_STATE_I2C_INIT;
1938 +       return 0;
1939 +
1940 +adap_2_failed:
1941 +       i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
1942 +adap_1_failed:
1943 +       i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
1944 +       return ret;
1945 +}
1946 +
1947 +void flexcop_i2c_exit(struct flexcop_device *fc)
1948 +{
1949 +       if (fc->init_state & FC_STATE_I2C_INIT) {
1950 +               i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap);
1951 +               i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
1952 +               i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
1953 +       }
1954 +       fc->init_state &= ~FC_STATE_I2C_INIT;
1955 +}
1956 diff --git a/drivers/media/common/b2c2/flexcop-misc.c b/drivers/media/common/b2c2/flexcop-misc.c
1957 new file mode 100644
1958 index 0000000..f06f3a9
1959 --- /dev/null
1960 +++ b/drivers/media/common/b2c2/flexcop-misc.c
1961 @@ -0,0 +1,86 @@
1962 +/*
1963 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
1964 + * flexcop-misc.c - miscellaneous functions
1965 + * see flexcop.c for copyright information
1966 + */
1967 +#include "flexcop.h"
1968 +
1969 +void flexcop_determine_revision(struct flexcop_device *fc)
1970 +{
1971 +       flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
1972 +
1973 +       switch (v.misc_204.Rev_N_sig_revision_hi) {
1974 +       case 0x2:
1975 +               deb_info("found a FlexCopII.\n");
1976 +               fc->rev = FLEXCOP_II;
1977 +               break;
1978 +       case 0x3:
1979 +               deb_info("found a FlexCopIIb.\n");
1980 +               fc->rev = FLEXCOP_IIB;
1981 +               break;
1982 +       case 0x0:
1983 +               deb_info("found a FlexCopIII.\n");
1984 +               fc->rev = FLEXCOP_III;
1985 +               break;
1986 +       default:
1987 +               err("unknown FlexCop Revision: %x. Please report this to "
1988 +                               "linux-dvb@linuxtv.org.",
1989 +                               v.misc_204.Rev_N_sig_revision_hi);
1990 +               break;
1991 +       }
1992 +
1993 +       if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
1994 +               deb_info("this FlexCop has "
1995 +                               "the additional 32 hardware pid filter.\n");
1996 +       else
1997 +               deb_info("this FlexCop has "
1998 +                               "the 6 basic main hardware pid filter.\n");
1999 +       /* bus parts have to decide if hw pid filtering is used or not. */
2000 +}
2001 +
2002 +static const char *flexcop_revision_names[] = {
2003 +       "Unknown chip",
2004 +       "FlexCopII",
2005 +       "FlexCopIIb",
2006 +       "FlexCopIII",
2007 +};
2008 +
2009 +static const char *flexcop_device_names[] = {
2010 +       [FC_UNK]        = "Unknown device",
2011 +       [FC_CABLE]      = "Cable2PC/CableStar 2 DVB-C",
2012 +       [FC_AIR_DVBT]   = "Air2PC/AirStar 2 DVB-T",
2013 +       [FC_AIR_ATSC1]  = "Air2PC/AirStar 2 ATSC 1st generation",
2014 +       [FC_AIR_ATSC2]  = "Air2PC/AirStar 2 ATSC 2nd generation",
2015 +       [FC_AIR_ATSC3]  = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
2016 +       [FC_SKY_REV23]  = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)",
2017 +       [FC_SKY_REV26]  = "Sky2PC/SkyStar 2 DVB-S rev 2.6",
2018 +       [FC_SKY_REV27]  = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
2019 +       [FC_SKY_REV28]  = "Sky2PC/SkyStar 2 DVB-S rev 2.8",
2020 +};
2021 +
2022 +static const char *flexcop_bus_names[] = {
2023 +       "USB",
2024 +       "PCI",
2025 +};
2026 +
2027 +void flexcop_device_name(struct flexcop_device *fc,
2028 +               const char *prefix, const char *suffix)
2029 +{
2030 +       info("%s '%s' at the '%s' bus controlled by a '%s' %s",
2031 +                       prefix, flexcop_device_names[fc->dev_type],
2032 +                       flexcop_bus_names[fc->bus_type],
2033 +                       flexcop_revision_names[fc->rev], suffix);
2034 +}
2035 +
2036 +void flexcop_dump_reg(struct flexcop_device *fc,
2037 +               flexcop_ibi_register reg, int num)
2038 +{
2039 +       flexcop_ibi_value v;
2040 +       int i;
2041 +       for (i = 0; i < num; i++) {
2042 +               v = fc->read_ibi_reg(fc, reg+4*i);
2043 +               deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
2044 +       }
2045 +       deb_rdump("\n");
2046 +}
2047 +EXPORT_SYMBOL(flexcop_dump_reg);
2048 diff --git a/drivers/media/common/b2c2/flexcop-reg.h b/drivers/media/common/b2c2/flexcop-reg.h
2049 new file mode 100644
2050 index 0000000..dc4528d
2051 --- /dev/null
2052 +++ b/drivers/media/common/b2c2/flexcop-reg.h
2053 @@ -0,0 +1,166 @@
2054 +/*
2055 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2056 + * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
2057 + * see flexcop.c for copyright information
2058 + */
2059 +#ifndef __FLEXCOP_REG_H__
2060 +#define __FLEXCOP_REG_H__
2061 +
2062 +typedef enum {
2063 +       FLEXCOP_UNK = 0,
2064 +       FLEXCOP_II,
2065 +       FLEXCOP_IIB,
2066 +       FLEXCOP_III,
2067 +} flexcop_revision_t;
2068 +
2069 +typedef enum {
2070 +       FC_UNK = 0,
2071 +       FC_CABLE,
2072 +       FC_AIR_DVBT,
2073 +       FC_AIR_ATSC1,
2074 +       FC_AIR_ATSC2,
2075 +       FC_AIR_ATSC3,
2076 +       FC_SKY_REV23,
2077 +       FC_SKY_REV26,
2078 +       FC_SKY_REV27,
2079 +       FC_SKY_REV28,
2080 +} flexcop_device_type_t;
2081 +
2082 +typedef enum {
2083 +       FC_USB = 0,
2084 +       FC_PCI,
2085 +} flexcop_bus_t;
2086 +
2087 +/* FlexCop IBI Registers */
2088 +#if defined(__LITTLE_ENDIAN)
2089 +#include "flexcop_ibi_value_le.h"
2090 +#else
2091 +#if defined(__BIG_ENDIAN)
2092 +#include "flexcop_ibi_value_be.h"
2093 +#else
2094 +#error no endian defined
2095 +#endif
2096 +#endif
2097 +
2098 +#define fc_data_Tag_ID_DVB  0x3e
2099 +#define fc_data_Tag_ID_ATSC 0x3f
2100 +#define fc_data_Tag_ID_IDSB 0x8b
2101 +
2102 +#define fc_key_code_default 0x1
2103 +#define fc_key_code_even    0x2
2104 +#define fc_key_code_odd     0x3
2105 +
2106 +extern flexcop_ibi_value ibi_zero;
2107 +
2108 +typedef enum {
2109 +       FC_I2C_PORT_DEMOD  = 1,
2110 +       FC_I2C_PORT_EEPROM = 2,
2111 +       FC_I2C_PORT_TUNER  = 3,
2112 +} flexcop_i2c_port_t;
2113 +
2114 +typedef enum {
2115 +       FC_WRITE = 0,
2116 +       FC_READ  = 1,
2117 +} flexcop_access_op_t;
2118 +
2119 +typedef enum {
2120 +       FC_SRAM_DEST_NET   = 1,
2121 +       FC_SRAM_DEST_CAI   = 2,
2122 +       FC_SRAM_DEST_CAO   = 4,
2123 +       FC_SRAM_DEST_MEDIA = 8
2124 +} flexcop_sram_dest_t;
2125 +
2126 +typedef enum {
2127 +       FC_SRAM_DEST_TARGET_WAN_USB = 0,
2128 +       FC_SRAM_DEST_TARGET_DMA1    = 1,
2129 +       FC_SRAM_DEST_TARGET_DMA2    = 2,
2130 +       FC_SRAM_DEST_TARGET_FC3_CA  = 3
2131 +} flexcop_sram_dest_target_t;
2132 +
2133 +typedef enum {
2134 +       FC_SRAM_2_32KB  = 0, /*  64KB */
2135 +       FC_SRAM_1_32KB  = 1, /*  32KB - default fow FCII */
2136 +       FC_SRAM_1_128KB = 2, /* 128KB */
2137 +       FC_SRAM_1_48KB  = 3, /*  48KB - default for FCIII */
2138 +} flexcop_sram_type_t;
2139 +
2140 +typedef enum {
2141 +       FC_WAN_SPEED_4MBITS  = 0,
2142 +       FC_WAN_SPEED_8MBITS  = 1,
2143 +       FC_WAN_SPEED_12MBITS = 2,
2144 +       FC_WAN_SPEED_16MBITS = 3,
2145 +} flexcop_wan_speed_t;
2146 +
2147 +typedef enum {
2148 +       FC_DMA_1 = 1,
2149 +       FC_DMA_2 = 2,
2150 +} flexcop_dma_index_t;
2151 +
2152 +typedef enum {
2153 +       FC_DMA_SUBADDR_0 = 1,
2154 +       FC_DMA_SUBADDR_1 = 2,
2155 +} flexcop_dma_addr_index_t;
2156 +
2157 +/* names of the particular registers */
2158 +typedef enum {
2159 +       dma1_000            = 0x000,
2160 +       dma1_004            = 0x004,
2161 +       dma1_008            = 0x008,
2162 +       dma1_00c            = 0x00c,
2163 +       dma2_010            = 0x010,
2164 +       dma2_014            = 0x014,
2165 +       dma2_018            = 0x018,
2166 +       dma2_01c            = 0x01c,
2167 +
2168 +       tw_sm_c_100         = 0x100,
2169 +       tw_sm_c_104         = 0x104,
2170 +       tw_sm_c_108         = 0x108,
2171 +       tw_sm_c_10c         = 0x10c,
2172 +       tw_sm_c_110         = 0x110,
2173 +
2174 +       lnb_switch_freq_200 = 0x200,
2175 +       misc_204            = 0x204,
2176 +       ctrl_208            = 0x208,
2177 +       irq_20c             = 0x20c,
2178 +       sw_reset_210        = 0x210,
2179 +       misc_214            = 0x214,
2180 +       mbox_v8_to_host_218 = 0x218,
2181 +       mbox_host_to_v8_21c = 0x21c,
2182 +
2183 +       pid_filter_300      = 0x300,
2184 +       pid_filter_304      = 0x304,
2185 +       pid_filter_308      = 0x308,
2186 +       pid_filter_30c      = 0x30c,
2187 +       index_reg_310       = 0x310,
2188 +       pid_n_reg_314       = 0x314,
2189 +       mac_low_reg_318     = 0x318,
2190 +       mac_high_reg_31c    = 0x31c,
2191 +
2192 +       data_tag_400        = 0x400,
2193 +       card_id_408         = 0x408,
2194 +       card_id_40c         = 0x40c,
2195 +       mac_address_418     = 0x418,
2196 +       mac_address_41c     = 0x41c,
2197 +
2198 +       ci_600              = 0x600,
2199 +       pi_604              = 0x604,
2200 +       pi_608              = 0x608,
2201 +       dvb_reg_60c         = 0x60c,
2202 +
2203 +       sram_ctrl_reg_700   = 0x700,
2204 +       net_buf_reg_704     = 0x704,
2205 +       cai_buf_reg_708     = 0x708,
2206 +       cao_buf_reg_70c     = 0x70c,
2207 +       media_buf_reg_710   = 0x710,
2208 +       sram_dest_reg_714   = 0x714,
2209 +       net_buf_reg_718     = 0x718,
2210 +       wan_ctrl_reg_71c    = 0x71c,
2211 +} flexcop_ibi_register;
2212 +
2213 +#define flexcop_set_ibi_value(reg,attr,val) { \
2214 +       flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \
2215 +       v.reg.attr = val; \
2216 +       fc->write_ibi_reg(fc,reg,v); \
2217 +}
2218 +
2219 +#endif
2220 diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
2221 new file mode 100644
2222 index 0000000..f2199e4
2223 --- /dev/null
2224 +++ b/drivers/media/common/b2c2/flexcop-sram.c
2225 @@ -0,0 +1,363 @@
2226 +/*
2227 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2228 + * flexcop-sram.c - functions for controlling the SRAM
2229 + * see flexcop.c for copyright information
2230 + */
2231 +#include "flexcop.h"
2232 +
2233 +static void flexcop_sram_set_chip(struct flexcop_device *fc,
2234 +               flexcop_sram_type_t type)
2235 +{
2236 +       flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
2237 +}
2238 +
2239 +int flexcop_sram_init(struct flexcop_device *fc)
2240 +{
2241 +       switch (fc->rev) {
2242 +       case FLEXCOP_II:
2243 +       case FLEXCOP_IIB:
2244 +               flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
2245 +               break;
2246 +       case FLEXCOP_III:
2247 +               flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
2248 +               break;
2249 +       default:
2250 +               return -EINVAL;
2251 +       }
2252 +       return 0;
2253 +}
2254 +
2255 +int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
2256 +                flexcop_sram_dest_target_t target)
2257 +{
2258 +       flexcop_ibi_value v;
2259 +       v = fc->read_ibi_reg(fc, sram_dest_reg_714);
2260 +
2261 +       if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
2262 +               err("SRAM destination target to available on FlexCopII(b)\n");
2263 +               return -EINVAL;
2264 +       }
2265 +       deb_sram("sram dest: %x target: %x\n", dest, target);
2266 +
2267 +       if (dest & FC_SRAM_DEST_NET)
2268 +               v.sram_dest_reg_714.NET_Dest = target;
2269 +       if (dest & FC_SRAM_DEST_CAI)
2270 +               v.sram_dest_reg_714.CAI_Dest = target;
2271 +       if (dest & FC_SRAM_DEST_CAO)
2272 +               v.sram_dest_reg_714.CAO_Dest = target;
2273 +       if (dest & FC_SRAM_DEST_MEDIA)
2274 +               v.sram_dest_reg_714.MEDIA_Dest = target;
2275 +
2276 +       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
2277 +       udelay(1000); /* TODO delay really necessary */
2278 +
2279 +       return 0;
2280 +}
2281 +EXPORT_SYMBOL(flexcop_sram_set_dest);
2282 +
2283 +void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
2284 +{
2285 +       flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
2286 +}
2287 +EXPORT_SYMBOL(flexcop_wan_set_speed);
2288 +
2289 +void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
2290 +{
2291 +       flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
2292 +       v.sram_dest_reg_714.ctrl_usb_wan = usb_wan;
2293 +       v.sram_dest_reg_714.ctrl_sramdma = sramdma;
2294 +       v.sram_dest_reg_714.ctrl_maximumfill = maximumfill;
2295 +       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
2296 +}
2297 +EXPORT_SYMBOL(flexcop_sram_ctrl);
2298 +
2299 +#if 0
2300 +static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
2301 +{
2302 +       int i, retries;
2303 +       u32 command;
2304 +
2305 +       for (i = 0; i < len; i++) {
2306 +               command = bank | addr | 0x04000000 | (*buf << 0x10);
2307 +
2308 +               retries = 2;
2309 +
2310 +               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
2311 +                       mdelay(1);
2312 +                       retries--;
2313 +               };
2314 +
2315 +               if (retries == 0)
2316 +                       printk("%s: SRAM timeout\n", __func__);
2317 +
2318 +               write_reg_dw(adapter, 0x700, command);
2319 +
2320 +               buf++;
2321 +               addr++;
2322 +       }
2323 +}
2324 +
2325 +static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
2326 +{
2327 +       int i, retries;
2328 +       u32 command, value;
2329 +
2330 +       for (i = 0; i < len; i++) {
2331 +               command = bank | addr | 0x04008000;
2332 +
2333 +               retries = 10000;
2334 +
2335 +               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
2336 +                       mdelay(1);
2337 +                       retries--;
2338 +               };
2339 +
2340 +               if (retries == 0)
2341 +                       printk("%s: SRAM timeout\n", __func__);
2342 +
2343 +               write_reg_dw(adapter, 0x700, command);
2344 +
2345 +               retries = 10000;
2346 +
2347 +               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
2348 +                       mdelay(1);
2349 +                       retries--;
2350 +               };
2351 +
2352 +               if (retries == 0)
2353 +                       printk("%s: SRAM timeout\n", __func__);
2354 +
2355 +               value = read_reg_dw(adapter, 0x700) >> 0x10;
2356 +
2357 +               *buf = (value & 0xff);
2358 +
2359 +               addr++;
2360 +               buf++;
2361 +       }
2362 +}
2363 +
2364 +static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
2365 +{
2366 +       u32 bank;
2367 +
2368 +       bank = 0;
2369 +
2370 +       if (adapter->dw_sram_type == 0x20000) {
2371 +               bank = (addr & 0x18000) << 0x0d;
2372 +       }
2373 +
2374 +       if (adapter->dw_sram_type == 0x00000) {
2375 +               if ((addr >> 0x0f) == 0)
2376 +                       bank = 0x20000000;
2377 +               else
2378 +                       bank = 0x10000000;
2379 +       }
2380 +       flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
2381 +}
2382 +
2383 +static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
2384 +{
2385 +       u32 bank;
2386 +       bank = 0;
2387 +
2388 +       if (adapter->dw_sram_type == 0x20000) {
2389 +               bank = (addr & 0x18000) << 0x0d;
2390 +       }
2391 +
2392 +       if (adapter->dw_sram_type == 0x00000) {
2393 +               if ((addr >> 0x0f) == 0)
2394 +                       bank = 0x20000000;
2395 +               else
2396 +                       bank = 0x10000000;
2397 +       }
2398 +       flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
2399 +}
2400 +
2401 +static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
2402 +{
2403 +       u32 length;
2404 +       while (len != 0) {
2405 +               length = len;
2406 +               /* check if the address range belongs to the same
2407 +                * 32K memory chip. If not, the data is read
2408 +                * from one chip at a time */
2409 +               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
2410 +                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
2411 +               }
2412 +
2413 +               sram_read_chunk(adapter, addr, buf, length);
2414 +               addr = addr + length;
2415 +               buf = buf + length;
2416 +               len = len - length;
2417 +       }
2418 +}
2419 +
2420 +static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
2421 +{
2422 +       u32 length;
2423 +       while (len != 0) {
2424 +               length = len;
2425 +
2426 +               /* check if the address range belongs to the same
2427 +                * 32K memory chip. If not, the data is
2428 +                * written to one chip at a time */
2429 +               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
2430 +                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
2431 +               }
2432 +
2433 +               sram_write_chunk(adapter, addr, buf, length);
2434 +               addr = addr + length;
2435 +               buf = buf + length;
2436 +               len = len - length;
2437 +       }
2438 +}
2439 +
2440 +static void sram_set_size(struct adapter *adapter, u32 mask)
2441 +{
2442 +       write_reg_dw(adapter, 0x71c,
2443 +                       (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
2444 +}
2445 +
2446 +static void sram_init(struct adapter *adapter)
2447 +{
2448 +       u32 tmp;
2449 +       tmp = read_reg_dw(adapter, 0x71c);
2450 +       write_reg_dw(adapter, 0x71c, 1);
2451 +
2452 +       if (read_reg_dw(adapter, 0x71c) != 0) {
2453 +               write_reg_dw(adapter, 0x71c, tmp);
2454 +               adapter->dw_sram_type = tmp & 0x30000;
2455 +               ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
2456 +       } else {
2457 +               adapter->dw_sram_type = 0x10000;
2458 +               ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
2459 +       }
2460 +}
2461 +
2462 +static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
2463 +{
2464 +       u8 tmp1, tmp2;
2465 +       dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
2466 +
2467 +       sram_set_size(adapter, mask);
2468 +       sram_init(adapter);
2469 +
2470 +       tmp2 = 0xa5;
2471 +       tmp1 = 0x4f;
2472 +
2473 +       sram_write(adapter, addr, &tmp2, 1);
2474 +       sram_write(adapter, addr + 4, &tmp1, 1);
2475 +
2476 +       tmp2 = 0;
2477 +       mdelay(20);
2478 +
2479 +       sram_read(adapter, addr, &tmp2, 1);
2480 +       sram_read(adapter, addr, &tmp2, 1);
2481 +
2482 +       dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
2483 +
2484 +       if (tmp2 != 0xa5)
2485 +               return 0;
2486 +
2487 +       tmp2 = 0x5a;
2488 +       tmp1 = 0xf4;
2489 +
2490 +       sram_write(adapter, addr, &tmp2, 1);
2491 +       sram_write(adapter, addr + 4, &tmp1, 1);
2492 +
2493 +       tmp2 = 0;
2494 +       mdelay(20);
2495 +
2496 +       sram_read(adapter, addr, &tmp2, 1);
2497 +       sram_read(adapter, addr, &tmp2, 1);
2498 +
2499 +       dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
2500 +
2501 +       if (tmp2 != 0x5a)
2502 +               return 0;
2503 +       return 1;
2504 +}
2505 +
2506 +static u32 sram_length(struct adapter *adapter)
2507 +{
2508 +       if (adapter->dw_sram_type == 0x10000)
2509 +               return 32768; /* 32K */
2510 +       if (adapter->dw_sram_type == 0x00000)
2511 +               return 65536; /* 64K */
2512 +       if (adapter->dw_sram_type == 0x20000)
2513 +               return 131072; /* 128K */
2514 +       return 32768; /* 32K */
2515 +}
2516 +
2517 +/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
2518 +   - for 128K there are 4x32K chips at bank 0,1,2,3.
2519 +   - for  64K there are 2x32K chips at bank 1,2.
2520 +   - for  32K there is one 32K chip at bank 0.
2521 +
2522 +   FlexCop works only with one bank at a time. The bank is selected
2523 +   by bits 28-29 of the 0x700 register.
2524 +
2525 +   bank 0 covers addresses 0x00000-0x07fff
2526 +   bank 1 covers addresses 0x08000-0x0ffff
2527 +   bank 2 covers addresses 0x10000-0x17fff
2528 +   bank 3 covers addresses 0x18000-0x1ffff */
2529 +
2530 +static int flexcop_sram_detect(struct flexcop_device *fc)
2531 +{
2532 +       flexcop_ibi_value r208, r71c_0, vr71c_1;
2533 +       r208 = fc->read_ibi_reg(fc, ctrl_208);
2534 +       fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
2535 +
2536 +       r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
2537 +       write_reg_dw(adapter, 0x71c, 1);
2538 +       tmp3 = read_reg_dw(adapter, 0x71c);
2539 +       dprintk("%s: tmp3 = %x\n", __func__, tmp3);
2540 +       write_reg_dw(adapter, 0x71c, tmp2);
2541 +
2542 +       // check for internal SRAM ???
2543 +       tmp3--;
2544 +       if (tmp3 != 0) {
2545 +               sram_set_size(adapter, 0x10000);
2546 +               sram_init(adapter);
2547 +               write_reg_dw(adapter, 0x208, tmp);
2548 +               dprintk("%s: sram size = 32K\n", __func__);
2549 +               return 32;
2550 +       }
2551 +
2552 +       if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
2553 +               sram_set_size(adapter, 0x20000);
2554 +               sram_init(adapter);
2555 +               write_reg_dw(adapter, 0x208, tmp);
2556 +               dprintk("%s: sram size = 128K\n", __func__);
2557 +               return 128;
2558 +       }
2559 +
2560 +       if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
2561 +               sram_set_size(adapter, 0x00000);
2562 +               sram_init(adapter);
2563 +               write_reg_dw(adapter, 0x208, tmp);
2564 +               dprintk("%s: sram size = 64K\n", __func__);
2565 +               return 64;
2566 +       }
2567 +
2568 +       if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
2569 +               sram_set_size(adapter, 0x10000);
2570 +               sram_init(adapter);
2571 +               write_reg_dw(adapter, 0x208, tmp);
2572 +               dprintk("%s: sram size = 32K\n", __func__);
2573 +               return 32;
2574 +       }
2575 +
2576 +       sram_set_size(adapter, 0x10000);
2577 +       sram_init(adapter);
2578 +       write_reg_dw(adapter, 0x208, tmp);
2579 +       dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
2580 +       return 0;
2581 +}
2582 +
2583 +static void sll_detect_sram_size(struct adapter *adapter)
2584 +{
2585 +       sram_detect_for_flex2(adapter);
2586 +}
2587 +
2588 +#endif
2589 diff --git a/drivers/media/common/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c
2590 new file mode 100644
2591 index 0000000..412c5da
2592 --- /dev/null
2593 +++ b/drivers/media/common/b2c2/flexcop.c
2594 @@ -0,0 +1,325 @@
2595 +/*
2596 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2597 + * flexcop.c - main module part
2598 + * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
2599 + * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
2600 + *
2601 + * Acknowledgements:
2602 + *   John Jurrius from BBTI, Inc. for extensive support
2603 + *                    with code examples and data books
2604 + *   Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
2605 + *
2606 + * Contributions to the skystar2-driver have been done by
2607 + *   Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
2608 + *   Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
2609 + *   Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
2610 + *   Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
2611 + *               filtering)
2612 + *
2613 + * This program is free software; you can redistribute it and/or
2614 + * modify it under the terms of the GNU Lesser General Public License
2615 + * as published by the Free Software Foundation; either version 2.1
2616 + * of the License, or (at your option) any later version.
2617 + *
2618 + * This program is distributed in the hope that it will be useful,
2619 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2620 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2621 + * GNU General Public License for more details.
2622 + *
2623 + * You should have received a copy of the GNU Lesser General Public License
2624 + * along with this program; if not, write to the Free Software
2625 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
2626 + */
2627 +
2628 +#include "flexcop.h"
2629 +
2630 +#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
2631 +#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
2632 +
2633 +#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
2634 +#define DEBSTATUS ""
2635 +#else
2636 +#define DEBSTATUS " (debugging is not enabled)"
2637 +#endif
2638 +
2639 +int b2c2_flexcop_debug;
2640 +EXPORT_SYMBOL_GPL(b2c2_flexcop_debug);
2641 +module_param_named(debug, b2c2_flexcop_debug,  int, 0644);
2642 +MODULE_PARM_DESC(debug,
2643 +               "set debug level (1=info,2=tuner,4=i2c,8=ts,"
2644 +               "16=sram,32=reg (|-able))."
2645 +               DEBSTATUS);
2646 +#undef DEBSTATUS
2647 +
2648 +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
2649 +
2650 +/* global zero for ibi values */
2651 +flexcop_ibi_value ibi_zero;
2652 +
2653 +static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
2654 +{
2655 +       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
2656 +       return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
2657 +}
2658 +
2659 +static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
2660 +{
2661 +       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
2662 +       return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
2663 +}
2664 +
2665 +static int flexcop_dvb_init(struct flexcop_device *fc)
2666 +{
2667 +       int ret = dvb_register_adapter(&fc->dvb_adapter,
2668 +                       "FlexCop Digital TV device", fc->owner,
2669 +                       fc->dev, adapter_nr);
2670 +       if (ret < 0) {
2671 +               err("error registering DVB adapter");
2672 +               return ret;
2673 +       }
2674 +       fc->dvb_adapter.priv = fc;
2675 +
2676 +       fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
2677 +                       | DMX_MEMORY_BASED_FILTERING);
2678 +       fc->demux.priv = fc;
2679 +       fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
2680 +       fc->demux.start_feed = flexcop_dvb_start_feed;
2681 +       fc->demux.stop_feed = flexcop_dvb_stop_feed;
2682 +       fc->demux.write_to_decoder = NULL;
2683 +
2684 +       ret = dvb_dmx_init(&fc->demux);
2685 +       if (ret < 0) {
2686 +               err("dvb_dmx failed: error %d", ret);
2687 +               goto err_dmx;
2688 +       }
2689 +
2690 +       fc->hw_frontend.source = DMX_FRONTEND_0;
2691 +
2692 +       fc->dmxdev.filternum = fc->demux.feednum;
2693 +       fc->dmxdev.demux = &fc->demux.dmx;
2694 +       fc->dmxdev.capabilities = 0;
2695 +       ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter);
2696 +       if (ret < 0) {
2697 +               err("dvb_dmxdev_init failed: error %d", ret);
2698 +               goto err_dmx_dev;
2699 +       }
2700 +
2701 +       ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend);
2702 +       if (ret < 0) {
2703 +               err("adding hw_frontend to dmx failed: error %d", ret);
2704 +               goto err_dmx_add_hw_frontend;
2705 +       }
2706 +
2707 +       fc->mem_frontend.source = DMX_MEMORY_FE;
2708 +       ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend);
2709 +       if (ret < 0) {
2710 +               err("adding mem_frontend to dmx failed: error %d", ret);
2711 +               goto err_dmx_add_mem_frontend;
2712 +       }
2713 +
2714 +       ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend);
2715 +       if (ret < 0) {
2716 +               err("connect frontend failed: error %d", ret);
2717 +               goto err_connect_frontend;
2718 +       }
2719 +
2720 +       ret = dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
2721 +       if (ret < 0) {
2722 +               err("dvb_net_init failed: error %d", ret);
2723 +               goto err_net;
2724 +       }
2725 +
2726 +       fc->init_state |= FC_STATE_DVB_INIT;
2727 +       return 0;
2728 +
2729 +err_net:
2730 +       fc->demux.dmx.disconnect_frontend(&fc->demux.dmx);
2731 +err_connect_frontend:
2732 +       fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
2733 +err_dmx_add_mem_frontend:
2734 +       fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
2735 +err_dmx_add_hw_frontend:
2736 +       dvb_dmxdev_release(&fc->dmxdev);
2737 +err_dmx_dev:
2738 +       dvb_dmx_release(&fc->demux);
2739 +err_dmx:
2740 +       dvb_unregister_adapter(&fc->dvb_adapter);
2741 +       return ret;
2742 +}
2743 +
2744 +static void flexcop_dvb_exit(struct flexcop_device *fc)
2745 +{
2746 +       if (fc->init_state & FC_STATE_DVB_INIT) {
2747 +               dvb_net_release(&fc->dvbnet);
2748 +
2749 +               fc->demux.dmx.close(&fc->demux.dmx);
2750 +               fc->demux.dmx.remove_frontend(&fc->demux.dmx,
2751 +                       &fc->mem_frontend);
2752 +               fc->demux.dmx.remove_frontend(&fc->demux.dmx,
2753 +                       &fc->hw_frontend);
2754 +               dvb_dmxdev_release(&fc->dmxdev);
2755 +               dvb_dmx_release(&fc->demux);
2756 +               dvb_unregister_adapter(&fc->dvb_adapter);
2757 +               deb_info("deinitialized dvb stuff\n");
2758 +       }
2759 +       fc->init_state &= ~FC_STATE_DVB_INIT;
2760 +}
2761 +
2762 +/* these methods are necessary to achieve the long-term-goal of hiding the
2763 + * struct flexcop_device from the bus-parts */
2764 +void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len)
2765 +{
2766 +       dvb_dmx_swfilter(&fc->demux, buf, len);
2767 +}
2768 +EXPORT_SYMBOL(flexcop_pass_dmx_data);
2769 +
2770 +void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
2771 +{
2772 +       dvb_dmx_swfilter_packets(&fc->demux, buf, no);
2773 +}
2774 +EXPORT_SYMBOL(flexcop_pass_dmx_packets);
2775 +
2776 +static void flexcop_reset(struct flexcop_device *fc)
2777 +{
2778 +       flexcop_ibi_value v210, v204;
2779 +
2780 +       /* reset the flexcop itself */
2781 +       fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
2782 +
2783 +       v210.raw = 0;
2784 +       v210.sw_reset_210.reset_block_000 = 1;
2785 +       v210.sw_reset_210.reset_block_100 = 1;
2786 +       v210.sw_reset_210.reset_block_200 = 1;
2787 +       v210.sw_reset_210.reset_block_300 = 1;
2788 +       v210.sw_reset_210.reset_block_400 = 1;
2789 +       v210.sw_reset_210.reset_block_500 = 1;
2790 +       v210.sw_reset_210.reset_block_600 = 1;
2791 +       v210.sw_reset_210.reset_block_700 = 1;
2792 +       v210.sw_reset_210.Block_reset_enable = 0xb2;
2793 +       v210.sw_reset_210.Special_controls = 0xc259;
2794 +       fc->write_ibi_reg(fc,sw_reset_210,v210);
2795 +       msleep(1);
2796 +
2797 +       /* reset the periphical devices */
2798 +
2799 +       v204 = fc->read_ibi_reg(fc,misc_204);
2800 +       v204.misc_204.Per_reset_sig = 0;
2801 +       fc->write_ibi_reg(fc,misc_204,v204);
2802 +       msleep(1);
2803 +       v204.misc_204.Per_reset_sig = 1;
2804 +       fc->write_ibi_reg(fc,misc_204,v204);
2805 +}
2806 +
2807 +void flexcop_reset_block_300(struct flexcop_device *fc)
2808 +{
2809 +       flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
2810 +                         v210 = fc->read_ibi_reg(fc, sw_reset_210);
2811 +
2812 +       deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
2813 +       fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
2814 +
2815 +       v210.sw_reset_210.reset_block_300 = 1;
2816 +       v210.sw_reset_210.Block_reset_enable = 0xb2;
2817 +
2818 +       fc->write_ibi_reg(fc,sw_reset_210,v210);
2819 +       fc->write_ibi_reg(fc,ctrl_208,v208_save);
2820 +}
2821 +
2822 +struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
2823 +{
2824 +       void *bus;
2825 +       struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
2826 +                               GFP_KERNEL);
2827 +       if (!fc) {
2828 +               err("no memory");
2829 +               return NULL;
2830 +       }
2831 +
2832 +       bus = kzalloc(bus_specific_len, GFP_KERNEL);
2833 +       if (!bus) {
2834 +               err("no memory");
2835 +               kfree(fc);
2836 +               return NULL;
2837 +       }
2838 +
2839 +       fc->bus_specific = bus;
2840 +
2841 +       return fc;
2842 +}
2843 +EXPORT_SYMBOL(flexcop_device_kmalloc);
2844 +
2845 +void flexcop_device_kfree(struct flexcop_device *fc)
2846 +{
2847 +       kfree(fc->bus_specific);
2848 +       kfree(fc);
2849 +}
2850 +EXPORT_SYMBOL(flexcop_device_kfree);
2851 +
2852 +int flexcop_device_initialize(struct flexcop_device *fc)
2853 +{
2854 +       int ret;
2855 +       ibi_zero.raw = 0;
2856 +
2857 +       flexcop_reset(fc);
2858 +       flexcop_determine_revision(fc);
2859 +       flexcop_sram_init(fc);
2860 +       flexcop_hw_filter_init(fc);
2861 +       flexcop_smc_ctrl(fc, 0);
2862 +
2863 +       ret = flexcop_dvb_init(fc);
2864 +       if (ret)
2865 +               goto error;
2866 +
2867 +       /* i2c has to be done before doing EEProm stuff -
2868 +        * because the EEProm is accessed via i2c */
2869 +       ret = flexcop_i2c_init(fc);
2870 +       if (ret)
2871 +               goto error;
2872 +
2873 +       /* do the MAC address reading after initializing the dvb_adapter */
2874 +       if (fc->get_mac_addr(fc, 0) == 0) {
2875 +               u8 *b = fc->dvb_adapter.proposed_mac;
2876 +               info("MAC address = %pM", b);
2877 +               flexcop_set_mac_filter(fc,b);
2878 +               flexcop_mac_filter_ctrl(fc,1);
2879 +       } else
2880 +               warn("reading of MAC address failed.\n");
2881 +
2882 +       ret = flexcop_frontend_init(fc);
2883 +       if (ret)
2884 +               goto error;
2885 +
2886 +       flexcop_device_name(fc,"initialization of","complete");
2887 +       return 0;
2888 +
2889 +error:
2890 +       flexcop_device_exit(fc);
2891 +       return ret;
2892 +}
2893 +EXPORT_SYMBOL(flexcop_device_initialize);
2894 +
2895 +void flexcop_device_exit(struct flexcop_device *fc)
2896 +{
2897 +       flexcop_frontend_exit(fc);
2898 +       flexcop_i2c_exit(fc);
2899 +       flexcop_dvb_exit(fc);
2900 +}
2901 +EXPORT_SYMBOL(flexcop_device_exit);
2902 +
2903 +static int flexcop_module_init(void)
2904 +{
2905 +       info(DRIVER_NAME " loaded successfully");
2906 +       return 0;
2907 +}
2908 +
2909 +static void flexcop_module_cleanup(void)
2910 +{
2911 +       info(DRIVER_NAME " unloaded successfully");
2912 +}
2913 +
2914 +module_init(flexcop_module_init);
2915 +module_exit(flexcop_module_cleanup);
2916 +
2917 +MODULE_AUTHOR(DRIVER_AUTHOR);
2918 +MODULE_DESCRIPTION(DRIVER_NAME);
2919 +MODULE_LICENSE("GPL");
2920 diff --git a/drivers/media/common/b2c2/flexcop.h b/drivers/media/common/b2c2/flexcop.h
2921 new file mode 100644
2922 index 0000000..897b10c
2923 --- /dev/null
2924 +++ b/drivers/media/common/b2c2/flexcop.h
2925 @@ -0,0 +1,29 @@
2926 +/*
2927 + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2928 + * flexcop.h - private header file for all flexcop-chip-source files
2929 + * see flexcop.c for copyright information
2930 + */
2931 +#ifndef __FLEXCOP_H__
2932 +#define __FLEXCOP_H___
2933 +
2934 +#define FC_LOG_PREFIX "b2c2-flexcop"
2935 +#include "flexcop-common.h"
2936 +
2937 +extern int b2c2_flexcop_debug;
2938 +
2939 +/* debug */
2940 +#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
2941 +#define dprintk(level,args...) \
2942 +       do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
2943 +#else
2944 +#define dprintk(level,args...)
2945 +#endif
2946 +
2947 +#define deb_info(args...) dprintk(0x01, args)
2948 +#define deb_tuner(args...) dprintk(0x02, args)
2949 +#define deb_i2c(args...) dprintk(0x04, args)
2950 +#define deb_ts(args...) dprintk(0x08, args)
2951 +#define deb_sram(args...) dprintk(0x10, args)
2952 +#define deb_rdump(args...) dprintk(0x20, args)
2953 +
2954 +#endif
2955 diff --git a/drivers/media/common/b2c2/flexcop_ibi_value_be.h b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
2956 new file mode 100644
2957 index 0000000..8f64bdb
2958 --- /dev/null
2959 +++ b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
2960 @@ -0,0 +1,455 @@
2961 +/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2962 + * register descriptions
2963 + * see flexcop.c for copyright information
2964 + */
2965 +/* This file is automatically generated, do not edit things here. */
2966 +#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
2967 +#define __FLEXCOP_IBI_VALUE_INCLUDED__
2968 +
2969 +typedef union {
2970 +       u32 raw;
2971 +
2972 +       struct {
2973 +               u32 dma_address0                   :30;
2974 +               u32 dma_0No_update                 : 1;
2975 +               u32 dma_0start                     : 1;
2976 +       } dma_0x0;
2977 +
2978 +       struct {
2979 +               u32 dma_addr_size                  :24;
2980 +               u32 DMA_maxpackets                 : 8;
2981 +       } dma_0x4_remap;
2982 +
2983 +       struct {
2984 +               u32 dma_addr_size                  :24;
2985 +               u32 unused                         : 1;
2986 +               u32 dma1timer                      : 7;
2987 +       } dma_0x4_read;
2988 +
2989 +       struct {
2990 +               u32 dma_addr_size                  :24;
2991 +               u32 dmatimer                       : 7;
2992 +               u32 unused                         : 1;
2993 +       } dma_0x4_write;
2994 +
2995 +       struct {
2996 +               u32 dma_cur_addr                   :30;
2997 +               u32 unused                         : 2;
2998 +       } dma_0x8;
2999 +
3000 +       struct {
3001 +               u32 dma_address1                   :30;
3002 +               u32 remap_enable                   : 1;
3003 +               u32 dma_1start                     : 1;
3004 +       } dma_0xc;
3005 +
3006 +       struct {
3007 +               u32 st_done                        : 1;
3008 +               u32 no_base_addr_ack_error         : 1;
3009 +               u32 twoWS_port_reg                 : 2;
3010 +               u32 total_bytes                    : 2;
3011 +               u32 twoWS_rw                       : 1;
3012 +               u32 working_start                  : 1;
3013 +               u32 data1_reg                      : 8;
3014 +               u32 baseaddr                       : 8;
3015 +               u32 reserved1                      : 1;
3016 +               u32 chipaddr                       : 7;
3017 +       } tw_sm_c_100;
3018 +
3019 +       struct {
3020 +               u32 unused                         : 6;
3021 +               u32 force_stop                     : 1;
3022 +               u32 exlicit_stops                  : 1;
3023 +               u32 data4_reg                      : 8;
3024 +               u32 data3_reg                      : 8;
3025 +               u32 data2_reg                      : 8;
3026 +       } tw_sm_c_104;
3027 +