diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-14 15:35:58 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 22:38:31 -0400 |
commit | 3785bc170f79ef04129731582b468c28e1326d6d (patch) | |
tree | b29b6c6ffc96418f134f4801eb7dcc053d227e56 /drivers/media/common | |
parent | 25aee3debe0464f6c680173041fa3de30ec9ff54 (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/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/common/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/common/b2c2/Kconfig | 31 | ||||
-rw-r--r-- | drivers/media/common/b2c2/Makefile | 7 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-common.h | 185 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-eeprom.c | 147 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-fe-tuner.c | 678 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-hw-filter.c | 232 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-i2c.c | 288 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-misc.c | 86 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-reg.h | 166 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop-sram.c | 363 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop.c | 324 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop.h | 29 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop_ibi_value_be.h | 455 | ||||
-rw-r--r-- | drivers/media/common/b2c2/flexcop_ibi_value_le.h | 455 |
16 files changed, 3449 insertions, 1 deletions
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig index 769c6f8142d2..4672f7d82f67 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 | |||
11 | source "drivers/media/common/b2c2/Kconfig" | ||
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index e3ec9639321b..d0512d7e5555 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | saa7146-objs := saa7146_i2c.o saa7146_core.o | 1 | saa7146-objs := saa7146_i2c.o saa7146_core.o |
2 | saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o | 2 | saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o |
3 | 3 | ||
4 | obj-y += tuners/ | 4 | obj-y += tuners/ b2c2/ |
5 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o | 5 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o |
6 | obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o | 6 | obj-$(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 000000000000..e270dd847342 --- /dev/null +++ b/drivers/media/common/b2c2/Kconfig | |||
@@ -0,0 +1,31 @@ | |||
1 | config 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 | |||
26 | config 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 000000000000..377d051548a9 --- /dev/null +++ b/drivers/media/common/b2c2/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | b2c2-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 | ||
3 | obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o | ||
4 | |||
5 | ccflags-y += -Idrivers/media/dvb-core/ | ||
6 | ccflags-y += -Idrivers/media/dvb-frontends/ | ||
7 | ccflags-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 000000000000..437912e49824 --- /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 | |||
39 | struct 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 | |||
49 | struct 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 | */ | ||
60 | struct 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 */ | ||
110 | void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len); | ||
111 | void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no); | ||
112 | |||
113 | struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len); | ||
114 | void flexcop_device_kfree(struct flexcop_device *); | ||
115 | |||
116 | int flexcop_device_initialize(struct flexcop_device *); | ||
117 | void flexcop_device_exit(struct flexcop_device *fc); | ||
118 | void flexcop_reset_block_300(struct flexcop_device *fc); | ||
119 | |||
120 | /* from flexcop-dma.c */ | ||
121 | int flexcop_dma_allocate(struct pci_dev *pdev, | ||
122 | struct flexcop_dma *dma, u32 size); | ||
123 | void flexcop_dma_free(struct flexcop_dma *dma); | ||
124 | |||
125 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, | ||
126 | flexcop_dma_index_t no, int onoff); | ||
127 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, | ||
128 | flexcop_dma_index_t no, int onoff); | ||
129 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, | ||
130 | flexcop_dma_index_t dma_idx); | ||
131 | int flexcop_dma_xfer_control(struct flexcop_device *fc, | ||
132 | flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, | ||
133 | int onoff); | ||
134 | int 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 */ | ||
139 | int 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 | */ | ||
146 | int 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 */ | ||
150 | int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, | ||
151 | flexcop_sram_dest_target_t target); | ||
152 | void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s); | ||
153 | void 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 */ | ||
158 | int flexcop_frontend_init(struct flexcop_device *fc); | ||
159 | void flexcop_frontend_exit(struct flexcop_device *fc); | ||
160 | |||
161 | /* from flexcop-i2c.c */ | ||
162 | int flexcop_i2c_init(struct flexcop_device *fc); | ||
163 | void flexcop_i2c_exit(struct flexcop_device *fc); | ||
164 | |||
165 | /* from flexcop-sram.c */ | ||
166 | int flexcop_sram_init(struct flexcop_device *fc); | ||
167 | |||
168 | /* from flexcop-misc.c */ | ||
169 | void flexcop_determine_revision(struct flexcop_device *fc); | ||
170 | void flexcop_device_name(struct flexcop_device *fc, | ||
171 | const char *prefix, const char *suffix); | ||
172 | void flexcop_dump_reg(struct flexcop_device *fc, | ||
173 | flexcop_ibi_register reg, int num); | ||
174 | |||
175 | /* from flexcop-hw-filter.c */ | ||
176 | int flexcop_pid_feed_control(struct flexcop_device *fc, | ||
177 | struct dvb_demux_feed *dvbdmxfeed, int onoff); | ||
178 | void flexcop_hw_filter_init(struct flexcop_device *fc); | ||
179 | |||
180 | void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff); | ||
181 | |||
182 | void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]); | ||
183 | void 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 000000000000..a25373a9bd84 --- /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) */ | ||
10 | static 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 | |||
15 | static int eeprom_lrc_write(struct adapter *adapter, u32 addr, | ||
16 | u32 len, u8 *wbuf, u8 *rbuf, int retries) | ||
17 | { | ||
18 | int i; | ||
19 | |||
20 | for (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 | |||
31 | static 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 | |||
47 | static 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 | |||
61 | static 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 | |||
89 | static 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 | |||
97 | static 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 | |||
106 | static 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 | |||
120 | static 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 */ | ||
132 | int 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 | } | ||
147 | EXPORT_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 000000000000..850a6c606750 --- /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) | ||
31 | static 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) | ||
59 | static 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) | ||
70 | static 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 | |||
97 | static 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 | |||
105 | static 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 | |||
116 | static 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 | |||
142 | static 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 | |||
148 | static 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 | |||
154 | static struct mt312_config skystar23_samsung_tbdu18132_config = { | ||
155 | .demod_address = 0x0e, | ||
156 | }; | ||
157 | |||
158 | static 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) | ||
186 | static 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 | |||
214 | static 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 | |||
259 | static 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 | |||
271 | static 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) | ||
294 | static 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 | |||
301 | static struct itd1000_config skystar2_rev2_7_itd1000_config = { | ||
302 | .i2c_address = 0x61, | ||
303 | }; | ||
304 | |||
305 | static 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 | |||
347 | fail_isl: | ||
348 | fc->fc_i2c_adap[2].no_base_addr = 0; | ||
349 | fail: | ||
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) | ||
360 | static 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 | |||
366 | static const struct cx24113_config skystar2_rev2_8_cx24113_config = { | ||
367 | .i2c_addr = 0x54, | ||
368 | .xtal_khz = 10111, | ||
369 | }; | ||
370 | |||
371 | static 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) | ||
410 | static 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 | |||
427 | static struct mt352_config samsung_tdtc9251dh0_config = { | ||
428 | .demod_address = 0x0f, | ||
429 | .demod_init = samsung_tdtc9251dh0_demod_init, | ||
430 | }; | ||
431 | |||
432 | static 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) | ||
448 | static 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 | |||
455 | static struct bcm3510_config air2pc_atsc_first_gen_config = { | ||
456 | .demod_address = 0x0f, | ||
457 | .request_firmware = flexcop_fe_request_firmware, | ||
458 | }; | ||
459 | |||
460 | static 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) | ||
472 | static struct nxt200x_config samsung_tbmv_config = { | ||
473 | .demod_address = 0x0a, | ||
474 | }; | ||
475 | |||
476 | static 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) | ||
492 | static 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 | |||
499 | static 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) | ||
515 | static 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 | |||
588 | static struct stv0297_config alps_tdee4_stv0297_config = { | ||
589 | .demod_address = 0x1c, | ||
590 | .inittab = alps_tdee4_stv0297_inittab, | ||
591 | }; | ||
592 | |||
593 | static 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 | |||
613 | fail: | ||
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 | |||
622 | static 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 */ | ||
638 | int 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 | |||
659 | fe_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 | |||
671 | void 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 000000000000..77e45475f4c7 --- /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 | |||
8 | static 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 | |||
14 | void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) | ||
15 | { | ||
16 | flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff); | ||
17 | } | ||
18 | |||
19 | static 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 | |||
24 | void 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 | |||
40 | void 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 | |||
45 | static 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 | |||
55 | static 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), \ | ||
66 | v208 = fc->read_ibi_reg(fc, ctrl_208); \ | ||
67 | vpid.vregname.field = onoff ? pid : 0x1fff; \ | ||
68 | vpid.vregname.trans_field = transval; \ | ||
69 | v208.ctrl_208.enablefield = onoff; \ | ||
70 | fc->write_ibi_reg(fc, vregname, vpid); \ | ||
71 | fc->write_ibi_reg(fc, ctrl_208, v208); | ||
72 | |||
73 | static 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 | |||
80 | static 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 | |||
87 | static 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 | |||
93 | static 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 | |||
99 | static 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 | |||
105 | static 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 | |||
111 | static 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 | |||
159 | static 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 | |||
170 | int 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 | } | ||
214 | EXPORT_SYMBOL(flexcop_pid_feed_control); | ||
215 | |||
216 | void 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 000000000000..965d5eb33752 --- /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 | |||
10 | static 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 | |||
41 | static 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 | |||
86 | static 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 | |||
106 | int 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 */ | ||
172 | EXPORT_SYMBOL(flexcop_i2c_request); | ||
173 | |||
174 | /* master xfer callback for demodulator */ | ||
175 | static 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 | |||
215 | static u32 flexcop_i2c_func(struct i2c_adapter *adapter) | ||
216 | { | ||
217 | return I2C_FUNC_I2C; | ||
218 | } | ||
219 | |||
220 | static struct i2c_algorithm flexcop_algo = { | ||
221 | .master_xfer = flexcop_master_xfer, | ||
222 | .functionality = flexcop_i2c_func, | ||
223 | }; | ||
224 | |||
225 | int 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 | |||
273 | adap_2_failed: | ||
274 | i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); | ||
275 | adap_1_failed: | ||
276 | i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | void 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 000000000000..f06f3a9070f5 --- /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 | |||
8 | void 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 | |||
41 | static const char *flexcop_revision_names[] = { | ||
42 | "Unknown chip", | ||
43 | "FlexCopII", | ||
44 | "FlexCopIIb", | ||
45 | "FlexCopIII", | ||
46 | }; | ||
47 | |||
48 | static 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 | |||
61 | static const char *flexcop_bus_names[] = { | ||
62 | "USB", | ||
63 | "PCI", | ||
64 | }; | ||
65 | |||
66 | void 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 | |||
75 | void 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 | } | ||
86 | EXPORT_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 000000000000..dc4528dcbb98 --- /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 | |||
9 | typedef enum { | ||
10 | FLEXCOP_UNK = 0, | ||
11 | FLEXCOP_II, | ||
12 | FLEXCOP_IIB, | ||
13 | FLEXCOP_III, | ||
14 | } flexcop_revision_t; | ||
15 | |||
16 | typedef 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 | |||
29 | typedef 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 | |||
53 | extern flexcop_ibi_value ibi_zero; | ||
54 | |||
55 | typedef 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 | |||
61 | typedef enum { | ||
62 | FC_WRITE = 0, | ||
63 | FC_READ = 1, | ||
64 | } flexcop_access_op_t; | ||
65 | |||
66 | typedef 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 | |||
73 | typedef 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 | |||
80 | typedef 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 | |||
87 | typedef 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 | |||
94 | typedef enum { | ||
95 | FC_DMA_1 = 1, | ||
96 | FC_DMA_2 = 2, | ||
97 | } flexcop_dma_index_t; | ||
98 | |||
99 | typedef 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 */ | ||
105 | typedef 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 000000000000..f2199e43e803 --- /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 | |||
8 | static 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 | |||
14 | int 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 | |||
30 | int 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 | } | ||
56 | EXPORT_SYMBOL(flexcop_sram_set_dest); | ||
57 | |||
58 | void 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 | } | ||
62 | EXPORT_SYMBOL(flexcop_wan_set_speed); | ||
63 | |||
64 | void 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 | } | ||
72 | EXPORT_SYMBOL(flexcop_sram_ctrl); | ||
73 | |||
74 | #if 0 | ||
75 | static 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 | |||
100 | static 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 | |||
139 | static 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 | |||
158 | static 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 | |||
176 | static 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 | |||
195 | static 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 | |||
215 | static 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 | |||
221 | static 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 | |||
237 | static 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 | |||
281 | static 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 | |||
305 | static 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 | |||
358 | static 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 000000000000..b1e8c99f469b --- /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 | |||
45 | int b2c2_flexcop_debug; | ||
46 | module_param_named(debug, b2c2_flexcop_debug, int, 0644); | ||
47 | MODULE_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 | |||
53 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
54 | |||
55 | /* global zero for ibi values */ | ||
56 | flexcop_ibi_value ibi_zero; | ||
57 | |||
58 | static 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 | |||
64 | static 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 | |||
70 | static 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 | |||
134 | err_net: | ||
135 | fc->demux.dmx.disconnect_frontend(&fc->demux.dmx); | ||
136 | err_connect_frontend: | ||
137 | fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend); | ||
138 | err_dmx_add_mem_frontend: | ||
139 | fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend); | ||
140 | err_dmx_add_hw_frontend: | ||
141 | dvb_dmxdev_release(&fc->dmxdev); | ||
142 | err_dmx_dev: | ||
143 | dvb_dmx_release(&fc->demux); | ||
144 | err_dmx: | ||
145 | dvb_unregister_adapter(&fc->dvb_adapter); | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | static 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 */ | ||
169 | void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len) | ||
170 | { | ||
171 | dvb_dmx_swfilter(&fc->demux, buf, len); | ||
172 | } | ||
173 | EXPORT_SYMBOL(flexcop_pass_dmx_data); | ||
174 | |||
175 | void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no) | ||
176 | { | ||
177 | dvb_dmx_swfilter_packets(&fc->demux, buf, no); | ||
178 | } | ||
179 | EXPORT_SYMBOL(flexcop_pass_dmx_packets); | ||
180 | |||
181 | static 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 | |||
212 | void 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 | |||
227 | struct 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 | } | ||
248 | EXPORT_SYMBOL(flexcop_device_kmalloc); | ||
249 | |||
250 | void flexcop_device_kfree(struct flexcop_device *fc) | ||
251 | { | ||
252 | kfree(fc->bus_specific); | ||
253 | kfree(fc); | ||
254 | } | ||
255 | EXPORT_SYMBOL(flexcop_device_kfree); | ||
256 | |||
257 | int 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 | |||
294 | error: | ||
295 | flexcop_device_exit(fc); | ||
296 | return ret; | ||
297 | } | ||
298 | EXPORT_SYMBOL(flexcop_device_initialize); | ||
299 | |||
300 | void flexcop_device_exit(struct flexcop_device *fc) | ||
301 | { | ||
302 | flexcop_frontend_exit(fc); | ||
303 | flexcop_i2c_exit(fc); | ||
304 | flexcop_dvb_exit(fc); | ||
305 | } | ||
306 | EXPORT_SYMBOL(flexcop_device_exit); | ||
307 | |||
308 | static int flexcop_module_init(void) | ||
309 | { | ||
310 | info(DRIVER_NAME " loaded successfully"); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static void flexcop_module_cleanup(void) | ||
315 | { | ||
316 | info(DRIVER_NAME " unloaded successfully"); | ||
317 | } | ||
318 | |||
319 | module_init(flexcop_module_init); | ||
320 | module_exit(flexcop_module_cleanup); | ||
321 | |||
322 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
323 | MODULE_DESCRIPTION(DRIVER_NAME); | ||
324 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/common/b2c2/flexcop.h b/drivers/media/common/b2c2/flexcop.h new file mode 100644 index 000000000000..897b10c85ad9 --- /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 | |||
12 | extern 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 000000000000..8f64bdbd72bb --- /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 | |||
9 | typedef 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 000000000000..c75830d7d942 --- /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 | |||
9 | typedef 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 | ||