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 * ----------------------------------------------------
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.
16 + * Returns negative errno, else the number of messages executed.
18 + * Adapter lock must be held when calling this function. No debug logging
19 + * takes place. adap->algo->master_xfer existence isn't checked.
21 +int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
23 + unsigned long orig_jiffies;
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);
32 + if (time_after(jiffies, orig_jiffies + adap->timeout))
38 +EXPORT_SYMBOL(__i2c_transfer);
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"
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>
59 comment "Multimedia core support"
62 +# Multimedia support - automatically enable V4L2 and DVB core
64 +config MEDIA_CAMERA_SUPPORT
65 + bool "Cameras/video grabbers support"
67 + Enable support for webcams and video grabbers.
69 + Say Y when you have a webcam or a video capture grabber board.
71 +config MEDIA_ANALOG_TV_SUPPORT
72 + bool "Analog TV support"
74 + Enable analog TV support.
76 + Say Y when you have a TV board with analog support or with a
77 + hybrid analog/digital TV chipset.
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.
83 +config MEDIA_DIGITAL_TV_SUPPORT
84 + bool "Digital TV support"
86 + Enable digital TV support.
88 + Say Y when you have a board with digital support or a board with
89 + hybrid digital TV and analog TV.
91 +config MEDIA_RADIO_SUPPORT
92 + bool "AM/FM radio receivers/transmitters support"
94 + Enable AM/FM radio support.
96 + Additional info and docs are available on the web at
97 + <http://linuxtv.org>
99 + Say Y when you have a board with radio support.
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.
105 +config MEDIA_RC_SUPPORT
106 + bool "Remote Controller support"
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.
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.
117 + Say Y when you have a TV or an IR device.
121 +# Selectable only for webcam/grabbers, as other drivers don't use it
124 config MEDIA_CONTROLLER
125 bool "Media Controller API (EXPERIMENTAL)"
126 depends on EXPERIMENTAL
127 + depends on MEDIA_CAMERA_SUPPORT
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.
135 -# V4L core and enabled API's
136 +# Video4Linux support
137 +# Only enables if one of the V4L2 types (ATV, webcam, radio) is selected
141 - tristate "Video For Linux"
143 - V4L core support for video capture and overlay devices, webcams and
146 - This kernel includes support for the new Video for Linux Two API,
149 - Additional info and docs are available on the web at
150 - <http://linuxtv.org>
152 - Documentation for V4L2 is also available on the web at
153 - <http://bytesex.org/v4l/>.
155 - To compile this driver as a module, choose M here: the
156 - module will be called videodev.
158 -config VIDEO_V4L2_COMMON
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
166 config VIDEO_V4L2_SUBDEV_API
167 bool "V4L2 sub-device userspace API (EXPERIMENTAL)"
168 @@ -62,27 +108,19 @@ config VIDEO_V4L2_SUBDEV_API
170 This API is mostly used by camera interfaces in embedded platforms.
172 +source "drivers/media/v4l2-core/Kconfig"
176 +# Only enables if one of DTV is selected
180 - tristate "DVB for Linux"
182 + depends on MEDIA_SUPPORT
183 + depends on MEDIA_DIGITAL_TV_SUPPORT
187 - DVB core utility functions for device handling, software fallbacks etc.
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.
192 - Say Y when you have a DVB or an ATSC card and want to use it.
194 - API specs and user tools are available from <http://www.linuxtv.org/>.
196 - Please report problems regarding this support to the LinuxDVB
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
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
216 -comment "Multimedia drivers"
217 +source "drivers/media/dvb-core/Kconfig"
219 -source "drivers/media/common/Kconfig"
220 +comment "Media drivers"
221 source "drivers/media/rc/Kconfig"
224 -# Tuner drivers for DVB and V4L
225 +# V4L platform/mem2mem drivers
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"
237 -# Video/Radio/Hybrid adapters
239 +comment "Supported FireWire (IEEE 1394) Adapters"
240 + depends on DVB_CORE && FIREWIRE
241 +source "drivers/media/firewire/Kconfig"
243 -source "drivers/media/video/Kconfig"
244 +# Common driver options
245 +source "drivers/media/common/Kconfig"
247 -source "drivers/media/radio/Kconfig"
248 +comment "Media ancillary drivers (tuners, sensors, i2c, frontends)"
252 +# Ancillary drivers (tuners, i2c, frontends)
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
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.
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.
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).
276 +source "drivers/media/i2c/Kconfig"
277 +source "drivers/media/tuners/Kconfig"
278 +source "drivers/media/dvb-frontends/Kconfig"
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
287 media-objs := media-device.o media-devnode.o media-entity.o
290 +# I2C drivers should come before other drivers, otherwise they'll fail
291 +# when compiled as builtin drivers
293 +obj-y += i2c/ tuners/
294 +obj-$(CONFIG_DVB_CORE) += dvb-frontends/
297 +# Now, let's link-in the media core
299 ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
300 obj-$(CONFIG_MEDIA_SUPPORT) += media.o
303 -obj-y += common/ rc/ video/
304 +obj-$(CONFIG_VIDEO_DEV) += v4l2-core/
305 +obj-$(CONFIG_DVB_CORE) += dvb-core/
307 +# There are both core and drivers at RC subtree - merge before drivers
311 +# Finally, merge the drivers that require the core
314 +obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ parport/
315 obj-$(CONFIG_VIDEO_DEV) += radio/
316 -obj-$(CONFIG_DVB_CORE) += dvb/
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
323 -config VIDEO_SAA7146
325 - depends on I2C && PCI
326 +# Used by common drivers, when they need to ask questions
327 +config MEDIA_COMMON_OPTIONS
330 -config VIDEO_SAA7146_VV
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
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
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
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
355 index 0000000..a8c6cdf
357 +++ b/drivers/media/common/b2c2/Kconfig
359 +config DVB_B2C2_FLEXCOP
361 + depends on DVB_CORE && I2C
362 + depends on DVB_B2C2_FLEXCOP_PCI || DVB_B2C2_FLEXCOP_USB
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
379 +# Selected via the PCI or USB flexcop drivers
380 +config DVB_B2C2_FLEXCOP_DEBUG
382 diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
384 index 0000000..24993a5
386 +++ b/drivers/media/common/b2c2/Makefile
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
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
398 index 0000000..437912e
400 +++ b/drivers/media/common/b2c2/flexcop-common.h
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
407 +#ifndef __FLEXCOP_COMMON_H__
408 +#define __FLEXCOP_COMMON_H__
410 +#include <linux/interrupt.h>
411 +#include <linux/pci.h>
412 +#include <linux/mutex.h>
414 +#include "flexcop-reg.h"
417 +#include "dvb_demux.h"
418 +#include "dvb_filter.h"
419 +#include "dvb_net.h"
420 +#include "dvb_frontend.h"
422 +#define FC_MAX_FEED 256
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"
429 +/* Steal from usb.h */
431 +#define err(format, arg...) \
432 + printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
434 +#define info(format, arg...) \
435 + printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
437 +#define warn(format, arg...) \
438 + printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
440 +struct flexcop_dma {
441 + struct pci_dev *pdev;
444 + dma_addr_t dma_addr0;
446 + dma_addr_t dma_addr1;
447 + u32 size; /* size of each address in bytes */
450 +struct flexcop_i2c_adapter {
451 + struct flexcop_device *fc;
452 + struct i2c_adapter i2c_adap;
455 + flexcop_i2c_port_t port;
458 +/* Control structure for data definitions that are common to
459 + * the B2C2-based PCI and USB devices.
461 +struct flexcop_device {
463 + struct device *dev; /* for firmware_class */
465 +#define FC_STATE_DVB_INIT 0x01
466 +#define FC_STATE_I2C_INIT 0x02
467 +#define FC_STATE_FE_INIT 0x04
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;
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 *);
486 + struct flexcop_i2c_adapter fc_i2c_adap[3];
487 + struct mutex i2c_mutex;
488 + struct module *owner;
490 + /* options and status */
491 + int extra_feedcount;
494 + int fullts_streaming_state;
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;
508 +/* exported prototypes */
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);
514 +struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
515 +void flexcop_device_kfree(struct flexcop_device *);
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);
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);
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,
535 +int flexcop_dma_config_timer(struct flexcop_device *fc,
536 + flexcop_dma_index_t dma_idx, u8 cycles);
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);
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.
547 +int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
548 + u8 chipaddr, u8 addr, u8 *buf, u16 len);
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);
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);
562 +/* from flexcop-i2c.c */
563 +int flexcop_i2c_init(struct flexcop_device *fc);
564 +void flexcop_i2c_exit(struct flexcop_device *fc);
566 +/* from flexcop-sram.c */
567 +int flexcop_sram_init(struct flexcop_device *fc);
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);
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);
581 +void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
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);
587 diff --git a/drivers/media/common/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c
589 index 0000000..a25373a
591 +++ b/drivers/media/common/b2c2/flexcop-eeprom.c
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
598 +#include "flexcop.h"
601 +/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
602 +static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
604 + return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
607 +static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
608 + u32 len, u8 *wbuf, u8 *rbuf, int retries)
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)
621 +/* These functions could be used to unlock SkyStar2 cards. */
623 +static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
631 + memcpy(wbuf, key, len);
635 + wbuf[19] = calc_lrc(wbuf, 19);
636 + return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
639 +static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
646 + if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
649 + memcpy(key, buf, len);
653 +static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
674 + tmp[7] = calc_lrc(tmp, 7);
676 + if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
681 +static int flexcop_eeprom_read(struct flexcop_device *fc,
682 + u16 addr, u8 *buf, u16 len)
684 + return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
689 +static u8 calc_lrc(u8 *buf, int len)
693 + for (i = 0; i < len; i++)
694 + sum = sum ^ buf[i];
698 +static int flexcop_eeprom_request(struct flexcop_device *fc,
699 + flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
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);
712 +static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
713 + u8 *buf, u16 len, int retries)
715 + int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
717 + if (calc_lrc(buf, len - 1) != buf[len - 1])
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)
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");
735 + memcpy(fc->dvb_adapter.proposed_mac,buf,6);
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
742 index 0000000..850a6c6
744 +++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
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
751 +#include <media/tuner.h>
752 +#include "flexcop.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"
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"
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)))
775 +#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
776 +static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
778 + struct flexcop_device *fc = fe->dvb->priv;
779 + flexcop_ibi_value v;
780 + deb_tuner("polarity/voltage = %u\n", voltage);
782 + v = fc->read_ibi_reg(fc, misc_204);
784 + case SEC_VOLTAGE_OFF:
785 + v.misc_204.ACPI1_sig = 1;
787 + case SEC_VOLTAGE_13:
788 + v.misc_204.ACPI1_sig = 0;
789 + v.misc_204.LNB_L_H_sig = 0;
791 + case SEC_VOLTAGE_18:
792 + v.misc_204.ACPI1_sig = 0;
793 + v.misc_204.LNB_L_H_sig = 1;
796 + err("unknown SEC_VOLTAGE value");
799 + return fc->write_ibi_reg(fc, misc_204, v);
803 +#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
804 +static int flexcop_sleep(struct dvb_frontend* fe)
806 + struct flexcop_device *fc = fe->dvb->priv;
808 + return fc->fe_sleep(fe);
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)
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;
822 + deb_tuner("tone = %u\n",tone);
832 + err("unknown SEC_TONE value");
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);
842 +static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
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);
850 +static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
853 + for (i = 7; i >= 0; i--) {
854 + d = (data >> i) & 1;
856 + flexcop_diseqc_send_bit(fe, d);
858 + flexcop_diseqc_send_bit(fe, par);
861 +static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
862 + int len, u8 *msg, unsigned long burst)
866 + flexcop_set_tone(fe, SEC_TONE_OFF);
869 + for (i = 0; i < len; i++)
870 + flexcop_diseqc_send_byte(fe,msg[i]);
875 + flexcop_diseqc_send_byte(fe, 0xff);
877 + flexcop_set_tone(fe, SEC_TONE_ON);
880 + flexcop_set_tone(fe, SEC_TONE_OFF);
887 +static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
888 + struct dvb_diseqc_master_cmd *cmd)
890 + return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
893 +static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
894 + fe_sec_mini_cmd_t minicmd)
896 + return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
899 +static struct mt312_config skystar23_samsung_tbdu18132_config = {
900 + .demod_address = 0x0e,
903 +static int skystar2_rev23_attach(struct flexcop_device *fc,
904 + struct i2c_adapter *i2c)
906 + struct dvb_frontend_ops *ops;
908 + fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
912 + if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
913 + DVB_PLL_SAMSUNG_TBDU18132))
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;
926 +#define skystar2_rev23_attach NULL
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)
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;
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);
959 +static u8 samsung_tbmu24112_inittab[] = {
1004 +static struct stv0299_config samsung_tbmu24112_config = {
1005 + .demod_address = 0x68,
1006 + .inittab = samsung_tbmu24112_inittab,
1007 + .mclk = 88000000UL,
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,
1016 +static int skystar2_rev26_attach(struct flexcop_device *fc,
1017 + struct i2c_adapter *i2c)
1019 + fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
1023 + if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
1024 + DVB_PLL_SAMSUNG_TBMU24112))
1027 + fc->fe->ops.set_voltage = flexcop_set_voltage;
1028 + fc->fe_sleep = fc->fe->ops.sleep;
1029 + fc->fe->ops.sleep = flexcop_sleep;
1034 +#define skystar2_rev26_attach NULL
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,
1042 + .repeated_start_workaround = 1,
1046 +static struct itd1000_config skystar2_rev2_7_itd1000_config = {
1047 + .i2c_address = 0x61,
1050 +static int skystar2_rev27_attach(struct flexcop_device *fc,
1051 + struct i2c_adapter *i2c)
1053 + flexcop_ibi_value r108;
1054 + struct i2c_adapter *i2c_tuner;
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,
1063 + i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
1067 + fc->fe_sleep = fc->fe->ops.sleep;
1068 + fc->fe->ops.sleep = flexcop_sleep;
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,
1074 + err("ISL6421 could NOT be attached");
1077 + info("ISL6421 successfully attached");
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? */
1088 + info("ITD1000 successfully attached");
1093 + fc->fc_i2c_adap[2].no_base_addr = 0;
1095 + /* for the next devices we need it again */
1096 + fc->fc_i2c_adap[0].no_base_addr = 0;
1100 +#define skystar2_rev27_attach NULL
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,
1111 +static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
1113 + .xtal_khz = 10111,
1116 +static int skystar2_rev28_attach(struct flexcop_device *fc,
1117 + struct i2c_adapter *i2c)
1119 + struct i2c_adapter *i2c_tuner;
1121 + fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
1126 + i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
1130 + if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
1132 + err("CX24113 could NOT be attached");
1135 + info("CX24113 successfully attached");
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,
1140 + err("ISL6421 could NOT be attached");
1141 + fc->fc_i2c_adap[2].no_base_addr = 0;
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 ??? */
1150 +#define skystar2_rev28_attach NULL
1153 +/* AirStar DVB-T */
1154 +#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
1155 +static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
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 };
1163 + mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
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));
1172 +static struct mt352_config samsung_tdtc9251dh0_config = {
1173 + .demod_address = 0x0f,
1174 + .demod_init = samsung_tdtc9251dh0_demod_init,
1177 +static int airstar_dvbt_attach(struct flexcop_device *fc,
1178 + struct i2c_adapter *i2c)
1180 + fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
1184 + return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
1185 + DVB_PLL_SAMSUNG_TDTC9251DH0);
1188 +#define airstar_dvbt_attach NULL
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)
1196 + struct flexcop_device *fc = fe->dvb->priv;
1197 + return request_firmware(fw, name, fc->dev);
1200 +static struct bcm3510_config air2pc_atsc_first_gen_config = {
1201 + .demod_address = 0x0f,
1202 + .request_firmware = flexcop_fe_request_firmware,
1205 +static int airstar_atsc1_attach(struct flexcop_device *fc,
1206 + struct i2c_adapter *i2c)
1208 + fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
1209 + return fc->fe != NULL;
1212 +#define airstar_atsc1_attach NULL
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,
1221 +static int airstar_atsc2_attach(struct flexcop_device *fc,
1222 + struct i2c_adapter *i2c)
1224 + fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
1228 + return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
1229 + DVB_PLL_SAMSUNG_TBMV);
1232 +#define airstar_atsc2_attach NULL
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,
1244 +static int airstar_atsc3_attach(struct flexcop_device *fc,
1245 + struct i2c_adapter *i2c)
1247 + fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
1251 + return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
1252 + TUNER_LG_TDVS_H06XF);
1255 +#define airstar_atsc3_attach NULL
1258 +/* CableStar2 DVB-C */
1259 +#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
1260 +static u8 alps_tdee4_stv0297_inittab[] = {
1333 +static struct stv0297_config alps_tdee4_stv0297_config = {
1334 + .demod_address = 0x1c,
1335 + .inittab = alps_tdee4_stv0297_inittab,
1338 +static int cablestar2_attach(struct flexcop_device *fc,
1339 + struct i2c_adapter *i2c)
1341 + fc->fc_i2c_adap[0].no_base_addr = 1;
1342 + fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
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;
1352 + if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
1353 + &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
1359 + /* Reset for next frontend to try */
1360 + fc->fc_i2c_adap[0].no_base_addr = 0;
1364 +#define cablestar2_attach NULL
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 },
1382 +/* try to figure out the frontend */
1383 +int flexcop_frontend_init(struct flexcop_device *fc)
1386 + for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
1387 + if (!flexcop_frontends[i].attach)
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))
1394 + /* Clean up partially attached frontend */
1396 + dvb_frontend_detach(fc->fe);
1400 + fc->dev_type = FC_UNK;
1401 + err("no frontend driver found for this B2C2/FlexCop adapter");
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);
1412 + fc->init_state |= FC_STATE_FE_INIT;
1416 +void flexcop_frontend_exit(struct flexcop_device *fc)
1418 + if (fc->init_state & FC_STATE_FE_INIT) {
1419 + dvb_unregister_frontend(fc->fe);
1420 + dvb_frontend_detach(fc->fe);
1422 + fc->init_state &= ~FC_STATE_FE_INIT;
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
1428 +++ b/drivers/media/common/b2c2/flexcop-hw-filter.c
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
1435 +#include "flexcop.h"
1437 +static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
1439 + flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
1440 + deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
1443 +void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
1445 + flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
1448 +static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
1450 + flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
1453 +void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
1455 + flexcop_ibi_value v418, v41c;
1456 + v41c = fc->read_ibi_reg(fc, mac_address_41c);
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];
1465 + fc->write_ibi_reg(fc, mac_address_418, v418);
1466 + fc->write_ibi_reg(fc, mac_address_41c, v41c);
1469 +void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
1471 + flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
1474 +static void flexcop_pid_group_filter(struct flexcop_device *fc,
1475 + u16 pid, u16 mask)
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);
1484 +static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
1486 + flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
1489 +/* this fancy define reduces the code size of the quite similar PID controlling of
1490 + * the first 6 PIDs
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);
1502 +static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
1503 + u16 pid, int onoff)
1505 + pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
1506 + Stream1_trans, 0);
1509 +static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
1510 + u16 pid, int onoff)
1512 + pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
1513 + Stream2_trans, 0);
1516 +static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
1517 + u16 pid, int onoff)
1519 + pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
1522 +static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
1523 + u16 pid, int onoff)
1525 + pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
1528 +static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
1529 + u16 pid, int onoff)
1531 + pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
1534 +static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
1535 + u16 pid, int onoff)
1537 + pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
1540 +static void flexcop_pid_control(struct flexcop_device *fc,
1541 + int index, u16 pid, int onoff)
1543 + if (pid == 0x2000)
1546 + deb_ts("setting pid: %5d %04x at index %d '%s'\n",
1547 + pid, pid, index, onoff ? "on" : "off");
1549 + /* We could use bit magic here to reduce source code size.
1550 + * I decided against it, but to use the real register names */
1553 + flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
1556 + flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
1559 + flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
1562 + flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
1565 + flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
1568 + flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
1571 + if (fc->has_32_hw_pid_filter && index < 38) {
1572 + flexcop_ibi_value vpid, vid;
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);
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);
1588 +static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
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;
1599 +int flexcop_pid_feed_control(struct flexcop_device *fc,
1600 + struct dvb_demux_feed *dvbdmxfeed, int onoff)
1602 + int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
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;
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 */
1614 + if (!fc->pid_filtering && fc->feedcount == onoff)
1615 + flexcop_toggle_fullts_streaming(fc, onoff);
1617 + if (fc->pid_filtering) {
1618 + flexcop_pid_control \
1619 + (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
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);
1626 + flexcop_toggle_fullts_streaming(fc, 0);
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);
1635 + /* feeding stopped -> reset the flexcop filter*/
1637 + flexcop_reset_block_300(fc);
1638 + flexcop_hw_filter_init(fc);
1643 +EXPORT_SYMBOL(flexcop_pid_feed_control);
1645 +void flexcop_hw_filter_init(struct flexcop_device *fc)
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);
1652 + flexcop_pid_group_filter(fc, 0, 0x1fe0);
1653 + flexcop_pid_group_filter_ctrl(fc, 0);
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);
1660 + flexcop_null_filter_ctrl(fc, 1);
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
1666 +++ b/drivers/media/common/b2c2/flexcop-i2c.c
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
1673 +#include "flexcop.h"
1675 +#define FC_MAX_I2C_RETRIES 100000
1677 +static int flexcop_i2c_operation(struct flexcop_device *fc,
1678 + flexcop_ibi_value *r100)
1681 + flexcop_ibi_value r;
1683 + r100->tw_sm_c_100.working_start = 1;
1684 + deb_i2c("r100 before: %08x\n",r100->raw);
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 */
1689 + for (i = 0; i < FC_MAX_I2C_RETRIES; i++) {
1690 + r = fc->read_ibi_reg(fc, tw_sm_c_100);
1692 + if (!r.tw_sm_c_100.no_base_addr_ack_error) {
1693 + if (r.tw_sm_c_100.st_done) {
1695 + deb_i2c("i2c success\n");
1699 + deb_i2c("suffering from an i2c ack_error\n");
1700 + return -EREMOTEIO;
1703 + deb_i2c("tried %d times i2c operation, "
1704 + "never finished or too many ack errors.\n", i);
1705 + return -EREMOTEIO;
1708 +static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
1709 + flexcop_ibi_value r100, u8 *buf)
1711 + flexcop_ibi_value r104;
1712 + int len = r100.tw_sm_c_100.total_bytes,
1713 + /* remember total_bytes is buflen-1 */
1716 + /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
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
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;
1728 + ret = flexcop_i2c_operation(i2c->fc, &r100);
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);
1735 + deb_i2c("read failed. %d\n", ret);
1739 + buf[0] = r100.tw_sm_c_100.data1_reg;
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);
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;
1753 +static int flexcop_i2c_write4(struct flexcop_device *fc,
1754 + flexcop_ibi_value r100, u8 *buf)
1756 + flexcop_ibi_value r104;
1757 + int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
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;
1766 + deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
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);
1773 +int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
1774 + flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
1778 +#ifdef DUMP_I2C_MESSAGES
1782 + u16 bytes_to_transfer;
1783 + flexcop_ibi_value r100;
1785 + deb_i2c("op = %d\n",op);
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;
1791 +#ifdef DUMP_I2C_MESSAGES
1792 + printk(KERN_DEBUG "%d ", i2c->port);
1793 + if (op == FC_READ)
1797 + printk("%02x): %02x ", chipaddr, addr);
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) {
1808 + while (len != 0) {
1809 + bytes_to_transfer = len > 4 ? 4 : len;
1811 + r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1;
1812 + r100.tw_sm_c_100.baseaddr = addr;
1814 + if (op == FC_READ)
1815 + ret = flexcop_i2c_read4(i2c, r100, buf);
1817 + ret = flexcop_i2c_write4(i2c->fc, r100, buf);
1819 +#ifdef DUMP_I2C_MESSAGES
1820 + for (i = 0; i < bytes_to_transfer; i++)
1821 + printk("%02x ", buf[i]);
1827 + buf += bytes_to_transfer;
1828 + addr += bytes_to_transfer;
1829 + len -= bytes_to_transfer;
1832 +#ifdef DUMP_I2C_MESSAGES
1838 +/* exported for PCI i2c */
1839 +EXPORT_SYMBOL(flexcop_i2c_request);
1841 +/* master xfer callback for demodulator */
1842 +static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
1843 + struct i2c_msg msgs[], int num)
1845 + struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
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)
1855 + if (mutex_lock_interruptible(&i2c->fc->i2c_mutex))
1856 + return -ERESTARTSYS;
1858 + for (i = 0; i < num; i++) {
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,
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],
1870 + deb_i2c("i2c master_xfer failed");
1875 + mutex_unlock(&i2c->fc->i2c_mutex);
1882 +static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
1884 + return I2C_FUNC_I2C;
1887 +static struct i2c_algorithm flexcop_algo = {
1888 + .master_xfer = flexcop_master_xfer,
1889 + .functionality = flexcop_i2c_func,
1892 +int flexcop_i2c_init(struct flexcop_device *fc)
1895 + mutex_init(&fc->i2c_mutex);
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;
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));
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]);
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;
1925 + ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap);
1929 + ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
1931 + goto adap_1_failed;
1933 + ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap);
1935 + goto adap_2_failed;
1937 + fc->init_state |= FC_STATE_I2C_INIT;
1941 + i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
1943 + i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
1947 +void flexcop_i2c_exit(struct flexcop_device *fc)
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);
1954 + fc->init_state &= ~FC_STATE_I2C_INIT;
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
1960 +++ b/drivers/media/common/b2c2/flexcop-misc.c
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
1967 +#include "flexcop.h"
1969 +void flexcop_determine_revision(struct flexcop_device *fc)
1971 + flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
1973 + switch (v.misc_204.Rev_N_sig_revision_hi) {
1975 + deb_info("found a FlexCopII.\n");
1976 + fc->rev = FLEXCOP_II;
1979 + deb_info("found a FlexCopIIb.\n");
1980 + fc->rev = FLEXCOP_IIB;
1983 + deb_info("found a FlexCopIII.\n");
1984 + fc->rev = FLEXCOP_III;
1987 + err("unknown FlexCop Revision: %x. Please report this to "
1988 + "linux-dvb@linuxtv.org.",
1989 + v.misc_204.Rev_N_sig_revision_hi);
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");
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. */
2002 +static const char *flexcop_revision_names[] = {
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",
2022 +static const char *flexcop_bus_names[] = {
2027 +void flexcop_device_name(struct flexcop_device *fc,
2028 + const char *prefix, const char *suffix)
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);
2036 +void flexcop_dump_reg(struct flexcop_device *fc,
2037 + flexcop_ibi_register reg, int num)
2039 + flexcop_ibi_value v;
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);
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
2052 +++ b/drivers/media/common/b2c2/flexcop-reg.h
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
2059 +#ifndef __FLEXCOP_REG_H__
2060 +#define __FLEXCOP_REG_H__
2067 +} flexcop_revision_t;
2080 +} flexcop_device_type_t;
2087 +/* FlexCop IBI Registers */
2088 +#if defined(__LITTLE_ENDIAN)
2089 +#include "flexcop_ibi_value_le.h"
2091 +#if defined(__BIG_ENDIAN)
2092 +#include "flexcop_ibi_value_be.h"
2094 +#error no endian defined
2098 +#define fc_data_Tag_ID_DVB 0x3e
2099 +#define fc_data_Tag_ID_ATSC 0x3f
2100 +#define fc_data_Tag_ID_IDSB 0x8b
2102 +#define fc_key_code_default 0x1
2103 +#define fc_key_code_even 0x2
2104 +#define fc_key_code_odd 0x3
2106 +extern flexcop_ibi_value ibi_zero;
2109 + FC_I2C_PORT_DEMOD = 1,
2110 + FC_I2C_PORT_EEPROM = 2,
2111 + FC_I2C_PORT_TUNER = 3,
2112 +} flexcop_i2c_port_t;
2117 +} flexcop_access_op_t;
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;
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;
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;
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;
2150 +} flexcop_dma_index_t;
2153 + FC_DMA_SUBADDR_0 = 1,
2154 + FC_DMA_SUBADDR_1 = 2,
2155 +} flexcop_dma_addr_index_t;
2157 +/* names of the particular registers */
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,
2174 + lnb_switch_freq_200 = 0x200,
2178 + sw_reset_210 = 0x210,
2180 + mbox_v8_to_host_218 = 0x218,
2181 + mbox_host_to_v8_21c = 0x21c,
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,
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,
2201 + dvb_reg_60c = 0x60c,
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;
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); \
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
2224 +++ b/drivers/media/common/b2c2/flexcop-sram.c
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
2231 +#include "flexcop.h"
2233 +static void flexcop_sram_set_chip(struct flexcop_device *fc,
2234 + flexcop_sram_type_t type)
2236 + flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
2239 +int flexcop_sram_init(struct flexcop_device *fc)
2241 + switch (fc->rev) {
2244 + flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
2247 + flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
2255 +int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
2256 + flexcop_sram_dest_target_t target)
2258 + flexcop_ibi_value v;
2259 + v = fc->read_ibi_reg(fc, sram_dest_reg_714);
2261 + if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
2262 + err("SRAM destination target to available on FlexCopII(b)\n");
2265 + deb_sram("sram dest: %x target: %x\n", dest, target);
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;
2276 + fc->write_ibi_reg(fc,sram_dest_reg_714,v);
2277 + udelay(1000); /* TODO delay really necessary */
2281 +EXPORT_SYMBOL(flexcop_sram_set_dest);
2283 +void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
2285 + flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
2287 +EXPORT_SYMBOL(flexcop_wan_set_speed);
2289 +void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
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);
2297 +EXPORT_SYMBOL(flexcop_sram_ctrl);
2300 +static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
2305 + for (i = 0; i < len; i++) {
2306 + command = bank | addr | 0x04000000 | (*buf << 0x10);
2310 + while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
2316 + printk("%s: SRAM timeout\n", __func__);
2318 + write_reg_dw(adapter, 0x700, command);
2325 +static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
2328 + u32 command, value;
2330 + for (i = 0; i < len; i++) {
2331 + command = bank | addr | 0x04008000;
2335 + while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
2341 + printk("%s: SRAM timeout\n", __func__);
2343 + write_reg_dw(adapter, 0x700, command);
2347 + while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
2353 + printk("%s: SRAM timeout\n", __func__);
2355 + value = read_reg_dw(adapter, 0x700) >> 0x10;
2357 + *buf = (value & 0xff);
2364 +static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
2370 + if (adapter->dw_sram_type == 0x20000) {
2371 + bank = (addr & 0x18000) << 0x0d;
2374 + if (adapter->dw_sram_type == 0x00000) {
2375 + if ((addr >> 0x0f) == 0)
2376 + bank = 0x20000000;
2378 + bank = 0x10000000;
2380 + flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
2383 +static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
2388 + if (adapter->dw_sram_type == 0x20000) {
2389 + bank = (addr & 0x18000) << 0x0d;
2392 + if (adapter->dw_sram_type == 0x00000) {
2393 + if ((addr >> 0x0f) == 0)
2394 + bank = 0x20000000;
2396 + bank = 0x10000000;
2398 + flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
2401 +static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
2404 + while (len != 0) {
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;
2413 + sram_read_chunk(adapter, addr, buf, length);
2414 + addr = addr + length;
2415 + buf = buf + length;
2416 + len = len - length;
2420 +static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
2423 + while (len != 0) {
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;
2433 + sram_write_chunk(adapter, addr, buf, length);
2434 + addr = addr + length;
2435 + buf = buf + length;
2436 + len = len - length;
2440 +static void sram_set_size(struct adapter *adapter, u32 mask)
2442 + write_reg_dw(adapter, 0x71c,
2443 + (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
2446 +static void sram_init(struct adapter *adapter)
2449 + tmp = read_reg_dw(adapter, 0x71c);
2450 + write_reg_dw(adapter, 0x71c, 1);
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);
2457 + adapter->dw_sram_type = 0x10000;
2458 + ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
2462 +static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
2465 + dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
2467 + sram_set_size(adapter, mask);
2468 + sram_init(adapter);
2473 + sram_write(adapter, addr, &tmp2, 1);
2474 + sram_write(adapter, addr + 4, &tmp1, 1);
2479 + sram_read(adapter, addr, &tmp2, 1);
2480 + sram_read(adapter, addr, &tmp2, 1);
2482 + dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
2490 + sram_write(adapter, addr, &tmp2, 1);
2491 + sram_write(adapter, addr + 4, &tmp1, 1);
2496 + sram_read(adapter, addr, &tmp2, 1);
2497 + sram_read(adapter, addr, &tmp2, 1);
2499 + dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
2506 +static u32 sram_length(struct adapter *adapter)
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 */
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.
2522 + FlexCop works only with one bank at a time. The bank is selected
2523 + by bits 28-29 of the 0x700 register.
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 */
2530 +static int flexcop_sram_detect(struct flexcop_device *fc)
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);
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);
2542 + // check for internal SRAM ???
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__);
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__);
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__);
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__);
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__);
2583 +static void sll_detect_sram_size(struct adapter *adapter)
2585 + sram_detect_for_flex2(adapter);
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
2593 +++ b/drivers/media/common/b2c2/flexcop.c
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
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)
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
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.
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.
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.
2628 +#include "flexcop.h"
2630 +#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
2631 +#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
2633 +#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
2634 +#define DEBSTATUS ""
2636 +#define DEBSTATUS " (debugging is not enabled)"
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))."
2648 +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
2650 +/* global zero for ibi values */
2651 +flexcop_ibi_value ibi_zero;
2653 +static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
2655 + struct flexcop_device *fc = dvbdmxfeed->demux->priv;
2656 + return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
2659 +static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
2661 + struct flexcop_device *fc = dvbdmxfeed->demux->priv;
2662 + return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
2665 +static int flexcop_dvb_init(struct flexcop_device *fc)
2667 + int ret = dvb_register_adapter(&fc->dvb_adapter,
2668 + "FlexCop Digital TV device", fc->owner,
2669 + fc->dev, adapter_nr);
2671 + err("error registering DVB adapter");
2674 + fc->dvb_adapter.priv = fc;
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;
2684 + ret = dvb_dmx_init(&fc->demux);
2686 + err("dvb_dmx failed: error %d", ret);
2690 + fc->hw_frontend.source = DMX_FRONTEND_0;
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);
2697 + err("dvb_dmxdev_init failed: error %d", ret);
2701 + ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend);
2703 + err("adding hw_frontend to dmx failed: error %d", ret);
2704 + goto err_dmx_add_hw_frontend;
2707 + fc->mem_frontend.source = DMX_MEMORY_FE;
2708 + ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend);
2710 + err("adding mem_frontend to dmx failed: error %d", ret);
2711 + goto err_dmx_add_mem_frontend;
2714 + ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend);
2716 + err("connect frontend failed: error %d", ret);
2717 + goto err_connect_frontend;
2720 + ret = dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
2722 + err("dvb_net_init failed: error %d", ret);
2726 + fc->init_state |= FC_STATE_DVB_INIT;
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);
2738 + dvb_dmx_release(&fc->demux);
2740 + dvb_unregister_adapter(&fc->dvb_adapter);
2744 +static void flexcop_dvb_exit(struct flexcop_device *fc)
2746 + if (fc->init_state & FC_STATE_DVB_INIT) {
2747 + dvb_net_release(&fc->dvbnet);
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");
2759 + fc->init_state &= ~FC_STATE_DVB_INIT;
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)
2766 + dvb_dmx_swfilter(&fc->demux, buf, len);
2768 +EXPORT_SYMBOL(flexcop_pass_dmx_data);
2770 +void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
2772 + dvb_dmx_swfilter_packets(&fc->demux, buf, no);
2774 +EXPORT_SYMBOL(flexcop_pass_dmx_packets);
2776 +static void flexcop_reset(struct flexcop_device *fc)
2778 + flexcop_ibi_value v210, v204;
2780 + /* reset the flexcop itself */
2781 + fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
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);
2797 + /* reset the periphical devices */
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);
2803 + v204.misc_204.Per_reset_sig = 1;
2804 + fc->write_ibi_reg(fc,misc_204,v204);
2807 +void flexcop_reset_block_300(struct flexcop_device *fc)
2809 + flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
2810 + v210 = fc->read_ibi_reg(fc, sw_reset_210);
2812 + deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
2813 + fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
2815 + v210.sw_reset_210.reset_block_300 = 1;
2816 + v210.sw_reset_210.Block_reset_enable = 0xb2;
2818 + fc->write_ibi_reg(fc,sw_reset_210,v210);
2819 + fc->write_ibi_reg(fc,ctrl_208,v208_save);
2822 +struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
2825 + struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
2832 + bus = kzalloc(bus_specific_len, GFP_KERNEL);
2839 + fc->bus_specific = bus;
2843 +EXPORT_SYMBOL(flexcop_device_kmalloc);
2845 +void flexcop_device_kfree(struct flexcop_device *fc)
2847 + kfree(fc->bus_specific);
2850 +EXPORT_SYMBOL(flexcop_device_kfree);
2852 +int flexcop_device_initialize(struct flexcop_device *fc)
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);
2863 + ret = flexcop_dvb_init(fc);
2867 + /* i2c has to be done before doing EEProm stuff -
2868 + * because the EEProm is accessed via i2c */
2869 + ret = flexcop_i2c_init(fc);
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);
2880 + warn("reading of MAC address failed.\n");
2882 + ret = flexcop_frontend_init(fc);
2886 + flexcop_device_name(fc,"initialization of","complete");
2890 + flexcop_device_exit(fc);
2893 +EXPORT_SYMBOL(flexcop_device_initialize);
2895 +void flexcop_device_exit(struct flexcop_device *fc)
2897 + flexcop_frontend_exit(fc);
2898 + flexcop_i2c_exit(fc);
2899 + flexcop_dvb_exit(fc);
2901 +EXPORT_SYMBOL(flexcop_device_exit);
2903 +static int flexcop_module_init(void)
2905 + info(DRIVER_NAME " loaded successfully");
2909 +static void flexcop_module_cleanup(void)
2911 + info(DRIVER_NAME " unloaded successfully");
2914 +module_init(flexcop_module_init);
2915 +module_exit(flexcop_module_cleanup);
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
2924 +++ b/drivers/media/common/b2c2/flexcop.h
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
2931 +#ifndef __FLEXCOP_H__
2932 +#define __FLEXCOP_H___
2934 +#define FC_LOG_PREFIX "b2c2-flexcop"
2935 +#include "flexcop-common.h"
2937 +extern int b2c2_flexcop_debug;
2940 +#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
2941 +#define dprintk(level,args...) \
2942 + do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
2944 +#define dprintk(level,args...)
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)
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
2959 +++ b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
2961 +/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2962 + * register descriptions
2963 + * see flexcop.c for copyright information
2965 +/* This file is automatically generated, do not edit things here. */
2966 +#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
2967 +#define __FLEXCOP_IBI_VALUE_INCLUDED__
2973 + u32 dma_address0 :30;
2974 + u32 dma_0No_update : 1;
2975 + u32 dma_0start : 1;
2979 + u32 dma_addr_size :24;
2980 + u32 DMA_maxpackets : 8;
2984 + u32 dma_addr_size :24;
2986 + u32 dma1timer : 7;
2990 + u32 dma_addr_size :24;
2996 + u32 dma_cur_addr :30;
3001 + u32 dma_address1 :30;
3002 + u32 remap_enable : 1;
3003 + u32 dma_1start : 1;
3008 + u32 no_base_addr_ack_error : 1;
3009 + u32 twoWS_port_reg : 2;
3010 + u32 total_bytes : 2;
3012 + u32 working_start : 1;
3013 + u32 data1_reg : 8;
3015 + u32 reserved1 : 1;
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;