aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-06-14 15:35:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-13 22:38:31 -0400
commit3785bc170f79ef04129731582b468c28e1326d6d (patch)
treeb29b6c6ffc96418f134f4801eb7dcc053d227e56 /drivers/media/common
parent25aee3debe0464f6c680173041fa3de30ec9ff54 (diff)
[media] b2c2: break it into common/pci/usb directories
b2c2 is, in fact, 2 drivers: one for PCI and one for USB, plus a common bus-independent code. Break it accordingly. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/Kconfig2
-rw-r--r--drivers/media/common/Makefile2
-rw-r--r--drivers/media/common/b2c2/Kconfig31
-rw-r--r--drivers/media/common/b2c2/Makefile7
-rw-r--r--drivers/media/common/b2c2/flexcop-common.h185
-rw-r--r--drivers/media/common/b2c2/flexcop-eeprom.c147
-rw-r--r--drivers/media/common/b2c2/flexcop-fe-tuner.c678
-rw-r--r--drivers/media/common/b2c2/flexcop-hw-filter.c232
-rw-r--r--drivers/media/common/b2c2/flexcop-i2c.c288
-rw-r--r--drivers/media/common/b2c2/flexcop-misc.c86
-rw-r--r--drivers/media/common/b2c2/flexcop-reg.h166
-rw-r--r--drivers/media/common/b2c2/flexcop-sram.c363
-rw-r--r--drivers/media/common/b2c2/flexcop.c324
-rw-r--r--drivers/media/common/b2c2/flexcop.h29
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_be.h455
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_le.h455
16 files changed, 3449 insertions, 1 deletions
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 769c6f8142d..4672f7d82f6 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -7,3 +7,5 @@ config VIDEO_SAA7146_VV
7 depends on VIDEO_V4L2 7 depends on VIDEO_V4L2
8 select VIDEOBUF_DMA_SG 8 select VIDEOBUF_DMA_SG
9 select VIDEO_SAA7146 9 select VIDEO_SAA7146
10
11source "drivers/media/common/b2c2/Kconfig"
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index e3ec9639321..d0512d7e555 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,6 +1,6 @@
1saa7146-objs := saa7146_i2c.o saa7146_core.o 1saa7146-objs := saa7146_i2c.o saa7146_core.o
2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o 2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
3 3
4obj-y += tuners/ 4obj-y += tuners/ b2c2/
5obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o 5obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
6obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o 6obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
diff --git a/drivers/media/common/b2c2/Kconfig b/drivers/media/common/b2c2/Kconfig
new file mode 100644
index 00000000000..e270dd84734
--- /dev/null
+++ b/drivers/media/common/b2c2/Kconfig
@@ -0,0 +1,31 @@
1config DVB_B2C2_FLEXCOP
2 tristate
3 depends on DVB_CORE && I2C
4 depends on DVB_B2C2_FLEXCOP_PCI || DVB_B2C2_FLEXCOP_USB
5 default y
6 select DVB_PLL if !DVB_FE_CUSTOMISE
7 select DVB_STV0299 if !DVB_FE_CUSTOMISE
8 select DVB_MT352 if !DVB_FE_CUSTOMISE
9 select DVB_MT312 if !DVB_FE_CUSTOMISE
10 select DVB_NXT200X if !DVB_FE_CUSTOMISE
11 select DVB_STV0297 if !DVB_FE_CUSTOMISE
12 select DVB_BCM3510 if !DVB_FE_CUSTOMISE
13 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
14 select DVB_S5H1420 if !DVB_FE_CUSTOMISE
15 select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
16 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
17 select DVB_CX24123 if !DVB_FE_CUSTOMISE
18 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
19 select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
20 help
21 Support for the digital TV receiver chip made by B2C2 Inc. included in
22 Technisats PCI cards and USB boxes.
23
24 Say Y if you own such a device and want to use it.
25
26config DVB_B2C2_FLEXCOP_DEBUG
27 bool "Enable debug for the B2C2 FlexCop drivers"
28 depends on DVB_B2C2_FLEXCOP
29 help
30 Say Y if you want to enable the module option to control debug messages
31 of all B2C2 FlexCop drivers.
diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
new file mode 100644
index 00000000000..377d051548a
--- /dev/null
+++ b/drivers/media/common/b2c2/Makefile
@@ -0,0 +1,7 @@
1b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
2 flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
3obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
4
5ccflags-y += -Idrivers/media/dvb-core/
6ccflags-y += -Idrivers/media/dvb-frontends/
7ccflags-y += -Idrivers/media/common/tuners/
diff --git a/drivers/media/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h
new file mode 100644
index 00000000000..437912e4982
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-common.h
@@ -0,0 +1,185 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-common.h - common header file for device-specific source files
4 * see flexcop.c for copyright information
5 */
6#ifndef __FLEXCOP_COMMON_H__
7#define __FLEXCOP_COMMON_H__
8
9#include <linux/interrupt.h>
10#include <linux/pci.h>
11#include <linux/mutex.h>
12
13#include "flexcop-reg.h"
14
15#include "dmxdev.h"
16#include "dvb_demux.h"
17#include "dvb_filter.h"
18#include "dvb_net.h"
19#include "dvb_frontend.h"
20
21#define FC_MAX_FEED 256
22
23#ifndef FC_LOG_PREFIX
24#warning please define a log prefix for your file, using a default one
25#define FC_LOG_PREFIX "b2c2-undef"
26#endif
27
28/* Steal from usb.h */
29#undef err
30#define err(format, arg...) \
31 printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
32#undef info
33#define info(format, arg...) \
34 printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
35#undef warn
36#define warn(format, arg...) \
37 printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
38
39struct flexcop_dma {
40 struct pci_dev *pdev;
41
42 u8 *cpu_addr0;
43 dma_addr_t dma_addr0;
44 u8 *cpu_addr1;
45 dma_addr_t dma_addr1;
46 u32 size; /* size of each address in bytes */
47};
48
49struct flexcop_i2c_adapter {
50 struct flexcop_device *fc;
51 struct i2c_adapter i2c_adap;
52
53 u8 no_base_addr;
54 flexcop_i2c_port_t port;
55};
56
57/* Control structure for data definitions that are common to
58 * the B2C2-based PCI and USB devices.
59 */
60struct flexcop_device {
61 /* general */
62 struct device *dev; /* for firmware_class */
63
64#define FC_STATE_DVB_INIT 0x01
65#define FC_STATE_I2C_INIT 0x02
66#define FC_STATE_FE_INIT 0x04
67 int init_state;
68
69 /* device information */
70 int has_32_hw_pid_filter;
71 flexcop_revision_t rev;
72 flexcop_device_type_t dev_type;
73 flexcop_bus_t bus_type;
74
75 /* dvb stuff */
76 struct dvb_adapter dvb_adapter;
77 struct dvb_frontend *fe;
78 struct dvb_net dvbnet;
79 struct dvb_demux demux;
80 struct dmxdev dmxdev;
81 struct dmx_frontend hw_frontend;
82 struct dmx_frontend mem_frontend;
83 int (*fe_sleep) (struct dvb_frontend *);
84
85 struct flexcop_i2c_adapter fc_i2c_adap[3];
86 struct mutex i2c_mutex;
87 struct module *owner;
88
89 /* options and status */
90 int extra_feedcount;
91 int feedcount;
92 int pid_filtering;
93 int fullts_streaming_state;
94
95 /* bus specific callbacks */
96 flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
97 flexcop_ibi_register);
98 int (*write_ibi_reg) (struct flexcop_device *,
99 flexcop_ibi_register, flexcop_ibi_value);
100 int (*i2c_request) (struct flexcop_i2c_adapter *,
101 flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
102 int (*stream_control) (struct flexcop_device *, int);
103 int (*get_mac_addr) (struct flexcop_device *fc, int extended);
104 void *bus_specific;
105};
106
107/* exported prototypes */
108
109/* from flexcop.c */
110void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
111void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
112
113struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
114void flexcop_device_kfree(struct flexcop_device *);
115
116int flexcop_device_initialize(struct flexcop_device *);
117void flexcop_device_exit(struct flexcop_device *fc);
118void flexcop_reset_block_300(struct flexcop_device *fc);
119
120/* from flexcop-dma.c */
121int flexcop_dma_allocate(struct pci_dev *pdev,
122 struct flexcop_dma *dma, u32 size);
123void flexcop_dma_free(struct flexcop_dma *dma);
124
125int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
126 flexcop_dma_index_t no, int onoff);
127int flexcop_dma_control_size_irq(struct flexcop_device *fc,
128 flexcop_dma_index_t no, int onoff);
129int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
130 flexcop_dma_index_t dma_idx);
131int flexcop_dma_xfer_control(struct flexcop_device *fc,
132 flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
133 int onoff);
134int flexcop_dma_config_timer(struct flexcop_device *fc,
135 flexcop_dma_index_t dma_idx, u8 cycles);
136
137/* from flexcop-eeprom.c */
138/* the PCI part uses this call to get the MAC address, the USB part has its own */
139int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended);
140
141/* from flexcop-i2c.c */
142/* the PCI part uses this a i2c_request callback, whereas the usb part has its own
143 * one. We have it in flexcop-i2c.c, because it is going via the actual
144 * I2C-channel of the flexcop.
145 */
146int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
147 u8 chipaddr, u8 addr, u8 *buf, u16 len);
148
149/* from flexcop-sram.c */
150int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
151 flexcop_sram_dest_target_t target);
152void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
153void flexcop_sram_ctrl(struct flexcop_device *fc,
154 int usb_wan, int sramdma, int maximumfill);
155
156/* global prototypes for the flexcop-chip */
157/* from flexcop-fe-tuner.c */
158int flexcop_frontend_init(struct flexcop_device *fc);
159void flexcop_frontend_exit(struct flexcop_device *fc);
160
161/* from flexcop-i2c.c */
162int flexcop_i2c_init(struct flexcop_device *fc);
163void flexcop_i2c_exit(struct flexcop_device *fc);
164
165/* from flexcop-sram.c */
166int flexcop_sram_init(struct flexcop_device *fc);
167
168/* from flexcop-misc.c */
169void flexcop_determine_revision(struct flexcop_device *fc);
170void flexcop_device_name(struct flexcop_device *fc,
171 const char *prefix, const char *suffix);
172void flexcop_dump_reg(struct flexcop_device *fc,
173 flexcop_ibi_register reg, int num);
174
175/* from flexcop-hw-filter.c */
176int flexcop_pid_feed_control(struct flexcop_device *fc,
177 struct dvb_demux_feed *dvbdmxfeed, int onoff);
178void flexcop_hw_filter_init(struct flexcop_device *fc);
179
180void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
181
182void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]);
183void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff);
184
185#endif
diff --git a/drivers/media/common/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c
new file mode 100644
index 00000000000..a25373a9bd8
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-eeprom.c
@@ -0,0 +1,147 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8#if 0
9/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
10static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
11{
12 return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
13}
14
15static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
16 u32 len, u8 *wbuf, u8 *rbuf, int retries)
17{
18int i;
19
20for (i = 0; i < retries; i++) {
21 if (eeprom_write(adapter, addr, wbuf, len) == len) {
22 if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
23 return 1;
24 }
25 }
26 return 0;
27}
28
29/* These functions could be used to unlock SkyStar2 cards. */
30
31static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
32{
33 u8 rbuf[20];
34 u8 wbuf[20];
35
36 if (len != 16)
37 return 0;
38
39 memcpy(wbuf, key, len);
40 wbuf[16] = 0;
41 wbuf[17] = 0;
42 wbuf[18] = 0;
43 wbuf[19] = calc_lrc(wbuf, 19);
44 return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
45}
46
47static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
48{
49 u8 buf[20];
50
51 if (len != 16)
52 return 0;
53
54 if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
55 return 0;
56
57 memcpy(key, buf, len);
58 return 1;
59}
60
61static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
62{
63 u8 tmp[8];
64
65 if (type != 0) {
66 tmp[0] = mac[0];
67 tmp[1] = mac[1];
68 tmp[2] = mac[2];
69 tmp[3] = mac[5];
70 tmp[4] = mac[6];
71 tmp[5] = mac[7];
72 } else {
73 tmp[0] = mac[0];
74 tmp[1] = mac[1];
75 tmp[2] = mac[2];
76 tmp[3] = mac[3];
77 tmp[4] = mac[4];
78 tmp[5] = mac[5];
79 }
80
81 tmp[6] = 0;
82 tmp[7] = calc_lrc(tmp, 7);
83
84 if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
85 return 1;
86 return 0;
87}
88
89static int flexcop_eeprom_read(struct flexcop_device *fc,
90 u16 addr, u8 *buf, u16 len)
91{
92 return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
93}
94
95#endif
96
97static u8 calc_lrc(u8 *buf, int len)
98{
99 int i;
100 u8 sum = 0;
101 for (i = 0; i < len; i++)
102 sum = sum ^ buf[i];
103 return sum;
104}
105
106static int flexcop_eeprom_request(struct flexcop_device *fc,
107 flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
108{
109 int i,ret = 0;
110 u8 chipaddr = 0x50 | ((addr >> 8) & 3);
111 for (i = 0; i < retries; i++) {
112 ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr,
113 addr & 0xff, buf, len);
114 if (ret == 0)
115 break;
116 }
117 return ret;
118}
119
120static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
121 u8 *buf, u16 len, int retries)
122{
123 int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
124 if (ret == 0)
125 if (calc_lrc(buf, len - 1) != buf[len - 1])
126 ret = -EINVAL;
127 return ret;
128}
129
130/* JJ's comment about extended == 1: it is not presently used anywhere but was
131 * added to the low-level functions for possible support of EUI64 */
132int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
133{
134 u8 buf[8];
135 int ret = 0;
136
137 if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
138 if (extended != 0) {
139 err("TODO: extended (EUI64) MAC addresses aren't "
140 "completely supported yet");
141 ret = -EINVAL;
142 } else
143 memcpy(fc->dvb_adapter.proposed_mac,buf,6);
144 }
145 return ret;
146}
147EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
new file mode 100644
index 00000000000..850a6c60675
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
@@ -0,0 +1,678 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
4 * see flexcop.c for copyright information
5 */
6#include <media/tuner.h>
7#include "flexcop.h"
8#include "mt312.h"
9#include "stv0299.h"
10#include "s5h1420.h"
11#include "itd1000.h"
12#include "cx24113.h"
13#include "cx24123.h"
14#include "isl6421.h"
15#include "mt352.h"
16#include "bcm3510.h"
17#include "nxt200x.h"
18#include "dvb-pll.h"
19#include "lgdt330x.h"
20#include "tuner-simple.h"
21#include "stv0297.h"
22
23
24/* Can we use the specified front-end? Remember that if we are compiled
25 * into the kernel we can't call code that's in modules. */
26#define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \
27 (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE)))
28
29/* lnb control */
30#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
31static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
32{
33 struct flexcop_device *fc = fe->dvb->priv;
34 flexcop_ibi_value v;
35 deb_tuner("polarity/voltage = %u\n", voltage);
36
37 v = fc->read_ibi_reg(fc, misc_204);
38 switch (voltage) {
39 case SEC_VOLTAGE_OFF:
40 v.misc_204.ACPI1_sig = 1;
41 break;
42 case SEC_VOLTAGE_13:
43 v.misc_204.ACPI1_sig = 0;
44 v.misc_204.LNB_L_H_sig = 0;
45 break;
46 case SEC_VOLTAGE_18:
47 v.misc_204.ACPI1_sig = 0;
48 v.misc_204.LNB_L_H_sig = 1;
49 break;
50 default:
51 err("unknown SEC_VOLTAGE value");
52 return -EINVAL;
53 }
54 return fc->write_ibi_reg(fc, misc_204, v);
55}
56#endif
57
58#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
59static int flexcop_sleep(struct dvb_frontend* fe)
60{
61 struct flexcop_device *fc = fe->dvb->priv;
62 if (fc->fe_sleep)
63 return fc->fe_sleep(fe);
64 return 0;
65}
66#endif
67
68/* SkyStar2 DVB-S rev 2.3 */
69#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
70static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
71{
72/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
73 struct flexcop_device *fc = fe->dvb->priv;
74 flexcop_ibi_value v;
75 u16 ax;
76 v.raw = 0;
77 deb_tuner("tone = %u\n",tone);
78
79 switch (tone) {
80 case SEC_TONE_ON:
81 ax = 0x01ff;
82 break;
83 case SEC_TONE_OFF:
84 ax = 0;
85 break;
86 default:
87 err("unknown SEC_TONE value");
88 return -EINVAL;
89 }
90
91 v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
92 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
93 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
94 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
95}
96
97static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
98{
99 flexcop_set_tone(fe, SEC_TONE_ON);
100 udelay(data ? 500 : 1000);
101 flexcop_set_tone(fe, SEC_TONE_OFF);
102 udelay(data ? 1000 : 500);
103}
104
105static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
106{
107 int i, par = 1, d;
108 for (i = 7; i >= 0; i--) {
109 d = (data >> i) & 1;
110 par ^= d;
111 flexcop_diseqc_send_bit(fe, d);
112 }
113 flexcop_diseqc_send_bit(fe, par);
114}
115
116static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
117 int len, u8 *msg, unsigned long burst)
118{
119 int i;
120
121 flexcop_set_tone(fe, SEC_TONE_OFF);
122 mdelay(16);
123
124 for (i = 0; i < len; i++)
125 flexcop_diseqc_send_byte(fe,msg[i]);
126 mdelay(16);
127
128 if (burst != -1) {
129 if (burst)
130 flexcop_diseqc_send_byte(fe, 0xff);
131 else {
132 flexcop_set_tone(fe, SEC_TONE_ON);
133 mdelay(12);
134 udelay(500);
135 flexcop_set_tone(fe, SEC_TONE_OFF);
136 }
137 msleep(20);
138 }
139 return 0;
140}
141
142static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
143 struct dvb_diseqc_master_cmd *cmd)
144{
145 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
146}
147
148static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
149 fe_sec_mini_cmd_t minicmd)
150{
151 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
152}
153
154static struct mt312_config skystar23_samsung_tbdu18132_config = {
155 .demod_address = 0x0e,
156};
157
158static int skystar2_rev23_attach(struct flexcop_device *fc,
159 struct i2c_adapter *i2c)
160{
161 struct dvb_frontend_ops *ops;
162
163 fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
164 if (!fc->fe)
165 return 0;
166
167 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
168 DVB_PLL_SAMSUNG_TBDU18132))
169 return 0;
170
171 ops = &fc->fe->ops;
172 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
173 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
174 ops->set_tone = flexcop_set_tone;
175 ops->set_voltage = flexcop_set_voltage;
176 fc->fe_sleep = ops->sleep;
177 ops->sleep = flexcop_sleep;
178 return 1;
179}
180#else
181#define skystar2_rev23_attach NULL
182#endif
183
184/* SkyStar2 DVB-S rev 2.6 */
185#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
186static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
187 u32 srate, u32 ratio)
188{
189 u8 aclk = 0;
190 u8 bclk = 0;
191
192 if (srate < 1500000) {
193 aclk = 0xb7; bclk = 0x47;
194 } else if (srate < 3000000) {
195 aclk = 0xb7; bclk = 0x4b;
196 } else if (srate < 7000000) {
197 aclk = 0xb7; bclk = 0x4f;
198 } else if (srate < 14000000) {
199 aclk = 0xb7; bclk = 0x53;
200 } else if (srate < 30000000) {
201 aclk = 0xb6; bclk = 0x53;
202 } else if (srate < 45000000) {
203 aclk = 0xb4; bclk = 0x51;
204 }
205
206 stv0299_writereg(fe, 0x13, aclk);
207 stv0299_writereg(fe, 0x14, bclk);
208 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
209 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
210 stv0299_writereg(fe, 0x21, ratio & 0xf0);
211 return 0;
212}
213
214static u8 samsung_tbmu24112_inittab[] = {
215 0x01, 0x15,
216 0x02, 0x30,
217 0x03, 0x00,
218 0x04, 0x7D,
219 0x05, 0x35,
220 0x06, 0x02,
221 0x07, 0x00,
222 0x08, 0xC3,
223 0x0C, 0x00,
224 0x0D, 0x81,
225 0x0E, 0x23,
226 0x0F, 0x12,
227 0x10, 0x7E,
228 0x11, 0x84,
229 0x12, 0xB9,
230 0x13, 0x88,
231 0x14, 0x89,
232 0x15, 0xC9,
233 0x16, 0x00,
234 0x17, 0x5C,
235 0x18, 0x00,
236 0x19, 0x00,
237 0x1A, 0x00,
238 0x1C, 0x00,
239 0x1D, 0x00,
240 0x1E, 0x00,
241 0x1F, 0x3A,
242 0x20, 0x2E,
243 0x21, 0x80,
244 0x22, 0xFF,
245 0x23, 0xC1,
246 0x28, 0x00,
247 0x29, 0x1E,
248 0x2A, 0x14,
249 0x2B, 0x0F,
250 0x2C, 0x09,
251 0x2D, 0x05,
252 0x31, 0x1F,
253 0x32, 0x19,
254 0x33, 0xFE,
255 0x34, 0x93,
256 0xff, 0xff,
257};
258
259static struct stv0299_config samsung_tbmu24112_config = {
260 .demod_address = 0x68,
261 .inittab = samsung_tbmu24112_inittab,
262 .mclk = 88000000UL,
263 .invert = 0,
264 .skip_reinit = 0,
265 .lock_output = STV0299_LOCKOUTPUT_LK,
266 .volt13_op0_op1 = STV0299_VOLT13_OP1,
267 .min_delay_ms = 100,
268 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
269};
270
271static int skystar2_rev26_attach(struct flexcop_device *fc,
272 struct i2c_adapter *i2c)
273{
274 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
275 if (!fc->fe)
276 return 0;
277
278 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
279 DVB_PLL_SAMSUNG_TBMU24112))
280 return 0;
281
282 fc->fe->ops.set_voltage = flexcop_set_voltage;
283 fc->fe_sleep = fc->fe->ops.sleep;
284 fc->fe->ops.sleep = flexcop_sleep;
285 return 1;
286
287}
288#else
289#define skystar2_rev26_attach NULL
290#endif
291
292/* SkyStar2 DVB-S rev 2.7 */
293#if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000)
294static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
295 .demod_address = 0x53,
296 .invert = 1,
297 .repeated_start_workaround = 1,
298 .serial_mpeg = 1,
299};
300
301static struct itd1000_config skystar2_rev2_7_itd1000_config = {
302 .i2c_address = 0x61,
303};
304
305static int skystar2_rev27_attach(struct flexcop_device *fc,
306 struct i2c_adapter *i2c)
307{
308 flexcop_ibi_value r108;
309 struct i2c_adapter *i2c_tuner;
310
311 /* enable no_base_addr - no repeated start when reading */
312 fc->fc_i2c_adap[0].no_base_addr = 1;
313 fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
314 i2c);
315 if (!fc->fe)
316 goto fail;
317
318 i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
319 if (!i2c_tuner)
320 goto fail;
321
322 fc->fe_sleep = fc->fe->ops.sleep;
323 fc->fe->ops.sleep = flexcop_sleep;
324
325 /* enable no_base_addr - no repeated start when reading */
326 fc->fc_i2c_adap[2].no_base_addr = 1;
327 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
328 0x08, 1, 1)) {
329 err("ISL6421 could NOT be attached");
330 goto fail_isl;
331 }
332 info("ISL6421 successfully attached");
333
334 /* the ITD1000 requires a lower i2c clock - is it a problem ? */
335 r108.raw = 0x00000506;
336 fc->write_ibi_reg(fc, tw_sm_c_108, r108);
337 if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
338 &skystar2_rev2_7_itd1000_config)) {
339 err("ITD1000 could NOT be attached");
340 /* Should i2c clock be restored? */
341 goto fail_isl;
342 }
343 info("ITD1000 successfully attached");
344
345 return 1;
346
347fail_isl:
348 fc->fc_i2c_adap[2].no_base_addr = 0;
349fail:
350 /* for the next devices we need it again */
351 fc->fc_i2c_adap[0].no_base_addr = 0;
352 return 0;
353}
354#else
355#define skystar2_rev27_attach NULL
356#endif
357
358/* SkyStar2 rev 2.8 */
359#if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113)
360static struct cx24123_config skystar2_rev2_8_cx24123_config = {
361 .demod_address = 0x55,
362 .dont_use_pll = 1,
363 .agc_callback = cx24113_agc_callback,
364};
365
366static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
367 .i2c_addr = 0x54,
368 .xtal_khz = 10111,
369};
370
371static int skystar2_rev28_attach(struct flexcop_device *fc,
372 struct i2c_adapter *i2c)
373{
374 struct i2c_adapter *i2c_tuner;
375
376 fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
377 i2c);
378 if (!fc->fe)
379 return 0;
380
381 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
382 if (!i2c_tuner)
383 return 0;
384
385 if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
386 i2c_tuner)) {
387 err("CX24113 could NOT be attached");
388 return 0;
389 }
390 info("CX24113 successfully attached");
391
392 fc->fc_i2c_adap[2].no_base_addr = 1;
393 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
394 0x08, 0, 0)) {
395 err("ISL6421 could NOT be attached");
396 fc->fc_i2c_adap[2].no_base_addr = 0;
397 return 0;
398 }
399 info("ISL6421 successfully attached");
400 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
401 * IR-receiver (PIC16F818) - but the card has no input for that ??? */
402 return 1;
403}
404#else
405#define skystar2_rev28_attach NULL
406#endif
407
408/* AirStar DVB-T */
409#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
410static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
411{
412 static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
413 static u8 mt352_reset[] = { 0x50, 0x80 };
414 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
415 static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
416 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
417
418 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
419 udelay(2000);
420 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
421 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
422 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
423 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
424 return 0;
425}
426
427static struct mt352_config samsung_tdtc9251dh0_config = {
428 .demod_address = 0x0f,
429 .demod_init = samsung_tdtc9251dh0_demod_init,
430};
431
432static int airstar_dvbt_attach(struct flexcop_device *fc,
433 struct i2c_adapter *i2c)
434{
435 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
436 if (!fc->fe)
437 return 0;
438
439 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
440 DVB_PLL_SAMSUNG_TDTC9251DH0);
441}
442#else
443#define airstar_dvbt_attach NULL
444#endif
445
446/* AirStar ATSC 1st generation */
447#if FE_SUPPORTED(BCM3510)
448static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
449 const struct firmware **fw, char* name)
450{
451 struct flexcop_device *fc = fe->dvb->priv;
452 return request_firmware(fw, name, fc->dev);
453}
454
455static struct bcm3510_config air2pc_atsc_first_gen_config = {
456 .demod_address = 0x0f,
457 .request_firmware = flexcop_fe_request_firmware,
458};
459
460static int airstar_atsc1_attach(struct flexcop_device *fc,
461 struct i2c_adapter *i2c)
462{
463 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
464 return fc->fe != NULL;
465}
466#else
467#define airstar_atsc1_attach NULL
468#endif
469
470/* AirStar ATSC 2nd generation */
471#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
472static struct nxt200x_config samsung_tbmv_config = {
473 .demod_address = 0x0a,
474};
475
476static int airstar_atsc2_attach(struct flexcop_device *fc,
477 struct i2c_adapter *i2c)
478{
479 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
480 if (!fc->fe)
481 return 0;
482
483 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
484 DVB_PLL_SAMSUNG_TBMV);
485}
486#else
487#define airstar_atsc2_attach NULL
488#endif
489
490/* AirStar ATSC 3rd generation */
491#if FE_SUPPORTED(LGDT330X)
492static struct lgdt330x_config air2pc_atsc_hd5000_config = {
493 .demod_address = 0x59,
494 .demod_chip = LGDT3303,
495 .serial_mpeg = 0x04,
496 .clock_polarity_flip = 1,
497};
498
499static int airstar_atsc3_attach(struct flexcop_device *fc,
500 struct i2c_adapter *i2c)
501{
502 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
503 if (!fc->fe)
504 return 0;
505
506 return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
507 TUNER_LG_TDVS_H06XF);
508}
509#else
510#define airstar_atsc3_attach NULL
511#endif
512
513/* CableStar2 DVB-C */
514#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
515static u8 alps_tdee4_stv0297_inittab[] = {
516 0x80, 0x01,
517 0x80, 0x00,
518 0x81, 0x01,
519 0x81, 0x00,
520 0x00, 0x48,
521 0x01, 0x58,
522 0x03, 0x00,
523 0x04, 0x00,
524 0x07, 0x00,
525 0x08, 0x00,
526 0x30, 0xff,
527 0x31, 0x9d,
528 0x32, 0xff,
529 0x33, 0x00,
530 0x34, 0x29,
531 0x35, 0x55,
532 0x36, 0x80,
533 0x37, 0x6e,
534 0x38, 0x9c,
535 0x40, 0x1a,
536 0x41, 0xfe,
537 0x42, 0x33,
538 0x43, 0x00,
539 0x44, 0xff,
540 0x45, 0x00,
541 0x46, 0x00,
542 0x49, 0x04,
543 0x4a, 0x51,
544 0x4b, 0xf8,
545 0x52, 0x30,
546 0x53, 0x06,
547 0x59, 0x06,
548 0x5a, 0x5e,
549 0x5b, 0x04,
550 0x61, 0x49,
551 0x62, 0x0a,
552 0x70, 0xff,
553 0x71, 0x04,
554 0x72, 0x00,
555 0x73, 0x00,
556 0x74, 0x0c,
557 0x80, 0x20,
558 0x81, 0x00,
559 0x82, 0x30,
560 0x83, 0x00,
561 0x84, 0x04,
562 0x85, 0x22,
563 0x86, 0x08,
564 0x87, 0x1b,
565 0x88, 0x00,
566 0x89, 0x00,
567 0x90, 0x00,
568 0x91, 0x04,
569 0xa0, 0x86,
570 0xa1, 0x00,
571 0xa2, 0x00,
572 0xb0, 0x91,
573 0xb1, 0x0b,
574 0xc0, 0x5b,
575 0xc1, 0x10,
576 0xc2, 0x12,
577 0xd0, 0x02,
578 0xd1, 0x00,
579 0xd2, 0x00,
580 0xd3, 0x00,
581 0xd4, 0x02,
582 0xd5, 0x00,
583 0xde, 0x00,
584 0xdf, 0x01,
585 0xff, 0xff,
586};
587
588static struct stv0297_config alps_tdee4_stv0297_config = {
589 .demod_address = 0x1c,
590 .inittab = alps_tdee4_stv0297_inittab,
591};
592
593static int cablestar2_attach(struct flexcop_device *fc,
594 struct i2c_adapter *i2c)
595{
596 fc->fc_i2c_adap[0].no_base_addr = 1;
597 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
598 if (!fc->fe)
599 goto fail;
600
601 /* This tuner doesn't use the stv0297's I2C gate, but instead the
602 * tuner is connected to a different flexcop I2C adapter. */
603 if (fc->fe->ops.i2c_gate_ctrl)
604 fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
605 fc->fe->ops.i2c_gate_ctrl = NULL;
606
607 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
608 &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
609 goto fail;
610
611 return 1;
612
613fail:
614 /* Reset for next frontend to try */
615 fc->fc_i2c_adap[0].no_base_addr = 0;
616 return 0;
617}
618#else
619#define cablestar2_attach NULL
620#endif
621
622static struct {
623 flexcop_device_type_t type;
624 int (*attach)(struct flexcop_device *, struct i2c_adapter *);
625} flexcop_frontends[] = {
626 { FC_SKY_REV27, skystar2_rev27_attach },
627 { FC_SKY_REV28, skystar2_rev28_attach },
628 { FC_SKY_REV26, skystar2_rev26_attach },
629 { FC_AIR_DVBT, airstar_dvbt_attach },
630 { FC_AIR_ATSC2, airstar_atsc2_attach },
631 { FC_AIR_ATSC3, airstar_atsc3_attach },
632 { FC_AIR_ATSC1, airstar_atsc1_attach },
633 { FC_CABLE, cablestar2_attach },
634 { FC_SKY_REV23, skystar2_rev23_attach },
635};
636
637/* try to figure out the frontend */
638int flexcop_frontend_init(struct flexcop_device *fc)
639{
640 int i;
641 for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
642 if (!flexcop_frontends[i].attach)
643 continue;
644 /* type needs to be set before, because of some workarounds
645 * done based on the probed card type */
646 fc->dev_type = flexcop_frontends[i].type;
647 if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
648 goto fe_found;
649 /* Clean up partially attached frontend */
650 if (fc->fe) {
651 dvb_frontend_detach(fc->fe);
652 fc->fe = NULL;
653 }
654 }
655 fc->dev_type = FC_UNK;
656 err("no frontend driver found for this B2C2/FlexCop adapter");
657 return -ENODEV;
658
659fe_found:
660 info("found '%s' .", fc->fe->ops.info.name);
661 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
662 err("frontend registration failed!");
663 dvb_frontend_detach(fc->fe);
664 fc->fe = NULL;
665 return -EINVAL;
666 }
667 fc->init_state |= FC_STATE_FE_INIT;
668 return 0;
669}
670
671void flexcop_frontend_exit(struct flexcop_device *fc)
672{
673 if (fc->init_state & FC_STATE_FE_INIT) {
674 dvb_unregister_frontend(fc->fe);
675 dvb_frontend_detach(fc->fe);
676 }
677 fc->init_state &= ~FC_STATE_FE_INIT;
678}
diff --git a/drivers/media/common/b2c2/flexcop-hw-filter.c b/drivers/media/common/b2c2/flexcop-hw-filter.c
new file mode 100644
index 00000000000..77e45475f4c
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-hw-filter.c
@@ -0,0 +1,232 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-hw-filter.c - pid and mac address filtering and control functions
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
9{
10 flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
11 deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
12}
13
14void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
15{
16 flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
17}
18
19static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
20{
21 flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
22}
23
24void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
25{
26 flexcop_ibi_value v418, v41c;
27 v41c = fc->read_ibi_reg(fc, mac_address_41c);
28
29 v418.mac_address_418.MAC1 = mac[0];
30 v418.mac_address_418.MAC2 = mac[1];
31 v418.mac_address_418.MAC3 = mac[2];
32 v418.mac_address_418.MAC6 = mac[3];
33 v41c.mac_address_41c.MAC7 = mac[4];
34 v41c.mac_address_41c.MAC8 = mac[5];
35
36 fc->write_ibi_reg(fc, mac_address_418, v418);
37 fc->write_ibi_reg(fc, mac_address_41c, v41c);
38}
39
40void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
41{
42 flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
43}
44
45static void flexcop_pid_group_filter(struct flexcop_device *fc,
46 u16 pid, u16 mask)
47{
48 /* index_reg_310.extra_index_reg need to 0 or 7 to work */
49 flexcop_ibi_value v30c;
50 v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
51 v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
52 fc->write_ibi_reg(fc, pid_filter_30c, v30c);
53}
54
55static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
56{
57 flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
58}
59
60/* this fancy define reduces the code size of the quite similar PID controlling of
61 * the first 6 PIDs
62 */
63
64#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
65 flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
66v208 = fc->read_ibi_reg(fc, ctrl_208); \
67vpid.vregname.field = onoff ? pid : 0x1fff; \
68vpid.vregname.trans_field = transval; \
69v208.ctrl_208.enablefield = onoff; \
70fc->write_ibi_reg(fc, vregname, vpid); \
71fc->write_ibi_reg(fc, ctrl_208, v208);
72
73static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
74 u16 pid, int onoff)
75{
76 pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
77 Stream1_trans, 0);
78}
79
80static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
81 u16 pid, int onoff)
82{
83 pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
84 Stream2_trans, 0);
85}
86
87static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
88 u16 pid, int onoff)
89{
90 pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
91}
92
93static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
94 u16 pid, int onoff)
95{
96 pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
97}
98
99static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
100 u16 pid, int onoff)
101{
102 pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
103}
104
105static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
106 u16 pid, int onoff)
107{
108 pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
109}
110
111static void flexcop_pid_control(struct flexcop_device *fc,
112 int index, u16 pid, int onoff)
113{
114 if (pid == 0x2000)
115 return;
116
117 deb_ts("setting pid: %5d %04x at index %d '%s'\n",
118 pid, pid, index, onoff ? "on" : "off");
119
120 /* We could use bit magic here to reduce source code size.
121 * I decided against it, but to use the real register names */
122 switch (index) {
123 case 0:
124 flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
125 break;
126 case 1:
127 flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
128 break;
129 case 2:
130 flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
131 break;
132 case 3:
133 flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
134 break;
135 case 4:
136 flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
137 break;
138 case 5:
139 flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
140 break;
141 default:
142 if (fc->has_32_hw_pid_filter && index < 38) {
143 flexcop_ibi_value vpid, vid;
144
145 /* set the index */
146 vid = fc->read_ibi_reg(fc, index_reg_310);
147 vid.index_reg_310.index_reg = index - 6;
148 fc->write_ibi_reg(fc, index_reg_310, vid);
149
150 vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
151 vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
152 vpid.pid_n_reg_314.PID_enable_bit = onoff;
153 fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
154 }
155 break;
156 }
157}
158
159static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
160{
161 if (fc->fullts_streaming_state != onoff) {
162 deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
163 flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
164 flexcop_pid_group_filter_ctrl(fc, onoff);
165 fc->fullts_streaming_state = onoff;
166 }
167 return 0;
168}
169
170int flexcop_pid_feed_control(struct flexcop_device *fc,
171 struct dvb_demux_feed *dvbdmxfeed, int onoff)
172{
173 int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
174
175 fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
176 if (dvbdmxfeed->index >= max_pid_filter)
177 fc->extra_feedcount += onoff ? 1 : -1;
178
179 /* toggle complete-TS-streaming when:
180 * - pid_filtering is not enabled and it is the first or last feed requested
181 * - pid_filtering is enabled,
182 * - but the number of requested feeds is exceeded
183 * - or the requested pid is 0x2000 */
184
185 if (!fc->pid_filtering && fc->feedcount == onoff)
186 flexcop_toggle_fullts_streaming(fc, onoff);
187
188 if (fc->pid_filtering) {
189 flexcop_pid_control \
190 (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
191
192 if (fc->extra_feedcount > 0)
193 flexcop_toggle_fullts_streaming(fc, 1);
194 else if (dvbdmxfeed->pid == 0x2000)
195 flexcop_toggle_fullts_streaming(fc, onoff);
196 else
197 flexcop_toggle_fullts_streaming(fc, 0);
198 }
199
200 /* if it was the first or last feed request change the stream-status */
201 if (fc->feedcount == onoff) {
202 flexcop_rcv_data_ctrl(fc, onoff);
203 if (fc->stream_control) /* device specific stream control */
204 fc->stream_control(fc, onoff);
205
206 /* feeding stopped -> reset the flexcop filter*/
207 if (onoff == 0) {
208 flexcop_reset_block_300(fc);
209 flexcop_hw_filter_init(fc);
210 }
211 }
212 return 0;
213}
214EXPORT_SYMBOL(flexcop_pid_feed_control);
215
216void flexcop_hw_filter_init(struct flexcop_device *fc)
217{
218 int i;
219 flexcop_ibi_value v;
220 for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
221 flexcop_pid_control(fc, i, 0x1fff, 0);
222
223 flexcop_pid_group_filter(fc, 0, 0x1fe0);
224 flexcop_pid_group_filter_ctrl(fc, 0);
225
226 v = fc->read_ibi_reg(fc, pid_filter_308);
227 v.pid_filter_308.EMM_filter_4 = 1;
228 v.pid_filter_308.EMM_filter_6 = 0;
229 fc->write_ibi_reg(fc, pid_filter_308, v);
230
231 flexcop_null_filter_ctrl(fc, 1);
232}
diff --git a/drivers/media/common/b2c2/flexcop-i2c.c b/drivers/media/common/b2c2/flexcop-i2c.c
new file mode 100644
index 00000000000..965d5eb3375
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-i2c.c
@@ -0,0 +1,288 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8#define FC_MAX_I2C_RETRIES 100000
9
10static int flexcop_i2c_operation(struct flexcop_device *fc,
11 flexcop_ibi_value *r100)
12{
13 int i;
14 flexcop_ibi_value r;
15
16 r100->tw_sm_c_100.working_start = 1;
17 deb_i2c("r100 before: %08x\n",r100->raw);
18
19 fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero);
20 fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */
21
22 for (i = 0; i < FC_MAX_I2C_RETRIES; i++) {
23 r = fc->read_ibi_reg(fc, tw_sm_c_100);
24
25 if (!r.tw_sm_c_100.no_base_addr_ack_error) {
26 if (r.tw_sm_c_100.st_done) {
27 *r100 = r;
28 deb_i2c("i2c success\n");
29 return 0;
30 }
31 } else {
32 deb_i2c("suffering from an i2c ack_error\n");
33 return -EREMOTEIO;
34 }
35 }
36 deb_i2c("tried %d times i2c operation, "
37 "never finished or too many ack errors.\n", i);
38 return -EREMOTEIO;
39}
40
41static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
42 flexcop_ibi_value r100, u8 *buf)
43{
44 flexcop_ibi_value r104;
45 int len = r100.tw_sm_c_100.total_bytes,
46 /* remember total_bytes is buflen-1 */
47 ret;
48
49 /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
50 * correctly:
51 *
52 * the ITD1000 is behind an i2c-gate which closes automatically
53 * after an i2c-transaction the STV0297 needs 2 consecutive reads
54 * one with no_base_addr = 0 and one with 1
55 *
56 * those two work-arounds are conflictin: we check for the card
57 * type, it is set when probing the ITD1000 */
58 if (i2c->fc->dev_type == FC_SKY_REV27)
59 r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
60
61 ret = flexcop_i2c_operation(i2c->fc, &r100);
62 if (ret != 0) {
63 deb_i2c("Retrying operation\n");
64 r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
65 ret = flexcop_i2c_operation(i2c->fc, &r100);
66 }
67 if (ret != 0) {
68 deb_i2c("read failed. %d\n", ret);
69 return ret;
70 }
71
72 buf[0] = r100.tw_sm_c_100.data1_reg;
73
74 if (len > 0) {
75 r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104);
76 deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
77
78 /* there is at least one more byte, otherwise we wouldn't be here */
79 buf[1] = r104.tw_sm_c_104.data2_reg;
80 if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
81 if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
82 }
83 return 0;
84}
85
86static int flexcop_i2c_write4(struct flexcop_device *fc,
87 flexcop_ibi_value r100, u8 *buf)
88{
89 flexcop_ibi_value r104;
90 int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
91 r104.raw = 0;
92
93 /* there is at least one byte, otherwise we wouldn't be here */
94 r100.tw_sm_c_100.data1_reg = buf[0];
95 r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
96 r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
97 r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
98
99 deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
100
101 /* write the additional i2c data before doing the actual i2c operation */
102 fc->write_ibi_reg(fc, tw_sm_c_104, r104);
103 return flexcop_i2c_operation(fc, &r100);
104}
105
106int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
107 flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
108{
109 int ret;
110
111#ifdef DUMP_I2C_MESSAGES
112 int i;
113#endif
114
115 u16 bytes_to_transfer;
116 flexcop_ibi_value r100;
117
118 deb_i2c("op = %d\n",op);
119 r100.raw = 0;
120 r100.tw_sm_c_100.chipaddr = chipaddr;
121 r100.tw_sm_c_100.twoWS_rw = op;
122 r100.tw_sm_c_100.twoWS_port_reg = i2c->port;
123
124#ifdef DUMP_I2C_MESSAGES
125 printk(KERN_DEBUG "%d ", i2c->port);
126 if (op == FC_READ)
127 printk("rd(");
128 else
129 printk("wr(");
130 printk("%02x): %02x ", chipaddr, addr);
131#endif
132
133 /* in that case addr is the only value ->
134 * we write it twice as baseaddr and val0
135 * BBTI is doing it like that for ISL6421 at least */
136 if (i2c->no_base_addr && len == 0 && op == FC_WRITE) {
137 buf = &addr;
138 len = 1;
139 }
140
141 while (len != 0) {
142 bytes_to_transfer = len > 4 ? 4 : len;
143
144 r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1;
145 r100.tw_sm_c_100.baseaddr = addr;
146
147 if (op == FC_READ)
148 ret = flexcop_i2c_read4(i2c, r100, buf);
149 else
150 ret = flexcop_i2c_write4(i2c->fc, r100, buf);
151
152#ifdef DUMP_I2C_MESSAGES
153 for (i = 0; i < bytes_to_transfer; i++)
154 printk("%02x ", buf[i]);
155#endif
156
157 if (ret < 0)
158 return ret;
159
160 buf += bytes_to_transfer;
161 addr += bytes_to_transfer;
162 len -= bytes_to_transfer;
163 }
164
165#ifdef DUMP_I2C_MESSAGES
166 printk("\n");
167#endif
168
169 return 0;
170}
171/* exported for PCI i2c */
172EXPORT_SYMBOL(flexcop_i2c_request);
173
174/* master xfer callback for demodulator */
175static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
176 struct i2c_msg msgs[], int num)
177{
178 struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
179 int i, ret = 0;
180
181 /* Some drivers use 1 byte or 0 byte reads as probes, which this
182 * driver doesn't support. These probes will always fail, so this
183 * hack makes them always succeed. If one knew how, it would of
184 * course be better to actually do the read. */
185 if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1)
186 return 1;
187
188 if (mutex_lock_interruptible(&i2c->fc->i2c_mutex))
189 return -ERESTARTSYS;
190
191 for (i = 0; i < num; i++) {
192 /* reading */
193 if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
194 ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
195 msgs[i].buf[0], msgs[i+1].buf,
196 msgs[i+1].len);
197 i++; /* skip the following message */
198 } else /* writing */
199 ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
200 msgs[i].buf[0], &msgs[i].buf[1],
201 msgs[i].len - 1);
202 if (ret < 0) {
203 deb_i2c("i2c master_xfer failed");
204 break;
205 }
206 }
207
208 mutex_unlock(&i2c->fc->i2c_mutex);
209
210 if (ret == 0)
211 ret = num;
212 return ret;
213}
214
215static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
216{
217 return I2C_FUNC_I2C;
218}
219
220static struct i2c_algorithm flexcop_algo = {
221 .master_xfer = flexcop_master_xfer,
222 .functionality = flexcop_i2c_func,
223};
224
225int flexcop_i2c_init(struct flexcop_device *fc)
226{
227 int ret;
228 mutex_init(&fc->i2c_mutex);
229
230 fc->fc_i2c_adap[0].fc = fc;
231 fc->fc_i2c_adap[1].fc = fc;
232 fc->fc_i2c_adap[2].fc = fc;
233 fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
234 fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
235 fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
236
237 strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
238 sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
239 strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
240 sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
241 strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
242 sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
243
244 i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
245 i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
246 i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
247
248 fc->fc_i2c_adap[0].i2c_adap.algo =
249 fc->fc_i2c_adap[1].i2c_adap.algo =
250 fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;
251 fc->fc_i2c_adap[0].i2c_adap.algo_data =
252 fc->fc_i2c_adap[1].i2c_adap.algo_data =
253 fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL;
254 fc->fc_i2c_adap[0].i2c_adap.dev.parent =
255 fc->fc_i2c_adap[1].i2c_adap.dev.parent =
256 fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev;
257
258 ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap);
259 if (ret < 0)
260 return ret;
261
262 ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
263 if (ret < 0)
264 goto adap_1_failed;
265
266 ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap);
267 if (ret < 0)
268 goto adap_2_failed;
269
270 fc->init_state |= FC_STATE_I2C_INIT;
271 return 0;
272
273adap_2_failed:
274 i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
275adap_1_failed:
276 i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
277 return ret;
278}
279
280void flexcop_i2c_exit(struct flexcop_device *fc)
281{
282 if (fc->init_state & FC_STATE_I2C_INIT) {
283 i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap);
284 i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
285 i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
286 }
287 fc->init_state &= ~FC_STATE_I2C_INIT;
288}
diff --git a/drivers/media/common/b2c2/flexcop-misc.c b/drivers/media/common/b2c2/flexcop-misc.c
new file mode 100644
index 00000000000..f06f3a9070f
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-misc.c
@@ -0,0 +1,86 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-misc.c - miscellaneous functions
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8void flexcop_determine_revision(struct flexcop_device *fc)
9{
10 flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
11
12 switch (v.misc_204.Rev_N_sig_revision_hi) {
13 case 0x2:
14 deb_info("found a FlexCopII.\n");
15 fc->rev = FLEXCOP_II;
16 break;
17 case 0x3:
18 deb_info("found a FlexCopIIb.\n");
19 fc->rev = FLEXCOP_IIB;
20 break;
21 case 0x0:
22 deb_info("found a FlexCopIII.\n");
23 fc->rev = FLEXCOP_III;
24 break;
25 default:
26 err("unknown FlexCop Revision: %x. Please report this to "
27 "linux-dvb@linuxtv.org.",
28 v.misc_204.Rev_N_sig_revision_hi);
29 break;
30 }
31
32 if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
33 deb_info("this FlexCop has "
34 "the additional 32 hardware pid filter.\n");
35 else
36 deb_info("this FlexCop has "
37 "the 6 basic main hardware pid filter.\n");
38 /* bus parts have to decide if hw pid filtering is used or not. */
39}
40
41static const char *flexcop_revision_names[] = {
42 "Unknown chip",
43 "FlexCopII",
44 "FlexCopIIb",
45 "FlexCopIII",
46};
47
48static const char *flexcop_device_names[] = {
49 [FC_UNK] = "Unknown device",
50 [FC_CABLE] = "Cable2PC/CableStar 2 DVB-C",
51 [FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T",
52 [FC_AIR_ATSC1] = "Air2PC/AirStar 2 ATSC 1st generation",
53 [FC_AIR_ATSC2] = "Air2PC/AirStar 2 ATSC 2nd generation",
54 [FC_AIR_ATSC3] = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
55 [FC_SKY_REV23] = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)",
56 [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6",
57 [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
58 [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8",
59};
60
61static const char *flexcop_bus_names[] = {
62 "USB",
63 "PCI",
64};
65
66void flexcop_device_name(struct flexcop_device *fc,
67 const char *prefix, const char *suffix)
68{
69 info("%s '%s' at the '%s' bus controlled by a '%s' %s",
70 prefix, flexcop_device_names[fc->dev_type],
71 flexcop_bus_names[fc->bus_type],
72 flexcop_revision_names[fc->rev], suffix);
73}
74
75void flexcop_dump_reg(struct flexcop_device *fc,
76 flexcop_ibi_register reg, int num)
77{
78 flexcop_ibi_value v;
79 int i;
80 for (i = 0; i < num; i++) {
81 v = fc->read_ibi_reg(fc, reg+4*i);
82 deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
83 }
84 deb_rdump("\n");
85}
86EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/common/b2c2/flexcop-reg.h b/drivers/media/common/b2c2/flexcop-reg.h
new file mode 100644
index 00000000000..dc4528dcbb9
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-reg.h
@@ -0,0 +1,166 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
4 * see flexcop.c for copyright information
5 */
6#ifndef __FLEXCOP_REG_H__
7#define __FLEXCOP_REG_H__
8
9typedef enum {
10 FLEXCOP_UNK = 0,
11 FLEXCOP_II,
12 FLEXCOP_IIB,
13 FLEXCOP_III,
14} flexcop_revision_t;
15
16typedef enum {
17 FC_UNK = 0,
18 FC_CABLE,
19 FC_AIR_DVBT,
20 FC_AIR_ATSC1,
21 FC_AIR_ATSC2,
22 FC_AIR_ATSC3,
23 FC_SKY_REV23,
24 FC_SKY_REV26,
25 FC_SKY_REV27,
26 FC_SKY_REV28,
27} flexcop_device_type_t;
28
29typedef enum {
30 FC_USB = 0,
31 FC_PCI,
32} flexcop_bus_t;
33
34/* FlexCop IBI Registers */
35#if defined(__LITTLE_ENDIAN)
36#include "flexcop_ibi_value_le.h"
37#else
38#if defined(__BIG_ENDIAN)
39#include "flexcop_ibi_value_be.h"
40#else
41#error no endian defined
42#endif
43#endif
44
45#define fc_data_Tag_ID_DVB 0x3e
46#define fc_data_Tag_ID_ATSC 0x3f
47#define fc_data_Tag_ID_IDSB 0x8b
48
49#define fc_key_code_default 0x1
50#define fc_key_code_even 0x2
51#define fc_key_code_odd 0x3
52
53extern flexcop_ibi_value ibi_zero;
54
55typedef enum {
56 FC_I2C_PORT_DEMOD = 1,
57 FC_I2C_PORT_EEPROM = 2,
58 FC_I2C_PORT_TUNER = 3,
59} flexcop_i2c_port_t;
60
61typedef enum {
62 FC_WRITE = 0,
63 FC_READ = 1,
64} flexcop_access_op_t;
65
66typedef enum {
67 FC_SRAM_DEST_NET = 1,
68 FC_SRAM_DEST_CAI = 2,
69 FC_SRAM_DEST_CAO = 4,
70 FC_SRAM_DEST_MEDIA = 8
71} flexcop_sram_dest_t;
72
73typedef enum {
74 FC_SRAM_DEST_TARGET_WAN_USB = 0,
75 FC_SRAM_DEST_TARGET_DMA1 = 1,
76 FC_SRAM_DEST_TARGET_DMA2 = 2,
77 FC_SRAM_DEST_TARGET_FC3_CA = 3
78} flexcop_sram_dest_target_t;
79
80typedef enum {
81 FC_SRAM_2_32KB = 0, /* 64KB */
82 FC_SRAM_1_32KB = 1, /* 32KB - default fow FCII */
83 FC_SRAM_1_128KB = 2, /* 128KB */
84 FC_SRAM_1_48KB = 3, /* 48KB - default for FCIII */
85} flexcop_sram_type_t;
86
87typedef enum {
88 FC_WAN_SPEED_4MBITS = 0,
89 FC_WAN_SPEED_8MBITS = 1,
90 FC_WAN_SPEED_12MBITS = 2,
91 FC_WAN_SPEED_16MBITS = 3,
92} flexcop_wan_speed_t;
93
94typedef enum {
95 FC_DMA_1 = 1,
96 FC_DMA_2 = 2,
97} flexcop_dma_index_t;
98
99typedef enum {
100 FC_DMA_SUBADDR_0 = 1,
101 FC_DMA_SUBADDR_1 = 2,
102} flexcop_dma_addr_index_t;
103
104/* names of the particular registers */
105typedef enum {
106 dma1_000 = 0x000,
107 dma1_004 = 0x004,
108 dma1_008 = 0x008,
109 dma1_00c = 0x00c,
110 dma2_010 = 0x010,
111 dma2_014 = 0x014,
112 dma2_018 = 0x018,
113 dma2_01c = 0x01c,
114
115 tw_sm_c_100 = 0x100,
116 tw_sm_c_104 = 0x104,
117 tw_sm_c_108 = 0x108,
118 tw_sm_c_10c = 0x10c,
119 tw_sm_c_110 = 0x110,
120
121 lnb_switch_freq_200 = 0x200,
122 misc_204 = 0x204,
123 ctrl_208 = 0x208,
124 irq_20c = 0x20c,
125 sw_reset_210 = 0x210,
126 misc_214 = 0x214,
127 mbox_v8_to_host_218 = 0x218,
128 mbox_host_to_v8_21c = 0x21c,
129
130 pid_filter_300 = 0x300,
131 pid_filter_304 = 0x304,
132 pid_filter_308 = 0x308,
133 pid_filter_30c = 0x30c,
134 index_reg_310 = 0x310,
135 pid_n_reg_314 = 0x314,
136 mac_low_reg_318 = 0x318,
137 mac_high_reg_31c = 0x31c,
138
139 data_tag_400 = 0x400,
140 card_id_408 = 0x408,
141 card_id_40c = 0x40c,
142 mac_address_418 = 0x418,
143 mac_address_41c = 0x41c,
144
145 ci_600 = 0x600,
146 pi_604 = 0x604,
147 pi_608 = 0x608,
148 dvb_reg_60c = 0x60c,
149
150 sram_ctrl_reg_700 = 0x700,
151 net_buf_reg_704 = 0x704,
152 cai_buf_reg_708 = 0x708,
153 cao_buf_reg_70c = 0x70c,
154 media_buf_reg_710 = 0x710,
155 sram_dest_reg_714 = 0x714,
156 net_buf_reg_718 = 0x718,
157 wan_ctrl_reg_71c = 0x71c,
158} flexcop_ibi_register;
159
160#define flexcop_set_ibi_value(reg,attr,val) { \
161 flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \
162 v.reg.attr = val; \
163 fc->write_ibi_reg(fc,reg,v); \
164}
165
166#endif
diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
new file mode 100644
index 00000000000..f2199e43e80
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop-sram.c
@@ -0,0 +1,363 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-sram.c - functions for controlling the SRAM
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8static void flexcop_sram_set_chip(struct flexcop_device *fc,
9 flexcop_sram_type_t type)
10{
11 flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
12}
13
14int flexcop_sram_init(struct flexcop_device *fc)
15{
16 switch (fc->rev) {
17 case FLEXCOP_II:
18 case FLEXCOP_IIB:
19 flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
20 break;
21 case FLEXCOP_III:
22 flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
23 break;
24 default:
25 return -EINVAL;
26 }
27 return 0;
28}
29
30int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
31 flexcop_sram_dest_target_t target)
32{
33 flexcop_ibi_value v;
34 v = fc->read_ibi_reg(fc, sram_dest_reg_714);
35
36 if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
37 err("SRAM destination target to available on FlexCopII(b)\n");
38 return -EINVAL;
39 }
40 deb_sram("sram dest: %x target: %x\n", dest, target);
41
42 if (dest & FC_SRAM_DEST_NET)
43 v.sram_dest_reg_714.NET_Dest = target;
44 if (dest & FC_SRAM_DEST_CAI)
45 v.sram_dest_reg_714.CAI_Dest = target;
46 if (dest & FC_SRAM_DEST_CAO)
47 v.sram_dest_reg_714.CAO_Dest = target;
48 if (dest & FC_SRAM_DEST_MEDIA)
49 v.sram_dest_reg_714.MEDIA_Dest = target;
50
51 fc->write_ibi_reg(fc,sram_dest_reg_714,v);
52 udelay(1000); /* TODO delay really necessary */
53
54 return 0;
55}
56EXPORT_SYMBOL(flexcop_sram_set_dest);
57
58void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
59{
60 flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
61}
62EXPORT_SYMBOL(flexcop_wan_set_speed);
63
64void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
65{
66 flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
67 v.sram_dest_reg_714.ctrl_usb_wan = usb_wan;
68 v.sram_dest_reg_714.ctrl_sramdma = sramdma;
69 v.sram_dest_reg_714.ctrl_maximumfill = maximumfill;
70 fc->write_ibi_reg(fc,sram_dest_reg_714,v);
71}
72EXPORT_SYMBOL(flexcop_sram_ctrl);
73
74#if 0
75static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
76{
77 int i, retries;
78 u32 command;
79
80 for (i = 0; i < len; i++) {
81 command = bank | addr | 0x04000000 | (*buf << 0x10);
82
83 retries = 2;
84
85 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
86 mdelay(1);
87 retries--;
88 };
89
90 if (retries == 0)
91 printk("%s: SRAM timeout\n", __func__);
92
93 write_reg_dw(adapter, 0x700, command);
94
95 buf++;
96 addr++;
97 }
98}
99
100static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
101{
102 int i, retries;
103 u32 command, value;
104
105 for (i = 0; i < len; i++) {
106 command = bank | addr | 0x04008000;
107
108 retries = 10000;
109
110 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
111 mdelay(1);
112 retries--;
113 };
114
115 if (retries == 0)
116 printk("%s: SRAM timeout\n", __func__);
117
118 write_reg_dw(adapter, 0x700, command);
119
120 retries = 10000;
121
122 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
123 mdelay(1);
124 retries--;
125 };
126
127 if (retries == 0)
128 printk("%s: SRAM timeout\n", __func__);
129
130 value = read_reg_dw(adapter, 0x700) >> 0x10;
131
132 *buf = (value & 0xff);
133
134 addr++;
135 buf++;
136 }
137}
138
139static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
140{
141 u32 bank;
142
143 bank = 0;
144
145 if (adapter->dw_sram_type == 0x20000) {
146 bank = (addr & 0x18000) << 0x0d;
147 }
148
149 if (adapter->dw_sram_type == 0x00000) {
150 if ((addr >> 0x0f) == 0)
151 bank = 0x20000000;
152 else
153 bank = 0x10000000;
154 }
155 flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
156}
157
158static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
159{
160 u32 bank;
161 bank = 0;
162
163 if (adapter->dw_sram_type == 0x20000) {
164 bank = (addr & 0x18000) << 0x0d;
165 }
166
167 if (adapter->dw_sram_type == 0x00000) {
168 if ((addr >> 0x0f) == 0)
169 bank = 0x20000000;
170 else
171 bank = 0x10000000;
172 }
173 flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
174}
175
176static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
177{
178 u32 length;
179 while (len != 0) {
180 length = len;
181 /* check if the address range belongs to the same
182 * 32K memory chip. If not, the data is read
183 * from one chip at a time */
184 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
185 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
186 }
187
188 sram_read_chunk(adapter, addr, buf, length);
189 addr = addr + length;
190 buf = buf + length;
191 len = len - length;
192 }
193}
194
195static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
196{
197 u32 length;
198 while (len != 0) {
199 length = len;
200
201 /* check if the address range belongs to the same
202 * 32K memory chip. If not, the data is
203 * written to one chip at a time */
204 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
205 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
206 }
207
208 sram_write_chunk(adapter, addr, buf, length);
209 addr = addr + length;
210 buf = buf + length;
211 len = len - length;
212 }
213}
214
215static void sram_set_size(struct adapter *adapter, u32 mask)
216{
217 write_reg_dw(adapter, 0x71c,
218 (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
219}
220
221static void sram_init(struct adapter *adapter)
222{
223 u32 tmp;
224 tmp = read_reg_dw(adapter, 0x71c);
225 write_reg_dw(adapter, 0x71c, 1);
226
227 if (read_reg_dw(adapter, 0x71c) != 0) {
228 write_reg_dw(adapter, 0x71c, tmp);
229 adapter->dw_sram_type = tmp & 0x30000;
230 ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
231 } else {
232 adapter->dw_sram_type = 0x10000;
233 ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
234 }
235}
236
237static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
238{
239 u8 tmp1, tmp2;
240 dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
241
242 sram_set_size(adapter, mask);
243 sram_init(adapter);
244
245 tmp2 = 0xa5;
246 tmp1 = 0x4f;
247
248 sram_write(adapter, addr, &tmp2, 1);
249 sram_write(adapter, addr + 4, &tmp1, 1);
250
251 tmp2 = 0;
252 mdelay(20);
253
254 sram_read(adapter, addr, &tmp2, 1);
255 sram_read(adapter, addr, &tmp2, 1);
256
257 dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
258
259 if (tmp2 != 0xa5)
260 return 0;
261
262 tmp2 = 0x5a;
263 tmp1 = 0xf4;
264
265 sram_write(adapter, addr, &tmp2, 1);
266 sram_write(adapter, addr + 4, &tmp1, 1);
267
268 tmp2 = 0;
269 mdelay(20);
270
271 sram_read(adapter, addr, &tmp2, 1);
272 sram_read(adapter, addr, &tmp2, 1);
273
274 dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
275
276 if (tmp2 != 0x5a)
277 return 0;
278 return 1;
279}
280
281static u32 sram_length(struct adapter *adapter)
282{
283 if (adapter->dw_sram_type == 0x10000)
284 return 32768; /* 32K */
285 if (adapter->dw_sram_type == 0x00000)
286 return 65536; /* 64K */
287 if (adapter->dw_sram_type == 0x20000)
288 return 131072; /* 128K */
289 return 32768; /* 32K */
290}
291
292/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
293 - for 128K there are 4x32K chips at bank 0,1,2,3.
294 - for 64K there are 2x32K chips at bank 1,2.
295 - for 32K there is one 32K chip at bank 0.
296
297 FlexCop works only with one bank at a time. The bank is selected
298 by bits 28-29 of the 0x700 register.
299
300 bank 0 covers addresses 0x00000-0x07fff
301 bank 1 covers addresses 0x08000-0x0ffff
302 bank 2 covers addresses 0x10000-0x17fff
303 bank 3 covers addresses 0x18000-0x1ffff */
304
305static int flexcop_sram_detect(struct flexcop_device *fc)
306{
307 flexcop_ibi_value r208, r71c_0, vr71c_1;
308 r208 = fc->read_ibi_reg(fc, ctrl_208);
309 fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
310
311 r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
312 write_reg_dw(adapter, 0x71c, 1);
313 tmp3 = read_reg_dw(adapter, 0x71c);
314 dprintk("%s: tmp3 = %x\n", __func__, tmp3);
315 write_reg_dw(adapter, 0x71c, tmp2);
316
317 // check for internal SRAM ???
318 tmp3--;
319 if (tmp3 != 0) {
320 sram_set_size(adapter, 0x10000);
321 sram_init(adapter);
322 write_reg_dw(adapter, 0x208, tmp);
323 dprintk("%s: sram size = 32K\n", __func__);
324 return 32;
325 }
326
327 if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
328 sram_set_size(adapter, 0x20000);
329 sram_init(adapter);
330 write_reg_dw(adapter, 0x208, tmp);
331 dprintk("%s: sram size = 128K\n", __func__);
332 return 128;
333 }
334
335 if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
336 sram_set_size(adapter, 0x00000);
337 sram_init(adapter);
338 write_reg_dw(adapter, 0x208, tmp);
339 dprintk("%s: sram size = 64K\n", __func__);
340 return 64;
341 }
342
343 if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
344 sram_set_size(adapter, 0x10000);
345 sram_init(adapter);
346 write_reg_dw(adapter, 0x208, tmp);
347 dprintk("%s: sram size = 32K\n", __func__);
348 return 32;
349 }
350
351 sram_set_size(adapter, 0x10000);
352 sram_init(adapter);
353 write_reg_dw(adapter, 0x208, tmp);
354 dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
355 return 0;
356}
357
358static void sll_detect_sram_size(struct adapter *adapter)
359{
360 sram_detect_for_flex2(adapter);
361}
362
363#endif
diff --git a/drivers/media/common/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c
new file mode 100644
index 00000000000..b1e8c99f469
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop.c
@@ -0,0 +1,324 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop.c - main module part
4 * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
5 * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
6 *
7 * Acknowledgements:
8 * John Jurrius from BBTI, Inc. for extensive support
9 * with code examples and data books
10 * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
11 *
12 * Contributions to the skystar2-driver have been done by
13 * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
14 * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
15 * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
16 * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
17 * filtering)
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 */
33
34#include "flexcop.h"
35
36#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
37#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
38
39#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
40#define DEBSTATUS ""
41#else
42#define DEBSTATUS " (debugging is not enabled)"
43#endif
44
45int b2c2_flexcop_debug;
46module_param_named(debug, b2c2_flexcop_debug, int, 0644);
47MODULE_PARM_DESC(debug,
48 "set debug level (1=info,2=tuner,4=i2c,8=ts,"
49 "16=sram,32=reg (|-able))."
50 DEBSTATUS);
51#undef DEBSTATUS
52
53DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
54
55/* global zero for ibi values */
56flexcop_ibi_value ibi_zero;
57
58static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
59{
60 struct flexcop_device *fc = dvbdmxfeed->demux->priv;
61 return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
62}
63
64static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
65{
66 struct flexcop_device *fc = dvbdmxfeed->demux->priv;
67 return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
68}
69
70static int flexcop_dvb_init(struct flexcop_device *fc)
71{
72 int ret = dvb_register_adapter(&fc->dvb_adapter,
73 "FlexCop Digital TV device", fc->owner,
74 fc->dev, adapter_nr);
75 if (ret < 0) {
76 err("error registering DVB adapter");
77 return ret;
78 }
79 fc->dvb_adapter.priv = fc;
80
81 fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
82 | DMX_MEMORY_BASED_FILTERING);
83 fc->demux.priv = fc;
84 fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
85 fc->demux.start_feed = flexcop_dvb_start_feed;
86 fc->demux.stop_feed = flexcop_dvb_stop_feed;
87 fc->demux.write_to_decoder = NULL;
88
89 ret = dvb_dmx_init(&fc->demux);
90 if (ret < 0) {
91 err("dvb_dmx failed: error %d", ret);
92 goto err_dmx;
93 }
94
95 fc->hw_frontend.source = DMX_FRONTEND_0;
96
97 fc->dmxdev.filternum = fc->demux.feednum;
98 fc->dmxdev.demux = &fc->demux.dmx;
99 fc->dmxdev.capabilities = 0;
100 ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter);
101 if (ret < 0) {
102 err("dvb_dmxdev_init failed: error %d", ret);
103 goto err_dmx_dev;
104 }
105
106 ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend);
107 if (ret < 0) {
108 err("adding hw_frontend to dmx failed: error %d", ret);
109 goto err_dmx_add_hw_frontend;
110 }
111
112 fc->mem_frontend.source = DMX_MEMORY_FE;
113 ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend);
114 if (ret < 0) {
115 err("adding mem_frontend to dmx failed: error %d", ret);
116 goto err_dmx_add_mem_frontend;
117 }
118
119 ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend);
120 if (ret < 0) {
121 err("connect frontend failed: error %d", ret);
122 goto err_connect_frontend;
123 }
124
125 ret = dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
126 if (ret < 0) {
127 err("dvb_net_init failed: error %d", ret);
128 goto err_net;
129 }
130
131 fc->init_state |= FC_STATE_DVB_INIT;
132 return 0;
133
134err_net:
135 fc->demux.dmx.disconnect_frontend(&fc->demux.dmx);
136err_connect_frontend:
137 fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
138err_dmx_add_mem_frontend:
139 fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
140err_dmx_add_hw_frontend:
141 dvb_dmxdev_release(&fc->dmxdev);
142err_dmx_dev:
143 dvb_dmx_release(&fc->demux);
144err_dmx:
145 dvb_unregister_adapter(&fc->dvb_adapter);
146 return ret;
147}
148
149static void flexcop_dvb_exit(struct flexcop_device *fc)
150{
151 if (fc->init_state & FC_STATE_DVB_INIT) {
152 dvb_net_release(&fc->dvbnet);
153
154 fc->demux.dmx.close(&fc->demux.dmx);
155 fc->demux.dmx.remove_frontend(&fc->demux.dmx,
156 &fc->mem_frontend);
157 fc->demux.dmx.remove_frontend(&fc->demux.dmx,
158 &fc->hw_frontend);
159 dvb_dmxdev_release(&fc->dmxdev);
160 dvb_dmx_release(&fc->demux);
161 dvb_unregister_adapter(&fc->dvb_adapter);
162 deb_info("deinitialized dvb stuff\n");
163 }
164 fc->init_state &= ~FC_STATE_DVB_INIT;
165}
166
167/* these methods are necessary to achieve the long-term-goal of hiding the
168 * struct flexcop_device from the bus-parts */
169void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len)
170{
171 dvb_dmx_swfilter(&fc->demux, buf, len);
172}
173EXPORT_SYMBOL(flexcop_pass_dmx_data);
174
175void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
176{
177 dvb_dmx_swfilter_packets(&fc->demux, buf, no);
178}
179EXPORT_SYMBOL(flexcop_pass_dmx_packets);
180
181static void flexcop_reset(struct flexcop_device *fc)
182{
183 flexcop_ibi_value v210, v204;
184
185 /* reset the flexcop itself */
186 fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
187
188 v210.raw = 0;
189 v210.sw_reset_210.reset_block_000 = 1;
190 v210.sw_reset_210.reset_block_100 = 1;
191 v210.sw_reset_210.reset_block_200 = 1;
192 v210.sw_reset_210.reset_block_300 = 1;
193 v210.sw_reset_210.reset_block_400 = 1;
194 v210.sw_reset_210.reset_block_500 = 1;
195 v210.sw_reset_210.reset_block_600 = 1;
196 v210.sw_reset_210.reset_block_700 = 1;
197 v210.sw_reset_210.Block_reset_enable = 0xb2;
198 v210.sw_reset_210.Special_controls = 0xc259;
199 fc->write_ibi_reg(fc,sw_reset_210,v210);
200 msleep(1);
201
202 /* reset the periphical devices */
203
204 v204 = fc->read_ibi_reg(fc,misc_204);
205 v204.misc_204.Per_reset_sig = 0;
206 fc->write_ibi_reg(fc,misc_204,v204);
207 msleep(1);
208 v204.misc_204.Per_reset_sig = 1;
209 fc->write_ibi_reg(fc,misc_204,v204);
210}
211
212void flexcop_reset_block_300(struct flexcop_device *fc)
213{
214 flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
215 v210 = fc->read_ibi_reg(fc, sw_reset_210);
216
217 deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
218 fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
219
220 v210.sw_reset_210.reset_block_300 = 1;
221 v210.sw_reset_210.Block_reset_enable = 0xb2;
222
223 fc->write_ibi_reg(fc,sw_reset_210,v210);
224 fc->write_ibi_reg(fc,ctrl_208,v208_save);
225}
226
227struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
228{
229 void *bus;
230 struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
231 GFP_KERNEL);
232 if (!fc) {
233 err("no memory");
234 return NULL;
235 }
236
237 bus = kzalloc(bus_specific_len, GFP_KERNEL);
238 if (!bus) {
239 err("no memory");
240 kfree(fc);
241 return NULL;
242 }
243
244 fc->bus_specific = bus;
245
246 return fc;
247}
248EXPORT_SYMBOL(flexcop_device_kmalloc);
249
250void flexcop_device_kfree(struct flexcop_device *fc)
251{
252 kfree(fc->bus_specific);
253 kfree(fc);
254}
255EXPORT_SYMBOL(flexcop_device_kfree);
256
257int flexcop_device_initialize(struct flexcop_device *fc)
258{
259 int ret;
260 ibi_zero.raw = 0;
261
262 flexcop_reset(fc);
263 flexcop_determine_revision(fc);
264 flexcop_sram_init(fc);
265 flexcop_hw_filter_init(fc);
266 flexcop_smc_ctrl(fc, 0);
267
268 ret = flexcop_dvb_init(fc);
269 if (ret)
270 goto error;
271
272 /* i2c has to be done before doing EEProm stuff -
273 * because the EEProm is accessed via i2c */
274 ret = flexcop_i2c_init(fc);
275 if (ret)
276 goto error;
277
278 /* do the MAC address reading after initializing the dvb_adapter */
279 if (fc->get_mac_addr(fc, 0) == 0) {
280 u8 *b = fc->dvb_adapter.proposed_mac;
281 info("MAC address = %pM", b);
282 flexcop_set_mac_filter(fc,b);
283 flexcop_mac_filter_ctrl(fc,1);
284 } else
285 warn("reading of MAC address failed.\n");
286
287 ret = flexcop_frontend_init(fc);
288 if (ret)
289 goto error;
290
291 flexcop_device_name(fc,"initialization of","complete");
292 return 0;
293
294error:
295 flexcop_device_exit(fc);
296 return ret;
297}
298EXPORT_SYMBOL(flexcop_device_initialize);
299
300void flexcop_device_exit(struct flexcop_device *fc)
301{
302 flexcop_frontend_exit(fc);
303 flexcop_i2c_exit(fc);
304 flexcop_dvb_exit(fc);
305}
306EXPORT_SYMBOL(flexcop_device_exit);
307
308static int flexcop_module_init(void)
309{
310 info(DRIVER_NAME " loaded successfully");
311 return 0;
312}
313
314static void flexcop_module_cleanup(void)
315{
316 info(DRIVER_NAME " unloaded successfully");
317}
318
319module_init(flexcop_module_init);
320module_exit(flexcop_module_cleanup);
321
322MODULE_AUTHOR(DRIVER_AUTHOR);
323MODULE_DESCRIPTION(DRIVER_NAME);
324MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/b2c2/flexcop.h b/drivers/media/common/b2c2/flexcop.h
new file mode 100644
index 00000000000..897b10c85ad
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop.h
@@ -0,0 +1,29 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop.h - private header file for all flexcop-chip-source files
4 * see flexcop.c for copyright information
5 */
6#ifndef __FLEXCOP_H__
7#define __FLEXCOP_H___
8
9#define FC_LOG_PREFIX "b2c2-flexcop"
10#include "flexcop-common.h"
11
12extern int b2c2_flexcop_debug;
13
14/* debug */
15#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
16#define dprintk(level,args...) \
17 do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
18#else
19#define dprintk(level,args...)
20#endif
21
22#define deb_info(args...) dprintk(0x01, args)
23#define deb_tuner(args...) dprintk(0x02, args)
24#define deb_i2c(args...) dprintk(0x04, args)
25#define deb_ts(args...) dprintk(0x08, args)
26#define deb_sram(args...) dprintk(0x10, args)
27#define deb_rdump(args...) dprintk(0x20, args)
28
29#endif
diff --git a/drivers/media/common/b2c2/flexcop_ibi_value_be.h b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
new file mode 100644
index 00000000000..8f64bdbd72b
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
@@ -0,0 +1,455 @@
1/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2 * register descriptions
3 * see flexcop.c for copyright information
4 */
5/* This file is automatically generated, do not edit things here. */
6#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
7#define __FLEXCOP_IBI_VALUE_INCLUDED__
8
9typedef union {
10 u32 raw;
11
12 struct {
13 u32 dma_address0 :30;
14 u32 dma_0No_update : 1;
15 u32 dma_0start : 1;
16 } dma_0x0;
17
18 struct {
19 u32 dma_addr_size :24;
20 u32 DMA_maxpackets : 8;
21 } dma_0x4_remap;
22
23 struct {
24 u32 dma_addr_size :24;
25 u32 unused : 1;
26 u32 dma1timer : 7;
27 } dma_0x4_read;
28
29 struct {
30 u32 dma_addr_size :24;
31 u32 dmatimer : 7;
32 u32 unused : 1;
33 } dma_0x4_write;
34
35 struct {
36 u32 dma_cur_addr :30;
37 u32 unused : 2;
38 } dma_0x8;
39
40 struct {
41 u32 dma_address1 :30;
42 u32 remap_enable : 1;
43 u32 dma_1start : 1;
44 } dma_0xc;
45
46 struct {
47 u32 st_done : 1;
48 u32 no_base_addr_ack_error : 1;
49 u32 twoWS_port_reg : 2;
50 u32 total_bytes : 2;
51 u32 twoWS_rw : 1;
52 u32 working_start : 1;
53 u32 data1_reg : 8;
54 u32 baseaddr : 8;
55 u32 reserved1 : 1;
56 u32 chipaddr : 7;
57 } tw_sm_c_100;
58
59 struct {
60 u32 unused : 6;
61 u32 force_stop : 1;
62 u32 exlicit_stops : 1;
63 u32 data4_reg : 8;
64 u32 data3_reg : 8;
65 u32 data2_reg : 8;
66 } tw_sm_c_104;
67
68 struct {
69 u32 reserved2 :19;
70 u32 tlo1 : 5;
71 u32 reserved1 : 2;
72 u32 thi1 : 6;
73 } tw_sm_c_108;
74
75 struct {
76 u32 reserved2 :19;
77 u32 tlo1 : 5;
78 u32 reserved1 : 2;
79 u32 thi1 : 6;
80 } tw_sm_c_10c;
81
82 struct {
83 u32 reserved2 :19;
84 u32 tlo1 : 5;
85 u32 reserved1 : 2;
86 u32 thi1 : 6;
87 } tw_sm_c_110;
88
89 struct {
90 u32 LNB_CTLPrescaler_sig : 2;
91 u32 LNB_CTLLowCount_sig :15;
92 u32 LNB_CTLHighCount_sig :15;
93 } lnb_switch_freq_200;
94
95 struct {
96 u32 Rev_N_sig_reserved2 : 1;
97 u32 Rev_N_sig_caps : 1;
98 u32 Rev_N_sig_reserved1 : 2;
99 u32 Rev_N_sig_revision_hi : 4;
100 u32 reserved :20;
101 u32 Per_reset_sig : 1;
102 u32 LNB_L_H_sig : 1;
103 u32 ACPI3_sig : 1;
104 u32 ACPI1_sig : 1;
105 } misc_204;
106
107 struct {
108 u32 unused : 9;
109 u32 Mailbox_from_V8_Enable_sig : 1;
110 u32 DMA2_Size_IRQ_Enable_sig : 1;
111 u32 DMA1_Size_IRQ_Enable_sig : 1;
112 u32 DMA2_Timer_Enable_sig : 1;
113 u32 DMA2_IRQ_Enable_sig : 1;
114 u32 DMA1_Timer_Enable_sig : 1;
115 u32 DMA1_IRQ_Enable_sig : 1;
116 u32 Rcv_Data_sig : 1;
117 u32 MAC_filter_Mode_sig : 1;
118 u32 Multi2_Enable_sig : 1;
119 u32 Per_CA_Enable_sig : 1;
120 u32 SMC_Enable_sig : 1;
121 u32 CA_Enable_sig : 1;
122 u32 WAN_CA_Enable_sig : 1;
123 u32 WAN_Enable_sig : 1;
124 u32 Mask_filter_sig : 1;
125 u32 Null_filter_sig : 1;
126 u32 ECM_filter_sig : 1;
127 u32 EMM_filter_sig : 1;
128 u32 PMT_filter_sig : 1;
129 u32 PCR_filter_sig : 1;
130 u32 Stream2_filter_sig : 1;
131 u32 Stream1_filter_sig : 1;
132 } ctrl_208;
133
134 struct {
135 u32 reserved :21;
136 u32 Transport_Error : 1;
137 u32 LLC_SNAP_FLAG_set : 1;
138 u32 Continuity_error_flag : 1;
139 u32 Data_receiver_error : 1;
140 u32 Mailbox_from_V8_Status_sig : 1;
141 u32 DMA2_Size_IRQ_Status : 1;
142 u32 DMA1_Size_IRQ_Status : 1;
143 u32 DMA2_Timer_Status : 1;
144 u32 DMA2_IRQ_Status : 1;
145 u32 DMA1_Timer_Status : 1;
146 u32 DMA1_IRQ_Status : 1;
147 } irq_20c;
148
149 struct {
150 u32 Special_controls :16;
151 u32 Block_reset_enable : 8;
152 u32 reset_block_700 : 1;
153 u32 reset_block_600 : 1;
154 u32 reset_block_500 : 1;
155 u32 reset_block_400 : 1;
156 u32 reset_block_300 : 1;
157 u32 reset_block_200 : 1;
158 u32 reset_block_100 : 1;
159 u32 reset_block_000 : 1;
160 } sw_reset_210;
161
162 struct {
163 u32 unused2 :20;
164 u32 polarity_PS_ERR_sig : 1;
165 u32 polarity_PS_SYNC_sig : 1;
166 u32 polarity_PS_VALID_sig : 1;
167 u32 polarity_PS_CLK_sig : 1;
168 u32 unused1 : 3;
169 u32 s2p_sel_sig : 1;
170 u32 section_pkg_enable_sig : 1;
171 u32 halt_V8_sig : 1;
172 u32 v2WS_oe_sig : 1;
173 u32 vuart_oe_sig : 1;
174 } misc_214;
175
176 struct {
177 u32 Mailbox_from_V8 :32;
178 } mbox_v8_to_host_218;
179
180 struct {
181 u32 sysramaccess_busmuster : 1;
182 u32 sysramaccess_write : 1;
183 u32 unused : 7;
184 u32 sysramaccess_addr :15;
185 u32 sysramaccess_data : 8;
186 } mbox_host_to_v8_21c;
187
188 struct {
189 u32 debug_fifo_problem : 1;
190 u32 debug_flag_write_status00 : 1;
191 u32 Stream2_trans : 1;
192 u32 Stream2_PID :13;
193 u32 debug_flag_pid_saved : 1;
194 u32 MAC_Multicast_filter : 1;
195 u32 Stream1_trans : 1;
196 u32 Stream1_PID :13;
197 } pid_filter_300;
198
199 struct {
200 u32 reserved : 2;
201 u32 PMT_trans : 1;
202 u32 PMT_PID :13;
203 u32 debug_overrun2 : 1;
204 u32 debug_overrun3 : 1;
205 u32 PCR_trans : 1;
206 u32 PCR_PID :13;
207 } pid_filter_304;
208
209 struct {
210 u32 reserved : 2;
211 u32 ECM_trans : 1;
212 u32 ECM_PID :13;
213 u32 EMM_filter_6 : 1;
214 u32 EMM_filter_4 : 1;
215 u32 EMM_trans : 1;
216 u32 EMM_PID :13;
217 } pid_filter_308;
218
219 struct {
220 u32 unused2 : 3;
221 u32 Group_mask :13;
222 u32 unused1 : 2;
223 u32 Group_trans : 1;
224 u32 Group_PID :13;
225 } pid_filter_30c_ext_ind_0_7;
226
227 struct {
228 u32 unused :15;
229 u32 net_master_read :17;
230 } pid_filter_30c_ext_ind_1;
231
232 struct {
233 u32 unused :15;
234 u32 net_master_write :17;
235 } pid_filter_30c_ext_ind_2;
236
237 struct {
238 u32 unused :15;
239 u32 next_net_master_write :17;
240 } pid_filter_30c_ext_ind_3;
241
242 struct {
243 u32 reserved2 : 5;
244 u32 stack_read :10;
245 u32 reserved1 : 6;
246 u32 state_write :10;
247 u32 unused1 : 1;
248 } pid_filter_30c_ext_ind_4;
249
250 struct {
251 u32 unused :22;
252 u32 stack_cnt :10;
253 } pid_filter_30c_ext_ind_5;
254
255 struct {
256 u32 unused : 4;
257 u32 data_size_reg :12;
258 u32 write_status4 : 2;
259 u32 write_status1 : 2;
260 u32 pid_fsm_save_reg300 : 2;
261 u32 pid_fsm_save_reg4 : 2;
262 u32 pid_fsm_save_reg3 : 2;
263 u32 pid_fsm_save_reg2 : 2;
264 u32 pid_fsm_save_reg1 : 2;
265 u32 pid_fsm_save_reg0 : 2;
266 } pid_filter_30c_ext_ind_6;
267
268 struct {
269 u32 unused :22;
270 u32 pass_alltables : 1;
271 u32 AB_select : 1;
272 u32 extra_index_reg : 3;
273 u32 index_reg : 5;
274 } index_reg_310;
275
276 struct {
277 u32 reserved :17;
278 u32 PID_enable_bit : 1;
279 u32 PID_trans : 1;
280 u32 PID :13;
281 } pid_n_reg_314;
282
283 struct {
284 u32 reserved : 6;
285 u32 HighAB_bit : 1;
286 u32 Enable_bit : 1;
287 u32 A6_byte : 8;
288 u32 A5_byte : 8;
289 u32 A4_byte : 8;
290 } mac_low_reg_318;
291
292 struct {
293 u32 reserved : 8;
294 u32 A3_byte : 8;
295 u32 A2_byte : 8;
296 u32 A1_byte : 8;
297 } mac_high_reg_31c;
298
299 struct {
300 u32 data_Tag_ID :16;
301 u32 reserved :16;
302 } data_tag_400;
303
304 struct {
305 u32 Card_IDbyte3 : 8;
306 u32 Card_IDbyte4 : 8;
307 u32 Card_IDbyte5 : 8;
308 u32 Card_IDbyte6 : 8;
309 } card_id_408;
310
311 struct {
312 u32 Card_IDbyte1 : 8;
313 u32 Card_IDbyte2 : 8;
314 } card_id_40c;
315
316 struct {
317 u32 MAC6 : 8;
318 u32 MAC3 : 8;
319 u32 MAC2 : 8;
320 u32 MAC1 : 8;
321 } mac_address_418;
322
323 struct {
324 u32 reserved :16;
325 u32 MAC8 : 8;
326 u32 MAC7 : 8;
327 } mac_address_41c;
328
329 struct {
330 u32 reserved :21;
331 u32 txbuffempty : 1;
332 u32 ReceiveByteFrameError : 1;
333 u32 ReceiveDataReady : 1;
334 u32 transmitter_data_byte : 8;
335 } ci_600;
336
337 struct {
338 u32 pi_component_reg : 3;
339 u32 pi_rw : 1;
340 u32 pi_ha :20;
341 u32 pi_d : 8;
342 } pi_604;
343
344 struct {
345 u32 pi_busy_n : 1;
346 u32 pi_wait_n : 1;
347 u32 pi_timeout_status : 1;
348 u32 pi_CiMax_IRQ_n : 1;
349 u32 config_cclk : 1;
350 u32 config_cs_n : 1;
351 u32 config_wr_n : 1;
352 u32 config_Prog_n : 1;
353 u32 config_Init_stat : 1;
354 u32 config_Done_stat : 1;
355 u32 pcmcia_b_mod_pwr_n : 1;
356 u32 pcmcia_a_mod_pwr_n : 1;
357 u32 reserved : 3;
358 u32 Timer_addr : 5;
359 u32 unused : 1;
360 u32 timer_data : 7;
361 u32 Timer_Load_req : 1;
362 u32 Timer_Read_req : 1;
363 u32 oncecycle_read : 1;
364 u32 serialReset : 1;
365 } pi_608;
366
367 struct {
368 u32 reserved : 6;
369 u32 rw_flag : 1;
370 u32 dvb_en : 1;
371 u32 key_array_row : 5;
372 u32 key_array_col : 3;
373 u32 key_code : 2;
374 u32 key_enable : 1;
375 u32 PID :13;
376 } dvb_reg_60c;
377
378 struct {
379 u32 start_sram_ibi : 1;
380 u32 reserved2 : 1;
381 u32 ce_pin_reg : 1;
382 u32 oe_pin_reg : 1;
383 u32 reserved1 : 3;
384 u32 sc_xfer_bit : 1;
385 u32 sram_data : 8;
386 u32 sram_rw : 1;
387 u32 sram_addr :15;
388 } sram_ctrl_reg_700;
389
390 struct {
391 u32 net_addr_write :16;
392 u32 net_addr_read :16;
393 } net_buf_reg_704;
394
395 struct {
396 u32 cai_cnt : 4;
397 u32 reserved2 : 6;
398 u32 cai_write :11;
399 u32 reserved1 : 5;
400 u32 cai_read :11;
401 } cai_buf_reg_708;
402
403 struct {
404 u32 cao_cnt : 4;
405 u32 reserved2 : 6;
406 u32 cap_write :11;
407 u32 reserved1 : 5;
408 u32 cao_read :11;
409 } cao_buf_reg_70c;
410
411 struct {
412 u32 media_cnt : 4;
413 u32 reserved2 : 6;
414 u32 media_write :11;
415 u32 reserved1 : 5;
416 u32 media_read :11;
417 } media_buf_reg_710;
418
419 struct {
420 u32 reserved :17;
421 u32 ctrl_maximumfill : 1;
422 u32 ctrl_sramdma : 1;
423 u32 ctrl_usb_wan : 1;
424 u32 cao_ovflow_error : 1;
425 u32 cai_ovflow_error : 1;
426 u32 media_ovflow_error : 1;
427 u32 net_ovflow_error : 1;
428 u32 MEDIA_Dest : 2;
429 u32 CAO_Dest : 2;
430 u32 CAI_Dest : 2;
431 u32 NET_Dest : 2;
432 } sram_dest_reg_714;
433
434 struct {
435 u32 reserved3 :11;
436 u32 net_addr_write : 1;
437 u32 reserved2 : 3;
438 u32 net_addr_read : 1;
439 u32 reserved1 : 4;
440 u32 net_cnt :12;
441 } net_buf_reg_718;
442
443 struct {
444 u32 reserved3 : 4;
445 u32 wan_pkt_frame : 4;
446 u32 reserved2 : 4;
447 u32 sram_memmap : 2;
448 u32 sram_chip : 2;
449 u32 wan_wait_state : 8;
450 u32 reserved1 : 6;
451 u32 wan_speed_sig : 2;
452 } wan_ctrl_reg_71c;
453} flexcop_ibi_value;
454
455#endif
diff --git a/drivers/media/common/b2c2/flexcop_ibi_value_le.h b/drivers/media/common/b2c2/flexcop_ibi_value_le.h
new file mode 100644
index 00000000000..c75830d7d94
--- /dev/null
+++ b/drivers/media/common/b2c2/flexcop_ibi_value_le.h
@@ -0,0 +1,455 @@
1/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2 * register descriptions
3 * see flexcop.c for copyright information
4 */
5/* This file is automatically generated, do not edit things here. */
6#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
7#define __FLEXCOP_IBI_VALUE_INCLUDED__
8
9typedef union {
10 u32 raw;
11
12 struct {
13 u32 dma_0start : 1;
14 u32 dma_0No_update : 1;
15 u32 dma_address0 :30;
16 } dma_0x0;
17
18 struct {
19 u32 DMA_maxpackets : 8;
20 u32 dma_addr_size :24;
21 } dma_0x4_remap;
22
23 struct {
24 u32 dma1timer : 7;
25 u32 unused : 1;
26 u32 dma_addr_size :24;
27 } dma_0x4_read;
28
29 struct {
30 u32 unused : 1;
31 u32 dmatimer : 7;
32 u32 dma_addr_size :24;
33 } dma_0x4_write;
34
35 struct {
36 u32 unused : 2;
37 u32 dma_cur_addr :30;
38 } dma_0x8;
39
40 struct {
41 u32 dma_1start : 1;
42 u32 remap_enable : 1;
43 u32 dma_address1 :30;
44 } dma_0xc;
45
46 struct {
47 u32 chipaddr : 7;
48 u32 reserved1 : 1;
49 u32 baseaddr : 8;
50 u32 data1_reg : 8;
51 u32 working_start : 1;
52 u32 twoWS_rw : 1;
53 u32 total_bytes : 2;
54 u32 twoWS_port_reg : 2;
55 u32 no_base_addr_ack_error : 1;
56 u32 st_done : 1;
57 } tw_sm_c_100;
58
59 struct {
60 u32 data2_reg : 8;
61 u32 data3_reg : 8;
62 u32 data4_reg : 8;
63 u32 exlicit_stops : 1;
64 u32 force_stop : 1;
65 u32 unused : 6;
66 } tw_sm_c_104;
67
68 struct {
69 u32 thi1 : 6;
70 u32 reserved1 : 2;
71 u32 tlo1 : 5;
72 u32 reserved2 :19;
73 } tw_sm_c_108;
74
75 struct {
76 u32 thi1 : 6;
77 u32 reserved1 : 2;
78 u32 tlo1 : 5;
79 u32 reserved2 :19;
80 } tw_sm_c_10c;
81
82 struct {
83 u32 thi1 : 6;
84 u32 reserved1 : 2;
85 u32 tlo1 : 5;
86 u32 reserved2 :19;
87 } tw_sm_c_110;
88
89 struct {
90 u32 LNB_CTLHighCount_sig :15;
91 u32 LNB_CTLLowCount_sig :15;
92 u32 LNB_CTLPrescaler_sig : 2;
93 } lnb_switch_freq_200;
94
95 struct {
96 u32 ACPI1_sig : 1;
97 u32 ACPI3_sig : 1;
98 u32 LNB_L_H_sig : 1;
99 u32 Per_reset_sig : 1;
100 u32 reserved :20;
101 u32 Rev_N_sig_revision_hi : 4;
102 u32 Rev_N_sig_reserved1 : 2;
103 u32 Rev_N_sig_caps : 1;
104 u32 Rev_N_sig_reserved2 : 1;
105 } misc_204;
106
107 struct {
108 u32 Stream1_filter_sig : 1;
109 u32 Stream2_filter_sig : 1;
110 u32 PCR_filter_sig : 1;
111 u32 PMT_filter_sig : 1;
112 u32 EMM_filter_sig : 1;
113 u32 ECM_filter_sig : 1;
114 u32 Null_filter_sig : 1;
115 u32 Mask_filter_sig : 1;
116 u32 WAN_Enable_sig : 1;
117 u32 WAN_CA_Enable_sig : 1;
118 u32 CA_Enable_sig : 1;
119 u32 SMC_Enable_sig : 1;
120 u32 Per_CA_Enable_sig : 1;
121 u32 Multi2_Enable_sig : 1;
122 u32 MAC_filter_Mode_sig : 1;
123 u32 Rcv_Data_sig : 1;
124 u32 DMA1_IRQ_Enable_sig : 1;
125 u32 DMA1_Timer_Enable_sig : 1;
126 u32 DMA2_IRQ_Enable_sig : 1;
127 u32 DMA2_Timer_Enable_sig : 1;
128 u32 DMA1_Size_IRQ_Enable_sig : 1;
129 u32 DMA2_Size_IRQ_Enable_sig : 1;
130 u32 Mailbox_from_V8_Enable_sig : 1;
131 u32 unused : 9;
132 } ctrl_208;
133
134 struct {
135 u32 DMA1_IRQ_Status : 1;
136 u32 DMA1_Timer_Status : 1;
137 u32 DMA2_IRQ_Status : 1;
138 u32 DMA2_Timer_Status : 1;
139 u32 DMA1_Size_IRQ_Status : 1;
140 u32 DMA2_Size_IRQ_Status : 1;
141 u32 Mailbox_from_V8_Status_sig : 1;
142 u32 Data_receiver_error : 1;
143 u32 Continuity_error_flag : 1;
144 u32 LLC_SNAP_FLAG_set : 1;
145 u32 Transport_Error : 1;
146 u32 reserved :21;
147 } irq_20c;
148
149 struct {
150 u32 reset_block_000 : 1;
151 u32 reset_block_100 : 1;
152 u32 reset_block_200 : 1;
153 u32 reset_block_300 : 1;
154 u32 reset_block_400 : 1;
155 u32 reset_block_500 : 1;
156 u32 reset_block_600 : 1;
157 u32 reset_block_700 : 1;
158 u32 Block_reset_enable : 8;
159 u32 Special_controls :16;
160 } sw_reset_210;
161
162 struct {
163 u32 vuart_oe_sig : 1;
164 u32 v2WS_oe_sig : 1;
165 u32 halt_V8_sig : 1;
166 u32 section_pkg_enable_sig : 1;
167 u32 s2p_sel_sig : 1;
168 u32 unused1 : 3;
169 u32 polarity_PS_CLK_sig : 1;
170 u32 polarity_PS_VALID_sig : 1;
171 u32 polarity_PS_SYNC_sig : 1;
172 u32 polarity_PS_ERR_sig : 1;
173 u32 unused2 :20;
174 } misc_214;
175
176 struct {
177 u32 Mailbox_from_V8 :32;
178 } mbox_v8_to_host_218;
179
180 struct {
181 u32 sysramaccess_data : 8;
182 u32 sysramaccess_addr :15;
183 u32 unused : 7;
184 u32 sysramaccess_write : 1;
185 u32 sysramaccess_busmuster : 1;
186 } mbox_host_to_v8_21c;
187
188 struct {
189 u32 Stream1_PID :13;
190 u32 Stream1_trans : 1;
191 u32 MAC_Multicast_filter : 1;
192 u32 debug_flag_pid_saved : 1;
193 u32 Stream2_PID :13;
194 u32 Stream2_trans : 1;
195 u32 debug_flag_write_status00 : 1;
196 u32 debug_fifo_problem : 1;
197 } pid_filter_300;
198
199 struct {
200 u32 PCR_PID :13;
201 u32 PCR_trans : 1;
202 u32 debug_overrun3 : 1;
203 u32 debug_overrun2 : 1;
204 u32 PMT_PID :13;
205 u32 PMT_trans : 1;
206 u32 reserved : 2;
207 } pid_filter_304;
208
209 struct {
210 u32 EMM_PID :13;
211 u32 EMM_trans : 1;
212 u32 EMM_filter_4 : 1;
213 u32 EMM_filter_6 : 1;
214 u32 ECM_PID :13;
215 u32 ECM_trans : 1;
216 u32 reserved : 2;
217 } pid_filter_308;
218
219 struct {
220 u32 Group_PID :13;
221 u32 Group_trans : 1;
222 u32 unused1 : 2;
223 u32 Group_mask :13;
224 u32 unused2 : 3;
225 } pid_filter_30c_ext_ind_0_7;
226
227 struct {
228 u32 net_master_read :17;
229 u32 unused :15;
230 } pid_filter_30c_ext_ind_1;
231
232 struct {
233 u32 net_master_write :17;
234 u32 unused :15;
235 } pid_filter_30c_ext_ind_2;
236
237 struct {
238 u32 next_net_master_write :17;
239 u32 unused :15;
240 } pid_filter_30c_ext_ind_3;
241
242 struct {
243 u32 unused1 : 1;
244 u32 state_write :10;
245 u32 reserved1 : 6;
246 u32 stack_read :10;
247 u32 reserved2 : 5;
248 } pid_filter_30c_ext_ind_4;
249
250 struct {
251 u32 stack_cnt :10;
252 u32 unused :22;
253 } pid_filter_30c_ext_ind_5;
254
255 struct {
256 u32 pid_fsm_save_reg0 : 2;
257 u32 pid_fsm_save_reg1 : 2;
258 u32 pid_fsm_save_reg2 : 2;
259 u32 pid_fsm_save_reg3 : 2;
260 u32 pid_fsm_save_reg4 : 2;
261 u32 pid_fsm_save_reg300 : 2;
262 u32 write_status1 : 2;
263 u32 write_status4 : 2;
264 u32 data_size_reg :12;
265 u32 unused : 4;
266 } pid_filter_30c_ext_ind_6;
267
268 struct {
269 u32 index_reg : 5;
270 u32 extra_index_reg : 3;
271 u32 AB_select : 1;
272 u32 pass_alltables : 1;
273 u32 unused :22;
274 } index_reg_310;
275
276 struct {
277 u32 PID :13;
278 u32 PID_trans : 1;
279 u32 PID_enable_bit : 1;
280 u32 reserved :17;
281 } pid_n_reg_314;
282
283 struct {
284 u32 A4_byte : 8;
285 u32 A5_byte : 8;
286 u32 A6_byte : 8;
287 u32 Enable_bit : 1;
288 u32 HighAB_bit : 1;
289 u32 reserved : 6;
290 } mac_low_reg_318;
291
292 struct {
293 u32 A1_byte : 8;
294 u32 A2_byte : 8;
295 u32 A3_byte : 8;
296 u32 reserved : 8;
297 } mac_high_reg_31c;
298
299 struct {
300 u32 reserved :16;
301 u32 data_Tag_ID :16;
302 } data_tag_400;
303
304 struct {
305 u32 Card_IDbyte6 : 8;
306 u32 Card_IDbyte5 : 8;
307 u32 Card_IDbyte4 : 8;
308 u32 Card_IDbyte3 : 8;
309 } card_id_408;
310
311 struct {
312 u32 Card_IDbyte2 : 8;
313 u32 Card_IDbyte1 : 8;
314 } card_id_40c;
315
316 struct {
317 u32 MAC1 : 8;
318 u32 MAC2 : 8;
319 u32 MAC3 : 8;
320 u32 MAC6 : 8;
321 } mac_address_418;
322
323 struct {
324 u32 MAC7 : 8;
325 u32 MAC8 : 8;
326 u32 reserved :16;
327 } mac_address_41c;
328
329 struct {
330 u32 transmitter_data_byte : 8;
331 u32 ReceiveDataReady : 1;
332 u32 ReceiveByteFrameError : 1;
333 u32 txbuffempty : 1;
334 u32 reserved :21;
335 } ci_600;
336
337 struct {
338 u32 pi_d : 8;
339 u32 pi_ha :20;
340 u32 pi_rw : 1;
341 u32 pi_component_reg : 3;
342 } pi_604;
343
344 struct {
345 u32 serialReset : 1;
346 u32 oncecycle_read : 1;
347 u32 Timer_Read_req : 1;
348 u32 Timer_Load_req : 1;
349 u32 timer_data : 7;
350 u32 unused : 1;
351 u32 Timer_addr : 5;
352 u32 reserved : 3;
353 u32 pcmcia_a_mod_pwr_n : 1;
354 u32 pcmcia_b_mod_pwr_n : 1;
355 u32 config_Done_stat : 1;
356 u32 config_Init_stat : 1;
357 u32 config_Prog_n : 1;
358 u32 config_wr_n : 1;
359 u32 config_cs_n : 1;
360 u32 config_cclk : 1;
361 u32 pi_CiMax_IRQ_n : 1;
362 u32 pi_timeout_status : 1;
363 u32 pi_wait_n : 1;
364 u32 pi_busy_n : 1;
365 } pi_608;
366
367 struct {
368 u32 PID :13;
369 u32 key_enable : 1;
370 u32 key_code : 2;
371 u32 key_array_col : 3;
372 u32 key_array_row : 5;
373 u32 dvb_en : 1;
374 u32 rw_flag : 1;
375 u32 reserved : 6;
376 } dvb_reg_60c;
377
378 struct {
379 u32 sram_addr :15;
380 u32 sram_rw : 1;
381 u32 sram_data : 8;
382 u32 sc_xfer_bit : 1;
383 u32 reserved1 : 3;
384 u32 oe_pin_reg : 1;
385 u32 ce_pin_reg : 1;
386 u32 reserved2 : 1;
387 u32 start_sram_ibi : 1;
388 } sram_ctrl_reg_700;
389
390 struct {
391 u32 net_addr_read :16;
392 u32 net_addr_write :16;
393 } net_buf_reg_704;
394
395 struct {
396 u32 cai_read :11;
397 u32 reserved1 : 5;
398 u32 cai_write :11;
399 u32 reserved2 : 6;
400 u32 cai_cnt : 4;
401 } cai_buf_reg_708;
402
403 struct {
404 u32 cao_read :11;
405 u32 reserved1 : 5;
406 u32 cap_write :11;
407 u32 reserved2 : 6;
408 u32 cao_cnt : 4;
409 } cao_buf_reg_70c;
410
411 struct {
412 u32 media_read :11;
413 u32 reserved1 : 5;
414 u32 media_write :11;
415 u32 reserved2 : 6;
416 u32 media_cnt : 4;
417 } media_buf_reg_710;
418
419 struct {
420 u32 NET_Dest : 2;
421 u32 CAI_Dest : 2;
422 u32 CAO_Dest : 2;
423 u32 MEDIA_Dest : 2;
424 u32 net_ovflow_error : 1;
425 u32 media_ovflow_error : 1;
426 u32 cai_ovflow_error : 1;
427 u32 cao_ovflow_error : 1;
428 u32 ctrl_usb_wan : 1;
429 u32 ctrl_sramdma : 1;
430 u32 ctrl_maximumfill : 1;
431 u32 reserved :17;
432 } sram_dest_reg_714;
433
434 struct {
435 u32 net_cnt :12;
436 u32 reserved1 : 4;
437 u32 net_addr_read : 1;
438 u32 reserved2 : 3;
439 u32 net_addr_write : 1;
440 u32 reserved3 :11;
441 } net_buf_reg_718;
442
443 struct {
444 u32 wan_speed_sig : 2;
445 u32 reserved1 : 6;
446 u32 wan_wait_state : 8;
447 u32 sram_chip : 2;
448 u32 sram_memmap : 2;
449 u32 reserved2 : 4;
450 u32 wan_pkt_frame : 4;
451 u32 reserved3 : 4;
452 } wan_ctrl_reg_71c;
453} flexcop_ibi_value;
454
455#endif