diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-14 15:35:57 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 22:30:06 -0400 |
commit | 25aee3debe0464f6c680173041fa3de30ec9ff54 (patch) | |
tree | e2b14f952a0831399f9cbb444cfb9c7980b6485b /drivers/media/dvb | |
parent | 786baecfe78f8e25547c628b48a60fc8e5636056 (diff) |
[media] Rename media/dvb as media/pci
The remaining dvb drivers are pci, so rename them to match the
bus.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
122 files changed, 0 insertions, 40361 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig deleted file mode 100644 index e2565a45de9b..000000000000 --- a/drivers/media/dvb/Kconfig +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | # | ||
2 | # DVB device configuration | ||
3 | # | ||
4 | |||
5 | menuconfig DVB_CAPTURE_DRIVERS | ||
6 | bool "DVB/ATSC adapters" | ||
7 | depends on DVB_CORE | ||
8 | default y | ||
9 | ---help--- | ||
10 | Say Y to select Digital TV adapters | ||
11 | |||
12 | if DVB_CAPTURE_DRIVERS && DVB_CORE | ||
13 | |||
14 | comment "Supported SAA7146 based PCI Adapters" | ||
15 | depends on DVB_CORE && PCI && I2C | ||
16 | source "drivers/media/dvb/ttpci/Kconfig" | ||
17 | |||
18 | comment "Supported FlexCopII (B2C2) Adapters" | ||
19 | depends on DVB_CORE && (PCI || USB) && I2C | ||
20 | source "drivers/media/dvb/b2c2/Kconfig" | ||
21 | |||
22 | comment "Supported BT878 Adapters" | ||
23 | depends on DVB_CORE && PCI && I2C | ||
24 | source "drivers/media/dvb/bt8xx/Kconfig" | ||
25 | |||
26 | comment "Supported Pluto2 Adapters" | ||
27 | depends on DVB_CORE && PCI && I2C | ||
28 | source "drivers/media/dvb/pluto2/Kconfig" | ||
29 | |||
30 | comment "Supported SDMC DM1105 Adapters" | ||
31 | depends on DVB_CORE && PCI && I2C | ||
32 | source "drivers/media/dvb/dm1105/Kconfig" | ||
33 | |||
34 | comment "Supported Earthsoft PT1 Adapters" | ||
35 | depends on DVB_CORE && PCI && I2C | ||
36 | source "drivers/media/dvb/pt1/Kconfig" | ||
37 | |||
38 | comment "Supported Mantis Adapters" | ||
39 | depends on DVB_CORE && PCI && I2C | ||
40 | source "drivers/media/dvb/mantis/Kconfig" | ||
41 | |||
42 | comment "Supported nGene Adapters" | ||
43 | depends on DVB_CORE && PCI && I2C | ||
44 | source "drivers/media/dvb/ngene/Kconfig" | ||
45 | |||
46 | comment "Supported ddbridge ('Octopus') Adapters" | ||
47 | depends on DVB_CORE && PCI && I2C | ||
48 | source "drivers/media/dvb/ddbridge/Kconfig" | ||
49 | |||
50 | endif # DVB_CAPTURE_DRIVERS | ||
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile deleted file mode 100644 index c5fa43a275ae..000000000000 --- a/drivers/media/dvb/Makefile +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the kernel multimedia device drivers. | ||
3 | # | ||
4 | |||
5 | obj-y := ttpci/ \ | ||
6 | b2c2/ \ | ||
7 | bt8xx/ \ | ||
8 | pluto2/ \ | ||
9 | dm1105/ \ | ||
10 | pt1/ \ | ||
11 | mantis/ \ | ||
12 | ngene/ \ | ||
13 | ddbridge/ | ||
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig deleted file mode 100644 index 9e5781400744..000000000000 --- a/drivers/media/dvb/b2c2/Kconfig +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | config DVB_B2C2_FLEXCOP | ||
2 | tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" | ||
3 | depends on DVB_CORE && I2C | ||
4 | select DVB_PLL if !DVB_FE_CUSTOMISE | ||
5 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
6 | select DVB_MT352 if !DVB_FE_CUSTOMISE | ||
7 | select DVB_MT312 if !DVB_FE_CUSTOMISE | ||
8 | select DVB_NXT200X if !DVB_FE_CUSTOMISE | ||
9 | select DVB_STV0297 if !DVB_FE_CUSTOMISE | ||
10 | select DVB_BCM3510 if !DVB_FE_CUSTOMISE | ||
11 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | ||
12 | select DVB_S5H1420 if !DVB_FE_CUSTOMISE | ||
13 | select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE | ||
14 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE | ||
15 | select DVB_CX24123 if !DVB_FE_CUSTOMISE | ||
16 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE | ||
17 | select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE | ||
18 | help | ||
19 | Support for the digital TV receiver chip made by B2C2 Inc. included in | ||
20 | Technisats PCI cards and USB boxes. | ||
21 | |||
22 | Say Y if you own such a device and want to use it. | ||
23 | |||
24 | config DVB_B2C2_FLEXCOP_PCI | ||
25 | tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI" | ||
26 | depends on DVB_B2C2_FLEXCOP && PCI && I2C | ||
27 | help | ||
28 | Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2. | ||
29 | |||
30 | Say Y if you own such a device and want to use it. | ||
31 | |||
32 | config DVB_B2C2_FLEXCOP_USB | ||
33 | tristate "Technisat/B2C2 Air/Sky/Cable2PC USB" | ||
34 | depends on DVB_B2C2_FLEXCOP && USB && I2C | ||
35 | help | ||
36 | Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2, | ||
37 | |||
38 | Say Y if you own such a device and want to use it. | ||
39 | |||
40 | config DVB_B2C2_FLEXCOP_DEBUG | ||
41 | bool "Enable debug for the B2C2 FlexCop drivers" | ||
42 | depends on DVB_B2C2_FLEXCOP | ||
43 | help | ||
44 | Say Y if you want to enable the module option to control debug messages | ||
45 | of all B2C2 FlexCop drivers. | ||
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile deleted file mode 100644 index 7a1f5ce6d322..000000000000 --- a/drivers/media/dvb/b2c2/Makefile +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
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 | ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),) | ||
6 | b2c2-flexcop-objs += flexcop-dma.o | ||
7 | endif | ||
8 | |||
9 | b2c2-flexcop-pci-objs = flexcop-pci.o | ||
10 | obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o | ||
11 | |||
12 | b2c2-flexcop-usb-objs = flexcop-usb.o | ||
13 | obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o | ||
14 | |||
15 | ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ | ||
16 | ccflags-y += -Idrivers/media/common/tuners/ | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h deleted file mode 100644 index 437912e49824..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
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/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c deleted file mode 100644 index 2881e0d956ad..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-dma.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * flexcop-dma.c - configuring and controlling the DMA of the FlexCop | ||
4 | * see flexcop.c for copyright information | ||
5 | */ | ||
6 | #include "flexcop.h" | ||
7 | |||
8 | int flexcop_dma_allocate(struct pci_dev *pdev, | ||
9 | struct flexcop_dma *dma, u32 size) | ||
10 | { | ||
11 | u8 *tcpu; | ||
12 | dma_addr_t tdma = 0; | ||
13 | |||
14 | if (size % 2) { | ||
15 | err("dma buffersize has to be even."); | ||
16 | return -EINVAL; | ||
17 | } | ||
18 | |||
19 | if ((tcpu = pci_alloc_consistent(pdev, size, &tdma)) != NULL) { | ||
20 | dma->pdev = pdev; | ||
21 | dma->cpu_addr0 = tcpu; | ||
22 | dma->dma_addr0 = tdma; | ||
23 | dma->cpu_addr1 = tcpu + size/2; | ||
24 | dma->dma_addr1 = tdma + size/2; | ||
25 | dma->size = size/2; | ||
26 | return 0; | ||
27 | } | ||
28 | return -ENOMEM; | ||
29 | } | ||
30 | EXPORT_SYMBOL(flexcop_dma_allocate); | ||
31 | |||
32 | void flexcop_dma_free(struct flexcop_dma *dma) | ||
33 | { | ||
34 | pci_free_consistent(dma->pdev, dma->size*2, | ||
35 | dma->cpu_addr0, dma->dma_addr0); | ||
36 | memset(dma,0,sizeof(struct flexcop_dma)); | ||
37 | } | ||
38 | EXPORT_SYMBOL(flexcop_dma_free); | ||
39 | |||
40 | int flexcop_dma_config(struct flexcop_device *fc, | ||
41 | struct flexcop_dma *dma, | ||
42 | flexcop_dma_index_t dma_idx) | ||
43 | { | ||
44 | flexcop_ibi_value v0x0,v0x4,v0xc; | ||
45 | v0x0.raw = v0x4.raw = v0xc.raw = 0; | ||
46 | |||
47 | v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; | ||
48 | v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; | ||
49 | v0x4.dma_0x4_write.dma_addr_size = dma->size / 4; | ||
50 | |||
51 | if ((dma_idx & FC_DMA_1) == dma_idx) { | ||
52 | fc->write_ibi_reg(fc,dma1_000,v0x0); | ||
53 | fc->write_ibi_reg(fc,dma1_004,v0x4); | ||
54 | fc->write_ibi_reg(fc,dma1_00c,v0xc); | ||
55 | } else if ((dma_idx & FC_DMA_2) == dma_idx) { | ||
56 | fc->write_ibi_reg(fc,dma2_010,v0x0); | ||
57 | fc->write_ibi_reg(fc,dma2_014,v0x4); | ||
58 | fc->write_ibi_reg(fc,dma2_01c,v0xc); | ||
59 | } else { | ||
60 | err("either DMA1 or DMA2 can be configured within one " | ||
61 | "flexcop_dma_config call."); | ||
62 | return -EINVAL; | ||
63 | } | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | EXPORT_SYMBOL(flexcop_dma_config); | ||
68 | |||
69 | /* start the DMA transfers, but not the DMA IRQs */ | ||
70 | int flexcop_dma_xfer_control(struct flexcop_device *fc, | ||
71 | flexcop_dma_index_t dma_idx, | ||
72 | flexcop_dma_addr_index_t index, | ||
73 | int onoff) | ||
74 | { | ||
75 | flexcop_ibi_value v0x0,v0xc; | ||
76 | flexcop_ibi_register r0x0,r0xc; | ||
77 | |||
78 | if ((dma_idx & FC_DMA_1) == dma_idx) { | ||
79 | r0x0 = dma1_000; | ||
80 | r0xc = dma1_00c; | ||
81 | } else if ((dma_idx & FC_DMA_2) == dma_idx) { | ||
82 | r0x0 = dma2_010; | ||
83 | r0xc = dma2_01c; | ||
84 | } else { | ||
85 | err("either transfer DMA1 or DMA2 can be started within one " | ||
86 | "flexcop_dma_xfer_control call."); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | |||
90 | v0x0 = fc->read_ibi_reg(fc,r0x0); | ||
91 | v0xc = fc->read_ibi_reg(fc,r0xc); | ||
92 | |||
93 | deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw); | ||
94 | deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw); | ||
95 | |||
96 | if (index & FC_DMA_SUBADDR_0) | ||
97 | v0x0.dma_0x0.dma_0start = onoff; | ||
98 | |||
99 | if (index & FC_DMA_SUBADDR_1) | ||
100 | v0xc.dma_0xc.dma_1start = onoff; | ||
101 | |||
102 | fc->write_ibi_reg(fc,r0x0,v0x0); | ||
103 | fc->write_ibi_reg(fc,r0xc,v0xc); | ||
104 | |||
105 | deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw); | ||
106 | deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw); | ||
107 | return 0; | ||
108 | } | ||
109 | EXPORT_SYMBOL(flexcop_dma_xfer_control); | ||
110 | |||
111 | static int flexcop_dma_remap(struct flexcop_device *fc, | ||
112 | flexcop_dma_index_t dma_idx, | ||
113 | int onoff) | ||
114 | { | ||
115 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c; | ||
116 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
117 | deb_info("%s\n",__func__); | ||
118 | v.dma_0xc.remap_enable = onoff; | ||
119 | fc->write_ibi_reg(fc,r,v); | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, | ||
124 | flexcop_dma_index_t no, | ||
125 | int onoff) | ||
126 | { | ||
127 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | ||
128 | |||
129 | if (no & FC_DMA_1) | ||
130 | v.ctrl_208.DMA1_IRQ_Enable_sig = onoff; | ||
131 | |||
132 | if (no & FC_DMA_2) | ||
133 | v.ctrl_208.DMA2_IRQ_Enable_sig = onoff; | ||
134 | |||
135 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
136 | return 0; | ||
137 | } | ||
138 | EXPORT_SYMBOL(flexcop_dma_control_size_irq); | ||
139 | |||
140 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, | ||
141 | flexcop_dma_index_t no, | ||
142 | int onoff) | ||
143 | { | ||
144 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | ||
145 | |||
146 | if (no & FC_DMA_1) | ||
147 | v.ctrl_208.DMA1_Timer_Enable_sig = onoff; | ||
148 | |||
149 | if (no & FC_DMA_2) | ||
150 | v.ctrl_208.DMA2_Timer_Enable_sig = onoff; | ||
151 | |||
152 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
153 | return 0; | ||
154 | } | ||
155 | EXPORT_SYMBOL(flexcop_dma_control_timer_irq); | ||
156 | |||
157 | /* 1 cycles = 1.97 msec */ | ||
158 | int flexcop_dma_config_timer(struct flexcop_device *fc, | ||
159 | flexcop_dma_index_t dma_idx, u8 cycles) | ||
160 | { | ||
161 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | ||
162 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
163 | |||
164 | flexcop_dma_remap(fc,dma_idx,0); | ||
165 | |||
166 | deb_info("%s\n",__func__); | ||
167 | v.dma_0x4_write.dmatimer = cycles; | ||
168 | fc->write_ibi_reg(fc,r,v); | ||
169 | return 0; | ||
170 | } | ||
171 | EXPORT_SYMBOL(flexcop_dma_config_timer); | ||
172 | |||
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c deleted file mode 100644 index a25373a9bd84..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-eeprom.c +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
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/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c deleted file mode 100644 index 850a6c606750..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ /dev/null | |||
@@ -1,678 +0,0 @@ | |||
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/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c deleted file mode 100644 index 77e45475f4c7..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
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/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c deleted file mode 100644 index 965d5eb33752..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ /dev/null | |||
@@ -1,288 +0,0 @@ | |||
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/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c deleted file mode 100644 index f06f3a9070f5..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
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/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c deleted file mode 100644 index 44f8fb5f17ff..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ /dev/null | |||
@@ -1,450 +0,0 @@ | |||
1 | /* | ||
2 | * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * flexcop-pci.c - covers the PCI part including DMA transfers | ||
4 | * see flexcop.c for copyright information | ||
5 | */ | ||
6 | |||
7 | #define FC_LOG_PREFIX "flexcop-pci" | ||
8 | #include "flexcop-common.h" | ||
9 | |||
10 | static int enable_pid_filtering = 1; | ||
11 | module_param(enable_pid_filtering, int, 0444); | ||
12 | MODULE_PARM_DESC(enable_pid_filtering, | ||
13 | "enable hardware pid filtering: supported values: 0 (fullts), 1"); | ||
14 | |||
15 | static int irq_chk_intv = 100; | ||
16 | module_param(irq_chk_intv, int, 0644); | ||
17 | MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); | ||
18 | |||
19 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG | ||
20 | #define dprintk(level,args...) \ | ||
21 | do { if ((debug & level)) printk(args); } while (0) | ||
22 | #define DEBSTATUS "" | ||
23 | #else | ||
24 | #define dprintk(level,args...) | ||
25 | #define DEBSTATUS " (debugging is not enabled)" | ||
26 | #endif | ||
27 | |||
28 | #define deb_info(args...) dprintk(0x01, args) | ||
29 | #define deb_reg(args...) dprintk(0x02, args) | ||
30 | #define deb_ts(args...) dprintk(0x04, args) | ||
31 | #define deb_irq(args...) dprintk(0x08, args) | ||
32 | #define deb_chk(args...) dprintk(0x10, args) | ||
33 | |||
34 | static int debug; | ||
35 | module_param(debug, int, 0644); | ||
36 | MODULE_PARM_DESC(debug, | ||
37 | "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." | ||
38 | DEBSTATUS); | ||
39 | |||
40 | #define DRIVER_VERSION "0.1" | ||
41 | #define DRIVER_NAME "flexcop-pci" | ||
42 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" | ||
43 | |||
44 | struct flexcop_pci { | ||
45 | struct pci_dev *pdev; | ||
46 | |||
47 | #define FC_PCI_INIT 0x01 | ||
48 | #define FC_PCI_DMA_INIT 0x02 | ||
49 | int init_state; | ||
50 | |||
51 | void __iomem *io_mem; | ||
52 | u32 irq; | ||
53 | /* buffersize (at least for DMA1, need to be % 188 == 0, | ||
54 | * this logic is required */ | ||
55 | #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188) | ||
56 | #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188) | ||
57 | struct flexcop_dma dma[2]; | ||
58 | |||
59 | int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ | ||
60 | u32 last_dma1_cur_pos; | ||
61 | /* position of the pointer last time the timer/packet irq occurred */ | ||
62 | int count; | ||
63 | int count_prev; | ||
64 | int stream_problem; | ||
65 | |||
66 | spinlock_t irq_lock; | ||
67 | unsigned long last_irq; | ||
68 | |||
69 | struct delayed_work irq_check_work; | ||
70 | struct flexcop_device *fc_dev; | ||
71 | }; | ||
72 | |||
73 | static int lastwreg, lastwval, lastrreg, lastrval; | ||
74 | |||
75 | static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc, | ||
76 | flexcop_ibi_register r) | ||
77 | { | ||
78 | struct flexcop_pci *fc_pci = fc->bus_specific; | ||
79 | flexcop_ibi_value v; | ||
80 | v.raw = readl(fc_pci->io_mem + r); | ||
81 | |||
82 | if (lastrreg != r || lastrval != v.raw) { | ||
83 | lastrreg = r; lastrval = v.raw; | ||
84 | deb_reg("new rd: %3x: %08x\n", r, v.raw); | ||
85 | } | ||
86 | |||
87 | return v; | ||
88 | } | ||
89 | |||
90 | static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, | ||
91 | flexcop_ibi_register r, flexcop_ibi_value v) | ||
92 | { | ||
93 | struct flexcop_pci *fc_pci = fc->bus_specific; | ||
94 | |||
95 | if (lastwreg != r || lastwval != v.raw) { | ||
96 | lastwreg = r; lastwval = v.raw; | ||
97 | deb_reg("new wr: %3x: %08x\n", r, v.raw); | ||
98 | } | ||
99 | |||
100 | writel(v.raw, fc_pci->io_mem + r); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static void flexcop_pci_irq_check_work(struct work_struct *work) | ||
105 | { | ||
106 | struct flexcop_pci *fc_pci = | ||
107 | container_of(work, struct flexcop_pci, irq_check_work.work); | ||
108 | struct flexcop_device *fc = fc_pci->fc_dev; | ||
109 | |||
110 | if (fc->feedcount) { | ||
111 | |||
112 | if (fc_pci->count == fc_pci->count_prev) { | ||
113 | deb_chk("no IRQ since the last check\n"); | ||
114 | if (fc_pci->stream_problem++ == 3) { | ||
115 | struct dvb_demux_feed *feed; | ||
116 | deb_info("flexcop-pci: stream problem, resetting pid filter\n"); | ||
117 | |||
118 | spin_lock_irq(&fc->demux.lock); | ||
119 | list_for_each_entry(feed, &fc->demux.feed_list, | ||
120 | list_head) { | ||
121 | flexcop_pid_feed_control(fc, feed, 0); | ||
122 | } | ||
123 | |||
124 | list_for_each_entry(feed, &fc->demux.feed_list, | ||
125 | list_head) { | ||
126 | flexcop_pid_feed_control(fc, feed, 1); | ||
127 | } | ||
128 | spin_unlock_irq(&fc->demux.lock); | ||
129 | |||
130 | fc_pci->stream_problem = 0; | ||
131 | } | ||
132 | } else { | ||
133 | fc_pci->stream_problem = 0; | ||
134 | fc_pci->count_prev = fc_pci->count; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | schedule_delayed_work(&fc_pci->irq_check_work, | ||
139 | msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); | ||
140 | } | ||
141 | |||
142 | /* When PID filtering is turned on, we use the timer IRQ, because small amounts | ||
143 | * of data need to be passed to the user space instantly as well. When PID | ||
144 | * filtering is turned off, we use the page-change-IRQ */ | ||
145 | static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) | ||
146 | { | ||
147 | struct flexcop_pci *fc_pci = dev_id; | ||
148 | struct flexcop_device *fc = fc_pci->fc_dev; | ||
149 | unsigned long flags; | ||
150 | flexcop_ibi_value v; | ||
151 | irqreturn_t ret = IRQ_HANDLED; | ||
152 | |||
153 | spin_lock_irqsave(&fc_pci->irq_lock, flags); | ||
154 | v = fc->read_ibi_reg(fc, irq_20c); | ||
155 | |||
156 | /* errors */ | ||
157 | if (v.irq_20c.Data_receiver_error) | ||
158 | deb_chk("data receiver error\n"); | ||
159 | if (v.irq_20c.Continuity_error_flag) | ||
160 | deb_chk("Contunuity error flag is set\n"); | ||
161 | if (v.irq_20c.LLC_SNAP_FLAG_set) | ||
162 | deb_chk("LLC_SNAP_FLAG_set is set\n"); | ||
163 | if (v.irq_20c.Transport_Error) | ||
164 | deb_chk("Transport error\n"); | ||
165 | |||
166 | if ((fc_pci->count % 1000) == 0) | ||
167 | deb_chk("%d valid irq took place so far\n", fc_pci->count); | ||
168 | |||
169 | if (v.irq_20c.DMA1_IRQ_Status == 1) { | ||
170 | if (fc_pci->active_dma1_addr == 0) | ||
171 | flexcop_pass_dmx_packets(fc_pci->fc_dev, | ||
172 | fc_pci->dma[0].cpu_addr0, | ||
173 | fc_pci->dma[0].size / 188); | ||
174 | else | ||
175 | flexcop_pass_dmx_packets(fc_pci->fc_dev, | ||
176 | fc_pci->dma[0].cpu_addr1, | ||
177 | fc_pci->dma[0].size / 188); | ||
178 | |||
179 | deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr); | ||
180 | fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr; | ||
181 | /* for the timer IRQ we only can use buffer dmx feeding, because we don't have | ||
182 | * complete TS packets when reading from the DMA memory */ | ||
183 | } else if (v.irq_20c.DMA1_Timer_Status == 1) { | ||
184 | dma_addr_t cur_addr = | ||
185 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; | ||
186 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; | ||
187 | |||
188 | deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, " | ||
189 | "last_cur_pos: %08x ", | ||
190 | jiffies_to_usecs(jiffies - fc_pci->last_irq), | ||
191 | v.raw, (unsigned long long)cur_addr, cur_pos, | ||
192 | fc_pci->last_dma1_cur_pos); | ||
193 | fc_pci->last_irq = jiffies; | ||
194 | |||
195 | /* buffer end was reached, restarted from the beginning | ||
196 | * pass the data from last_cur_pos to the buffer end to the demux | ||
197 | */ | ||
198 | if (cur_pos < fc_pci->last_dma1_cur_pos) { | ||
199 | deb_irq(" end was reached: passing %d bytes ", | ||
200 | (fc_pci->dma[0].size*2 - 1) - | ||
201 | fc_pci->last_dma1_cur_pos); | ||
202 | flexcop_pass_dmx_data(fc_pci->fc_dev, | ||
203 | fc_pci->dma[0].cpu_addr0 + | ||
204 | fc_pci->last_dma1_cur_pos, | ||
205 | (fc_pci->dma[0].size*2) - | ||
206 | fc_pci->last_dma1_cur_pos); | ||
207 | fc_pci->last_dma1_cur_pos = 0; | ||
208 | } | ||
209 | |||
210 | if (cur_pos > fc_pci->last_dma1_cur_pos) { | ||
211 | deb_irq(" passing %d bytes ", | ||
212 | cur_pos - fc_pci->last_dma1_cur_pos); | ||
213 | flexcop_pass_dmx_data(fc_pci->fc_dev, | ||
214 | fc_pci->dma[0].cpu_addr0 + | ||
215 | fc_pci->last_dma1_cur_pos, | ||
216 | cur_pos - fc_pci->last_dma1_cur_pos); | ||
217 | } | ||
218 | deb_irq("\n"); | ||
219 | |||
220 | fc_pci->last_dma1_cur_pos = cur_pos; | ||
221 | fc_pci->count++; | ||
222 | } else { | ||
223 | deb_irq("isr for flexcop called, " | ||
224 | "apparently without reason (%08x)\n", v.raw); | ||
225 | ret = IRQ_NONE; | ||
226 | } | ||
227 | |||
228 | spin_unlock_irqrestore(&fc_pci->irq_lock, flags); | ||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) | ||
233 | { | ||
234 | struct flexcop_pci *fc_pci = fc->bus_specific; | ||
235 | if (onoff) { | ||
236 | flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1); | ||
237 | flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2); | ||
238 | flexcop_dma_config_timer(fc, FC_DMA_1, 0); | ||
239 | flexcop_dma_xfer_control(fc, FC_DMA_1, | ||
240 | FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1); | ||
241 | deb_irq("DMA xfer enabled\n"); | ||
242 | |||
243 | fc_pci->last_dma1_cur_pos = 0; | ||
244 | flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1); | ||
245 | deb_irq("IRQ enabled\n"); | ||
246 | fc_pci->count_prev = fc_pci->count; | ||
247 | } else { | ||
248 | flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0); | ||
249 | deb_irq("IRQ disabled\n"); | ||
250 | |||
251 | flexcop_dma_xfer_control(fc, FC_DMA_1, | ||
252 | FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0); | ||
253 | deb_irq("DMA xfer disabled\n"); | ||
254 | } | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) | ||
259 | { | ||
260 | int ret; | ||
261 | ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0], | ||
262 | FC_DEFAULT_DMA1_BUFSIZE); | ||
263 | if (ret != 0) | ||
264 | return ret; | ||
265 | |||
266 | ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1], | ||
267 | FC_DEFAULT_DMA2_BUFSIZE); | ||
268 | if (ret != 0) { | ||
269 | flexcop_dma_free(&fc_pci->dma[0]); | ||
270 | return ret; | ||
271 | } | ||
272 | |||
273 | flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA | | ||
274 | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); | ||
275 | flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO | | ||
276 | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); | ||
277 | fc_pci->init_state |= FC_PCI_DMA_INIT; | ||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci) | ||
282 | { | ||
283 | if (fc_pci->init_state & FC_PCI_DMA_INIT) { | ||
284 | flexcop_dma_free(&fc_pci->dma[0]); | ||
285 | flexcop_dma_free(&fc_pci->dma[1]); | ||
286 | } | ||
287 | fc_pci->init_state &= ~FC_PCI_DMA_INIT; | ||
288 | } | ||
289 | |||
290 | static int flexcop_pci_init(struct flexcop_pci *fc_pci) | ||
291 | { | ||
292 | int ret; | ||
293 | |||
294 | info("card revision %x", fc_pci->pdev->revision); | ||
295 | |||
296 | if ((ret = pci_enable_device(fc_pci->pdev)) != 0) | ||
297 | return ret; | ||
298 | pci_set_master(fc_pci->pdev); | ||
299 | |||
300 | if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0) | ||
301 | goto err_pci_disable_device; | ||
302 | |||
303 | fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800); | ||
304 | |||
305 | if (!fc_pci->io_mem) { | ||
306 | err("cannot map io memory\n"); | ||
307 | ret = -EIO; | ||
308 | goto err_pci_release_regions; | ||
309 | } | ||
310 | |||
311 | pci_set_drvdata(fc_pci->pdev, fc_pci); | ||
312 | spin_lock_init(&fc_pci->irq_lock); | ||
313 | if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr, | ||
314 | IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) | ||
315 | goto err_pci_iounmap; | ||
316 | |||
317 | fc_pci->init_state |= FC_PCI_INIT; | ||
318 | return ret; | ||
319 | |||
320 | err_pci_iounmap: | ||
321 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | ||
322 | pci_set_drvdata(fc_pci->pdev, NULL); | ||
323 | err_pci_release_regions: | ||
324 | pci_release_regions(fc_pci->pdev); | ||
325 | err_pci_disable_device: | ||
326 | pci_disable_device(fc_pci->pdev); | ||
327 | return ret; | ||
328 | } | ||
329 | |||
330 | static void flexcop_pci_exit(struct flexcop_pci *fc_pci) | ||
331 | { | ||
332 | if (fc_pci->init_state & FC_PCI_INIT) { | ||
333 | free_irq(fc_pci->pdev->irq, fc_pci); | ||
334 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | ||
335 | pci_set_drvdata(fc_pci->pdev, NULL); | ||
336 | pci_release_regions(fc_pci->pdev); | ||
337 | pci_disable_device(fc_pci->pdev); | ||
338 | } | ||
339 | fc_pci->init_state &= ~FC_PCI_INIT; | ||
340 | } | ||
341 | |||
342 | static int flexcop_pci_probe(struct pci_dev *pdev, | ||
343 | const struct pci_device_id *ent) | ||
344 | { | ||
345 | struct flexcop_device *fc; | ||
346 | struct flexcop_pci *fc_pci; | ||
347 | int ret = -ENOMEM; | ||
348 | |||
349 | if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) { | ||
350 | err("out of memory\n"); | ||
351 | return -ENOMEM; | ||
352 | } | ||
353 | |||
354 | /* general flexcop init */ | ||
355 | fc_pci = fc->bus_specific; | ||
356 | fc_pci->fc_dev = fc; | ||
357 | |||
358 | fc->read_ibi_reg = flexcop_pci_read_ibi_reg; | ||
359 | fc->write_ibi_reg = flexcop_pci_write_ibi_reg; | ||
360 | fc->i2c_request = flexcop_i2c_request; | ||
361 | fc->get_mac_addr = flexcop_eeprom_check_mac_addr; | ||
362 | fc->stream_control = flexcop_pci_stream_control; | ||
363 | |||
364 | if (enable_pid_filtering) | ||
365 | info("will use the HW PID filter."); | ||
366 | else | ||
367 | info("will pass the complete TS to the demuxer."); | ||
368 | |||
369 | fc->pid_filtering = enable_pid_filtering; | ||
370 | fc->bus_type = FC_PCI; | ||
371 | fc->dev = &pdev->dev; | ||
372 | fc->owner = THIS_MODULE; | ||
373 | |||
374 | /* bus specific part */ | ||
375 | fc_pci->pdev = pdev; | ||
376 | if ((ret = flexcop_pci_init(fc_pci)) != 0) | ||
377 | goto err_kfree; | ||
378 | |||
379 | /* init flexcop */ | ||
380 | if ((ret = flexcop_device_initialize(fc)) != 0) | ||
381 | goto err_pci_exit; | ||
382 | |||
383 | /* init dma */ | ||
384 | if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) | ||
385 | goto err_fc_exit; | ||
386 | |||
387 | INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); | ||
388 | |||
389 | if (irq_chk_intv > 0) | ||
390 | schedule_delayed_work(&fc_pci->irq_check_work, | ||
391 | msecs_to_jiffies(irq_chk_intv < 100 ? | ||
392 | 100 : | ||
393 | irq_chk_intv)); | ||
394 | return ret; | ||
395 | |||
396 | err_fc_exit: | ||
397 | flexcop_device_exit(fc); | ||
398 | err_pci_exit: | ||
399 | flexcop_pci_exit(fc_pci); | ||
400 | err_kfree: | ||
401 | flexcop_device_kfree(fc); | ||
402 | return ret; | ||
403 | } | ||
404 | |||
405 | /* in theory every _exit function should be called exactly two times, | ||
406 | * here and in the bail-out-part of the _init-function | ||
407 | */ | ||
408 | static void flexcop_pci_remove(struct pci_dev *pdev) | ||
409 | { | ||
410 | struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); | ||
411 | |||
412 | if (irq_chk_intv > 0) | ||
413 | cancel_delayed_work(&fc_pci->irq_check_work); | ||
414 | |||
415 | flexcop_pci_dma_exit(fc_pci); | ||
416 | flexcop_device_exit(fc_pci->fc_dev); | ||
417 | flexcop_pci_exit(fc_pci); | ||
418 | flexcop_device_kfree(fc_pci->fc_dev); | ||
419 | } | ||
420 | |||
421 | static struct pci_device_id flexcop_pci_tbl[] = { | ||
422 | { PCI_DEVICE(0x13d0, 0x2103) }, | ||
423 | { }, | ||
424 | }; | ||
425 | |||
426 | MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl); | ||
427 | |||
428 | static struct pci_driver flexcop_pci_driver = { | ||
429 | .name = "b2c2_flexcop_pci", | ||
430 | .id_table = flexcop_pci_tbl, | ||
431 | .probe = flexcop_pci_probe, | ||
432 | .remove = flexcop_pci_remove, | ||
433 | }; | ||
434 | |||
435 | static int __init flexcop_pci_module_init(void) | ||
436 | { | ||
437 | return pci_register_driver(&flexcop_pci_driver); | ||
438 | } | ||
439 | |||
440 | static void __exit flexcop_pci_module_exit(void) | ||
441 | { | ||
442 | pci_unregister_driver(&flexcop_pci_driver); | ||
443 | } | ||
444 | |||
445 | module_init(flexcop_pci_module_init); | ||
446 | module_exit(flexcop_pci_module_exit); | ||
447 | |||
448 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
449 | MODULE_DESCRIPTION(DRIVER_NAME); | ||
450 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h deleted file mode 100644 index dc4528dcbb98..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
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/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c deleted file mode 100644 index f2199e43e803..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-sram.c +++ /dev/null | |||
@@ -1,363 +0,0 @@ | |||
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/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c deleted file mode 100644 index 8b6275f85908..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ /dev/null | |||
@@ -1,587 +0,0 @@ | |||
1 | /* | ||
2 | * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * flexcop-usb.c - covers the USB part | ||
4 | * see flexcop.c for copyright information | ||
5 | */ | ||
6 | #define FC_LOG_PREFIX "flexcop_usb" | ||
7 | #include "flexcop-usb.h" | ||
8 | #include "flexcop-common.h" | ||
9 | |||
10 | /* Version information */ | ||
11 | #define DRIVER_VERSION "0.1" | ||
12 | #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver" | ||
13 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" | ||
14 | |||
15 | /* debug */ | ||
16 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG | ||
17 | #define dprintk(level,args...) \ | ||
18 | do { if ((debug & level)) printk(args); } while (0) | ||
19 | |||
20 | #define debug_dump(b, l, method) do {\ | ||
21 | int i; \ | ||
22 | for (i = 0; i < l; i++) \ | ||
23 | method("%02x ", b[i]); \ | ||
24 | method("\n"); \ | ||
25 | } while (0) | ||
26 | |||
27 | #define DEBSTATUS "" | ||
28 | #else | ||
29 | #define dprintk(level, args...) | ||
30 | #define debug_dump(b, l, method) | ||
31 | #define DEBSTATUS " (debugging is not enabled)" | ||
32 | #endif | ||
33 | |||
34 | static int debug; | ||
35 | module_param(debug, int, 0644); | ||
36 | MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2," | ||
37 | "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); | ||
38 | #undef DEBSTATUS | ||
39 | |||
40 | #define deb_info(args...) dprintk(0x01, args) | ||
41 | #define deb_ts(args...) dprintk(0x02, args) | ||
42 | #define deb_ctrl(args...) dprintk(0x04, args) | ||
43 | #define deb_i2c(args...) dprintk(0x08, args) | ||
44 | #define deb_v8(args...) dprintk(0x10, args) | ||
45 | |||
46 | /* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits | ||
47 | * in the IBI address, to make the V8 code simpler. | ||
48 | * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used) | ||
49 | * in general: 0000 0HHH 000L LL00 | ||
50 | * IBI ADDRESS FORMAT: RHHH BLLL | ||
51 | * | ||
52 | * where R is the read(1)/write(0) bit, B is the busy bit | ||
53 | * and HHH and LLL are the two sets of three bits from the PCI address. | ||
54 | */ | ||
55 | #define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \ | ||
56 | (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) | ||
57 | #define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \ | ||
58 | (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) | ||
59 | |||
60 | /* | ||
61 | * DKT 020228 | ||
62 | * - forget about this VENDOR_BUFFER_SIZE, read and write register | ||
63 | * deal with DWORD or 4 bytes, that should be should from now on | ||
64 | * - from now on, we don't support anything older than firm 1.00 | ||
65 | * I eliminated the write register as a 2 trip of writing hi word and lo word | ||
66 | * and force this to write only 4 bytes at a time. | ||
67 | * NOTE: this should work with all the firmware from 1.00 and newer | ||
68 | */ | ||
69 | static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read) | ||
70 | { | ||
71 | struct flexcop_usb *fc_usb = fc->bus_specific; | ||
72 | u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG; | ||
73 | u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR; | ||
74 | u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | | ||
75 | (read ? 0x80 : 0); | ||
76 | |||
77 | int len = usb_control_msg(fc_usb->udev, | ||
78 | read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT, | ||
79 | request, | ||
80 | request_type, /* 0xc0 read or 0x40 write */ | ||
81 | wAddress, | ||
82 | 0, | ||
83 | val, | ||
84 | sizeof(u32), | ||
85 | B2C2_WAIT_FOR_OPERATION_RDW * HZ); | ||
86 | |||
87 | if (len != sizeof(u32)) { | ||
88 | err("error while %s dword from %d (%d).", read ? "reading" : | ||
89 | "writing", wAddress, wRegOffsPCI); | ||
90 | return -EIO; | ||
91 | } | ||
92 | return 0; | ||
93 | } | ||
94 | /* | ||
95 | * DKT 010817 - add support for V8 memory read/write and flash update | ||
96 | */ | ||
97 | static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, | ||
98 | flexcop_usb_request_t req, u8 page, u16 wAddress, | ||
99 | u8 *pbBuffer, u32 buflen) | ||
100 | { | ||
101 | u8 request_type = USB_TYPE_VENDOR; | ||
102 | u16 wIndex; | ||
103 | int nWaitTime, pipe, len; | ||
104 | wIndex = page << 8; | ||
105 | |||
106 | switch (req) { | ||
107 | case B2C2_USB_READ_V8_MEM: | ||
108 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; | ||
109 | request_type |= USB_DIR_IN; | ||
110 | pipe = B2C2_USB_CTRL_PIPE_IN; | ||
111 | break; | ||
112 | case B2C2_USB_WRITE_V8_MEM: | ||
113 | wIndex |= pbBuffer[0]; | ||
114 | request_type |= USB_DIR_OUT; | ||
115 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; | ||
116 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
117 | break; | ||
118 | case B2C2_USB_FLASH_BLOCK: | ||
119 | request_type |= USB_DIR_OUT; | ||
120 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; | ||
121 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
122 | break; | ||
123 | default: | ||
124 | deb_info("unsupported request for v8_mem_req %x.\n", req); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req, | ||
128 | wAddress, wIndex, buflen); | ||
129 | |||
130 | len = usb_control_msg(fc_usb->udev, pipe, | ||
131 | req, | ||
132 | request_type, | ||
133 | wAddress, | ||
134 | wIndex, | ||
135 | pbBuffer, | ||
136 | buflen, | ||
137 | nWaitTime * HZ); | ||
138 | |||
139 | debug_dump(pbBuffer, len, deb_v8); | ||
140 | return len == buflen ? 0 : -EIO; | ||
141 | } | ||
142 | |||
143 | #define bytes_left_to_read_on_page(paddr,buflen) \ | ||
144 | ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \ | ||
145 | ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK))) | ||
146 | |||
147 | static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb, | ||
148 | flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start, | ||
149 | u32 addr, int extended, u8 *buf, u32 len) | ||
150 | { | ||
151 | int i,ret = 0; | ||
152 | u16 wMax; | ||
153 | u32 pagechunk = 0; | ||
154 | |||
155 | switch(req) { | ||
156 | case B2C2_USB_READ_V8_MEM: | ||
157 | wMax = USB_MEM_READ_MAX; | ||
158 | break; | ||
159 | case B2C2_USB_WRITE_V8_MEM: | ||
160 | wMax = USB_MEM_WRITE_MAX; | ||
161 | break; | ||
162 | case B2C2_USB_FLASH_BLOCK: | ||
163 | wMax = USB_FLASH_MAX; | ||
164 | break; | ||
165 | default: | ||
166 | return -EINVAL; | ||
167 | break; | ||
168 | } | ||
169 | for (i = 0; i < len;) { | ||
170 | pagechunk = | ||
171 | wMax < bytes_left_to_read_on_page(addr, len) ? | ||
172 | wMax : | ||
173 | bytes_left_to_read_on_page(addr, len); | ||
174 | deb_info("%x\n", | ||
175 | (addr & V8_MEMORY_PAGE_MASK) | | ||
176 | (V8_MEMORY_EXTENDED*extended)); | ||
177 | |||
178 | ret = flexcop_usb_v8_memory_req(fc_usb, req, | ||
179 | page_start + (addr / V8_MEMORY_PAGE_SIZE), | ||
180 | (addr & V8_MEMORY_PAGE_MASK) | | ||
181 | (V8_MEMORY_EXTENDED*extended), | ||
182 | &buf[i], pagechunk); | ||
183 | |||
184 | if (ret < 0) | ||
185 | return ret; | ||
186 | addr += pagechunk; | ||
187 | len -= pagechunk; | ||
188 | } | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended) | ||
193 | { | ||
194 | return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM, | ||
195 | V8_MEMORY_PAGE_FLASH, 0x1f010, 1, | ||
196 | fc->dvb_adapter.proposed_mac, 6); | ||
197 | } | ||
198 | |||
199 | #if 0 | ||
200 | static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set, | ||
201 | flexcop_usb_utility_function_t func, u8 extra, u16 wIndex, | ||
202 | u16 buflen, u8 *pvBuffer) | ||
203 | { | ||
204 | u16 wValue; | ||
205 | u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR; | ||
206 | int nWaitTime = 2, | ||
207 | pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len; | ||
208 | wValue = (func << 8) | extra; | ||
209 | |||
210 | len = usb_control_msg(fc_usb->udev,pipe, | ||
211 | B2C2_USB_UTILITY, | ||
212 | request_type, | ||
213 | wValue, | ||
214 | wIndex, | ||
215 | pvBuffer, | ||
216 | buflen, | ||
217 | nWaitTime * HZ); | ||
218 | return len == buflen ? 0 : -EIO; | ||
219 | } | ||
220 | #endif | ||
221 | |||
222 | /* usb i2c stuff */ | ||
223 | static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, | ||
224 | flexcop_usb_request_t req, flexcop_usb_i2c_function_t func, | ||
225 | u8 chipaddr, u8 addr, u8 *buf, u8 buflen) | ||
226 | { | ||
227 | struct flexcop_usb *fc_usb = i2c->fc->bus_specific; | ||
228 | u16 wValue, wIndex; | ||
229 | int nWaitTime,pipe,len; | ||
230 | u8 request_type = USB_TYPE_VENDOR; | ||
231 | |||
232 | switch (func) { | ||
233 | case USB_FUNC_I2C_WRITE: | ||
234 | case USB_FUNC_I2C_MULTIWRITE: | ||
235 | case USB_FUNC_I2C_REPEATWRITE: | ||
236 | /* DKT 020208 - add this to support special case of DiSEqC */ | ||
237 | case USB_FUNC_I2C_CHECKWRITE: | ||
238 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
239 | nWaitTime = 2; | ||
240 | request_type |= USB_DIR_OUT; | ||
241 | break; | ||
242 | case USB_FUNC_I2C_READ: | ||
243 | case USB_FUNC_I2C_REPEATREAD: | ||
244 | pipe = B2C2_USB_CTRL_PIPE_IN; | ||
245 | nWaitTime = 2; | ||
246 | request_type |= USB_DIR_IN; | ||
247 | break; | ||
248 | default: | ||
249 | deb_info("unsupported function for i2c_req %x\n", func); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | wValue = (func << 8) | (i2c->port << 4); | ||
253 | wIndex = (chipaddr << 8 ) | addr; | ||
254 | |||
255 | deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n", | ||
256 | func, request_type, req, | ||
257 | wValue & 0xff, wValue >> 8, | ||
258 | wIndex & 0xff, wIndex >> 8); | ||
259 | |||
260 | len = usb_control_msg(fc_usb->udev,pipe, | ||
261 | req, | ||
262 | request_type, | ||
263 | wValue, | ||
264 | wIndex, | ||
265 | buf, | ||
266 | buflen, | ||
267 | nWaitTime * HZ); | ||
268 | return len == buflen ? 0 : -EREMOTEIO; | ||
269 | } | ||
270 | |||
271 | /* actual bus specific access functions, | ||
272 | make sure prototype are/will be equal to pci */ | ||
273 | static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, | ||
274 | flexcop_ibi_register reg) | ||
275 | { | ||
276 | flexcop_ibi_value val; | ||
277 | val.raw = 0; | ||
278 | flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1); | ||
279 | return val; | ||
280 | } | ||
281 | |||
282 | static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, | ||
283 | flexcop_ibi_register reg, flexcop_ibi_value val) | ||
284 | { | ||
285 | return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0); | ||
286 | } | ||
287 | |||
288 | static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c, | ||
289 | flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) | ||
290 | { | ||
291 | if (op == FC_READ) | ||
292 | return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, | ||
293 | USB_FUNC_I2C_READ, chipaddr, addr, buf, len); | ||
294 | else | ||
295 | return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, | ||
296 | USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len); | ||
297 | } | ||
298 | |||
299 | static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, | ||
300 | u8 *buffer, int buffer_length) | ||
301 | { | ||
302 | u8 *b; | ||
303 | int l; | ||
304 | |||
305 | deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", | ||
306 | fc_usb->tmp_buffer_length, buffer_length); | ||
307 | |||
308 | if (fc_usb->tmp_buffer_length > 0) { | ||
309 | memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, | ||
310 | buffer_length); | ||
311 | fc_usb->tmp_buffer_length += buffer_length; | ||
312 | b = fc_usb->tmp_buffer; | ||
313 | l = fc_usb->tmp_buffer_length; | ||
314 | } else { | ||
315 | b=buffer; | ||
316 | l=buffer_length; | ||
317 | } | ||
318 | |||
319 | while (l >= 190) { | ||
320 | if (*b == 0xff) { | ||
321 | switch (*(b+1) & 0x03) { | ||
322 | case 0x01: /* media packet */ | ||
323 | if (*(b+2) == 0x47) | ||
324 | flexcop_pass_dmx_packets( | ||
325 | fc_usb->fc_dev, b+2, 1); | ||
326 | else | ||
327 | deb_ts("not ts packet %*ph\n", 4, b+2); | ||
328 | b += 190; | ||
329 | l -= 190; | ||
330 | break; | ||
331 | default: | ||
332 | deb_ts("wrong packet type\n"); | ||
333 | l = 0; | ||
334 | break; | ||
335 | } | ||
336 | } else { | ||
337 | deb_ts("wrong header\n"); | ||
338 | l = 0; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | if (l>0) | ||
343 | memcpy(fc_usb->tmp_buffer, b, l); | ||
344 | fc_usb->tmp_buffer_length = l; | ||
345 | } | ||
346 | |||
347 | static void flexcop_usb_urb_complete(struct urb *urb) | ||
348 | { | ||
349 | struct flexcop_usb *fc_usb = urb->context; | ||
350 | int i; | ||
351 | |||
352 | if (urb->actual_length > 0) | ||
353 | deb_ts("urb completed, bufsize: %d actlen; %d\n", | ||
354 | urb->transfer_buffer_length, urb->actual_length); | ||
355 | |||
356 | for (i = 0; i < urb->number_of_packets; i++) { | ||
357 | if (urb->iso_frame_desc[i].status < 0) { | ||
358 | err("iso frame descriptor %d has an error: %d\n", i, | ||
359 | urb->iso_frame_desc[i].status); | ||
360 | } else | ||
361 | if (urb->iso_frame_desc[i].actual_length > 0) { | ||
362 | deb_ts("passed %d bytes to the demux\n", | ||
363 | urb->iso_frame_desc[i].actual_length); | ||
364 | |||
365 | flexcop_usb_process_frame(fc_usb, | ||
366 | urb->transfer_buffer + | ||
367 | urb->iso_frame_desc[i].offset, | ||
368 | urb->iso_frame_desc[i].actual_length); | ||
369 | } | ||
370 | urb->iso_frame_desc[i].status = 0; | ||
371 | urb->iso_frame_desc[i].actual_length = 0; | ||
372 | } | ||
373 | usb_submit_urb(urb,GFP_ATOMIC); | ||
374 | } | ||
375 | |||
376 | static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff) | ||
377 | { | ||
378 | /* submit/kill iso packets */ | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) | ||
383 | { | ||
384 | int i; | ||
385 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) | ||
386 | if (fc_usb->iso_urb[i] != NULL) { | ||
387 | deb_ts("unlinking/killing urb no. %d\n",i); | ||
388 | usb_kill_urb(fc_usb->iso_urb[i]); | ||
389 | usb_free_urb(fc_usb->iso_urb[i]); | ||
390 | } | ||
391 | |||
392 | if (fc_usb->iso_buffer != NULL) | ||
393 | pci_free_consistent(NULL, | ||
394 | fc_usb->buffer_size, fc_usb->iso_buffer, | ||
395 | fc_usb->dma_addr); | ||
396 | } | ||
397 | |||
398 | static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) | ||
399 | { | ||
400 | u16 frame_size = le16_to_cpu( | ||
401 | fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); | ||
402 | int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * | ||
403 | frame_size, i, j, ret; | ||
404 | int buffer_offset = 0; | ||
405 | |||
406 | deb_ts("creating %d iso-urbs with %d frames " | ||
407 | "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB, | ||
408 | B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize); | ||
409 | |||
410 | fc_usb->iso_buffer = pci_alloc_consistent(NULL, | ||
411 | bufsize, &fc_usb->dma_addr); | ||
412 | if (fc_usb->iso_buffer == NULL) | ||
413 | return -ENOMEM; | ||
414 | |||
415 | memset(fc_usb->iso_buffer, 0, bufsize); | ||
416 | fc_usb->buffer_size = bufsize; | ||
417 | |||
418 | /* creating iso urbs */ | ||
419 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { | ||
420 | fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO, | ||
421 | GFP_ATOMIC); | ||
422 | if (fc_usb->iso_urb[i] == NULL) { | ||
423 | ret = -ENOMEM; | ||
424 | goto urb_error; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | /* initialising and submitting iso urbs */ | ||
429 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { | ||
430 | int frame_offset = 0; | ||
431 | struct urb *urb = fc_usb->iso_urb[i]; | ||
432 | deb_ts("initializing and submitting urb no. %d " | ||
433 | "(buf_offset: %d).\n", i, buffer_offset); | ||
434 | |||
435 | urb->dev = fc_usb->udev; | ||
436 | urb->context = fc_usb; | ||
437 | urb->complete = flexcop_usb_urb_complete; | ||
438 | urb->pipe = B2C2_USB_DATA_PIPE; | ||
439 | urb->transfer_flags = URB_ISO_ASAP; | ||
440 | urb->interval = 1; | ||
441 | urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO; | ||
442 | urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO; | ||
443 | urb->transfer_buffer = fc_usb->iso_buffer + buffer_offset; | ||
444 | |||
445 | buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO; | ||
446 | for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) { | ||
447 | deb_ts("urb no: %d, frame: %d, frame_offset: %d\n", | ||
448 | i, j, frame_offset); | ||
449 | urb->iso_frame_desc[j].offset = frame_offset; | ||
450 | urb->iso_frame_desc[j].length = frame_size; | ||
451 | frame_offset += frame_size; | ||
452 | } | ||
453 | |||
454 | if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) { | ||
455 | err("submitting urb %d failed with %d.", i, ret); | ||
456 | goto urb_error; | ||
457 | } | ||
458 | deb_ts("submitted urb no. %d.\n",i); | ||
459 | } | ||
460 | |||
461 | /* SRAM */ | ||
462 | flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA | | ||
463 | FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, | ||
464 | FC_SRAM_DEST_TARGET_WAN_USB); | ||
465 | flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS); | ||
466 | flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1); | ||
467 | return 0; | ||
468 | |||
469 | urb_error: | ||
470 | flexcop_usb_transfer_exit(fc_usb); | ||
471 | return ret; | ||
472 | } | ||
473 | |||
474 | static int flexcop_usb_init(struct flexcop_usb *fc_usb) | ||
475 | { | ||
476 | /* use the alternate setting with the larges buffer */ | ||
477 | usb_set_interface(fc_usb->udev,0,1); | ||
478 | switch (fc_usb->udev->speed) { | ||
479 | case USB_SPEED_LOW: | ||
480 | err("cannot handle USB speed because it is too slow."); | ||
481 | return -ENODEV; | ||
482 | break; | ||
483 | case USB_SPEED_FULL: | ||
484 | info("running at FULL speed."); | ||
485 | break; | ||
486 | case USB_SPEED_HIGH: | ||
487 | info("running at HIGH speed."); | ||
488 | break; | ||
489 | case USB_SPEED_UNKNOWN: /* fall through */ | ||
490 | default: | ||
491 | err("cannot handle USB speed because it is unknown."); | ||
492 | return -ENODEV; | ||
493 | } | ||
494 | usb_set_intfdata(fc_usb->uintf, fc_usb); | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static void flexcop_usb_exit(struct flexcop_usb *fc_usb) | ||
499 | { | ||
500 | usb_set_intfdata(fc_usb->uintf, NULL); | ||
501 | } | ||
502 | |||
503 | static int flexcop_usb_probe(struct usb_interface *intf, | ||
504 | const struct usb_device_id *id) | ||
505 | { | ||
506 | struct usb_device *udev = interface_to_usbdev(intf); | ||
507 | struct flexcop_usb *fc_usb = NULL; | ||
508 | struct flexcop_device *fc = NULL; | ||
509 | int ret; | ||
510 | |||
511 | if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) { | ||
512 | err("out of memory\n"); | ||
513 | return -ENOMEM; | ||
514 | } | ||
515 | |||
516 | /* general flexcop init */ | ||
517 | fc_usb = fc->bus_specific; | ||
518 | fc_usb->fc_dev = fc; | ||
519 | |||
520 | fc->read_ibi_reg = flexcop_usb_read_ibi_reg; | ||
521 | fc->write_ibi_reg = flexcop_usb_write_ibi_reg; | ||
522 | fc->i2c_request = flexcop_usb_i2c_request; | ||
523 | fc->get_mac_addr = flexcop_usb_get_mac_addr; | ||
524 | |||
525 | fc->stream_control = flexcop_usb_stream_control; | ||
526 | |||
527 | fc->pid_filtering = 1; | ||
528 | fc->bus_type = FC_USB; | ||
529 | |||
530 | fc->dev = &udev->dev; | ||
531 | fc->owner = THIS_MODULE; | ||
532 | |||
533 | /* bus specific part */ | ||
534 | fc_usb->udev = udev; | ||
535 | fc_usb->uintf = intf; | ||
536 | if ((ret = flexcop_usb_init(fc_usb)) != 0) | ||
537 | goto err_kfree; | ||
538 | |||
539 | /* init flexcop */ | ||
540 | if ((ret = flexcop_device_initialize(fc)) != 0) | ||
541 | goto err_usb_exit; | ||
542 | |||
543 | /* xfer init */ | ||
544 | if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0) | ||
545 | goto err_fc_exit; | ||
546 | |||
547 | info("%s successfully initialized and connected.", DRIVER_NAME); | ||
548 | return 0; | ||
549 | |||
550 | err_fc_exit: | ||
551 | flexcop_device_exit(fc); | ||
552 | err_usb_exit: | ||
553 | flexcop_usb_exit(fc_usb); | ||
554 | err_kfree: | ||
555 | flexcop_device_kfree(fc); | ||
556 | return ret; | ||
557 | } | ||
558 | |||
559 | static void flexcop_usb_disconnect(struct usb_interface *intf) | ||
560 | { | ||
561 | struct flexcop_usb *fc_usb = usb_get_intfdata(intf); | ||
562 | flexcop_usb_transfer_exit(fc_usb); | ||
563 | flexcop_device_exit(fc_usb->fc_dev); | ||
564 | flexcop_usb_exit(fc_usb); | ||
565 | flexcop_device_kfree(fc_usb->fc_dev); | ||
566 | info("%s successfully deinitialized and disconnected.", DRIVER_NAME); | ||
567 | } | ||
568 | |||
569 | static struct usb_device_id flexcop_usb_table [] = { | ||
570 | { USB_DEVICE(0x0af7, 0x0101) }, | ||
571 | { } | ||
572 | }; | ||
573 | MODULE_DEVICE_TABLE (usb, flexcop_usb_table); | ||
574 | |||
575 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
576 | static struct usb_driver flexcop_usb_driver = { | ||
577 | .name = "b2c2_flexcop_usb", | ||
578 | .probe = flexcop_usb_probe, | ||
579 | .disconnect = flexcop_usb_disconnect, | ||
580 | .id_table = flexcop_usb_table, | ||
581 | }; | ||
582 | |||
583 | module_usb_driver(flexcop_usb_driver); | ||
584 | |||
585 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
586 | MODULE_DESCRIPTION(DRIVER_NAME); | ||
587 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h deleted file mode 100644 index 92529a9c4475..000000000000 --- a/drivers/media/dvb/b2c2/flexcop-usb.h +++ /dev/null | |||
@@ -1,111 +0,0 @@ | |||
1 | /* | ||
2 | * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * flexcop-usb.h - header file for the USB part | ||
4 | * see flexcop.c for copyright information | ||
5 | */ | ||
6 | #ifndef __FLEXCOP_USB_H_INCLUDED__ | ||
7 | #define __FLEXCOP_USB_H_INCLUDED__ | ||
8 | |||
9 | #include <linux/usb.h> | ||
10 | |||
11 | /* transfer parameters */ | ||
12 | #define B2C2_USB_FRAMES_PER_ISO 4 | ||
13 | #define B2C2_USB_NUM_ISO_URB 4 | ||
14 | |||
15 | #define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0) | ||
16 | #define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0) | ||
17 | #define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81) | ||
18 | |||
19 | struct flexcop_usb { | ||
20 | struct usb_device *udev; | ||
21 | struct usb_interface *uintf; | ||
22 | |||
23 | u8 *iso_buffer; | ||
24 | int buffer_size; | ||
25 | dma_addr_t dma_addr; | ||
26 | |||
27 | struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; | ||
28 | struct flexcop_device *fc_dev; | ||
29 | |||
30 | u8 tmp_buffer[1023+190]; | ||
31 | int tmp_buffer_length; | ||
32 | }; | ||
33 | |||
34 | #if 0 | ||
35 | /* request types TODO What is its use?*/ | ||
36 | typedef enum { | ||
37 | |||
38 | } flexcop_usb_request_type_t; | ||
39 | #endif | ||
40 | |||
41 | /* request */ | ||
42 | typedef enum { | ||
43 | B2C2_USB_WRITE_V8_MEM = 0x04, | ||
44 | B2C2_USB_READ_V8_MEM = 0x05, | ||
45 | B2C2_USB_READ_REG = 0x08, | ||
46 | B2C2_USB_WRITE_REG = 0x0A, | ||
47 | B2C2_USB_WRITEREGHI = 0x0B, | ||
48 | B2C2_USB_FLASH_BLOCK = 0x10, | ||
49 | B2C2_USB_I2C_REQUEST = 0x11, | ||
50 | B2C2_USB_UTILITY = 0x12, | ||
51 | } flexcop_usb_request_t; | ||
52 | |||
53 | /* function definition for I2C_REQUEST */ | ||
54 | typedef enum { | ||
55 | USB_FUNC_I2C_WRITE = 0x01, | ||
56 | USB_FUNC_I2C_MULTIWRITE = 0x02, | ||
57 | USB_FUNC_I2C_READ = 0x03, | ||
58 | USB_FUNC_I2C_REPEATWRITE = 0x04, | ||
59 | USB_FUNC_GET_DESCRIPTOR = 0x05, | ||
60 | USB_FUNC_I2C_REPEATREAD = 0x06, | ||
61 | /* DKT 020208 - add this to support special case of DiSEqC */ | ||
62 | USB_FUNC_I2C_CHECKWRITE = 0x07, | ||
63 | USB_FUNC_I2C_CHECKRESULT = 0x08, | ||
64 | } flexcop_usb_i2c_function_t; | ||
65 | |||
66 | /* function definition for UTILITY request 0x12 | ||
67 | * DKT 020304 - new utility function */ | ||
68 | typedef enum { | ||
69 | UTILITY_SET_FILTER = 0x01, | ||
70 | UTILITY_DATA_ENABLE = 0x02, | ||
71 | UTILITY_FLEX_MULTIWRITE = 0x03, | ||
72 | UTILITY_SET_BUFFER_SIZE = 0x04, | ||
73 | UTILITY_FLEX_OPERATOR = 0x05, | ||
74 | UTILITY_FLEX_RESET300_START = 0x06, | ||
75 | UTILITY_FLEX_RESET300_STOP = 0x07, | ||
76 | UTILITY_FLEX_RESET300 = 0x08, | ||
77 | UTILITY_SET_ISO_SIZE = 0x09, | ||
78 | UTILITY_DATA_RESET = 0x0A, | ||
79 | UTILITY_GET_DATA_STATUS = 0x10, | ||
80 | UTILITY_GET_V8_REG = 0x11, | ||
81 | /* DKT 020326 - add function for v1.14 */ | ||
82 | UTILITY_SRAM_WRITE = 0x12, | ||
83 | UTILITY_SRAM_READ = 0x13, | ||
84 | UTILITY_SRAM_TESTFILL = 0x14, | ||
85 | UTILITY_SRAM_TESTSET = 0x15, | ||
86 | UTILITY_SRAM_TESTVERIFY = 0x16, | ||
87 | } flexcop_usb_utility_function_t; | ||
88 | |||
89 | #define B2C2_WAIT_FOR_OPERATION_RW (1*HZ) | ||
90 | #define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ) | ||
91 | #define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ) | ||
92 | |||
93 | #define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ) | ||
94 | #define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ) | ||
95 | #define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ) | ||
96 | |||
97 | typedef enum { | ||
98 | V8_MEMORY_PAGE_DVB_CI = 0x20, | ||
99 | V8_MEMORY_PAGE_DVB_DS = 0x40, | ||
100 | V8_MEMORY_PAGE_MULTI2 = 0x60, | ||
101 | V8_MEMORY_PAGE_FLASH = 0x80 | ||
102 | } flexcop_usb_mem_page_t; | ||
103 | |||
104 | #define V8_MEMORY_EXTENDED (1 << 15) | ||
105 | #define USB_MEM_READ_MAX 32 | ||
106 | #define USB_MEM_WRITE_MAX 1 | ||
107 | #define USB_FLASH_MAX 8 | ||
108 | #define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */ | ||
109 | #define V8_MEMORY_PAGE_MASK 0x7FFF | ||
110 | |||
111 | #endif | ||
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c deleted file mode 100644 index b1e8c99f469b..000000000000 --- a/drivers/media/dvb/b2c2/flexcop.c +++ /dev/null | |||
@@ -1,324 +0,0 @@ | |||
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/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h deleted file mode 100644 index 897b10c85ad9..000000000000 --- a/drivers/media/dvb/b2c2/flexcop.h +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
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/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h deleted file mode 100644 index 8f64bdbd72bb..000000000000 --- a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h +++ /dev/null | |||
@@ -1,455 +0,0 @@ | |||
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/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h deleted file mode 100644 index c75830d7d942..000000000000 --- a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h +++ /dev/null | |||
@@ -1,455 +0,0 @@ | |||
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 | ||
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig deleted file mode 100644 index 8668e634c7ec..000000000000 --- a/drivers/media/dvb/bt8xx/Kconfig +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | config DVB_BT8XX | ||
2 | tristate "BT8xx based PCI cards" | ||
3 | depends on DVB_CORE && PCI && I2C && VIDEO_BT848 | ||
4 | select DVB_MT352 if !DVB_FE_CUSTOMISE | ||
5 | select DVB_SP887X if !DVB_FE_CUSTOMISE | ||
6 | select DVB_NXT6000 if !DVB_FE_CUSTOMISE | ||
7 | select DVB_CX24110 if !DVB_FE_CUSTOMISE | ||
8 | select DVB_OR51211 if !DVB_FE_CUSTOMISE | ||
9 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | ||
10 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
11 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE | ||
12 | help | ||
13 | Support for PCI cards based on the Bt8xx PCI bridge. Examples are | ||
14 | the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, | ||
15 | the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and | ||
16 | some AVerMedia cards. | ||
17 | |||
18 | Since these cards have no MPEG decoder onboard, they transmit | ||
19 | only compressed MPEG data over the PCI bus, so you need | ||
20 | an external software decoder to watch TV on your computer. | ||
21 | |||
22 | Say Y if you own such a device and want to use it. | ||
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile deleted file mode 100644 index 36591ae505f4..000000000000 --- a/drivers/media/dvb/bt8xx/Makefile +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o | ||
2 | |||
3 | ccflags-y += -Idrivers/media/dvb-core | ||
4 | ccflags-y += -Idrivers/media/dvb-frontends | ||
5 | ccflags-y += -Idrivers/media/video/bt8xx | ||
6 | ccflags-y += -Idrivers/media/common/tuners | ||
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c deleted file mode 100644 index b34fa95185e4..000000000000 --- a/drivers/media/dvb/bt8xx/bt878.c +++ /dev/null | |||
@@ -1,609 +0,0 @@ | |||
1 | /* | ||
2 | * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card | ||
3 | * | ||
4 | * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> | ||
5 | * | ||
6 | * large parts based on the bttv driver | ||
7 | * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de) | ||
8 | * & Marcus Metzler (mocm@metzlerbros.de) | ||
9 | * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | |||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | |||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
26 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <linux/ioport.h> | ||
35 | #include <asm/pgtable.h> | ||
36 | #include <asm/page.h> | ||
37 | #include <linux/types.h> | ||
38 | #include <linux/interrupt.h> | ||
39 | #include <linux/kmod.h> | ||
40 | #include <linux/vmalloc.h> | ||
41 | #include <linux/init.h> | ||
42 | |||
43 | #include "dmxdev.h" | ||
44 | #include "dvbdev.h" | ||
45 | #include "bt878.h" | ||
46 | #include "dst_priv.h" | ||
47 | |||
48 | |||
49 | /**************************************/ | ||
50 | /* Miscellaneous utility definitions */ | ||
51 | /**************************************/ | ||
52 | |||
53 | static unsigned int bt878_verbose = 1; | ||
54 | static unsigned int bt878_debug; | ||
55 | |||
56 | module_param_named(verbose, bt878_verbose, int, 0444); | ||
57 | MODULE_PARM_DESC(verbose, | ||
58 | "verbose startup messages, default is 1 (yes)"); | ||
59 | module_param_named(debug, bt878_debug, int, 0644); | ||
60 | MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off)."); | ||
61 | |||
62 | int bt878_num; | ||
63 | struct bt878 bt878[BT878_MAX]; | ||
64 | |||
65 | EXPORT_SYMBOL(bt878_num); | ||
66 | EXPORT_SYMBOL(bt878); | ||
67 | |||
68 | #define btwrite(dat,adr) bmtwrite((dat), (bt->bt878_mem+(adr))) | ||
69 | #define btread(adr) bmtread(bt->bt878_mem+(adr)) | ||
70 | |||
71 | #define btand(dat,adr) btwrite((dat) & btread(adr), adr) | ||
72 | #define btor(dat,adr) btwrite((dat) | btread(adr), adr) | ||
73 | #define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) | ||
74 | |||
75 | #if defined(dprintk) | ||
76 | #undef dprintk | ||
77 | #endif | ||
78 | #define dprintk(fmt, arg...) \ | ||
79 | do { \ | ||
80 | if (bt878_debug) \ | ||
81 | printk(KERN_DEBUG fmt, ##arg); \ | ||
82 | } while (0) | ||
83 | |||
84 | static void bt878_mem_free(struct bt878 *bt) | ||
85 | { | ||
86 | if (bt->buf_cpu) { | ||
87 | pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu, | ||
88 | bt->buf_dma); | ||
89 | bt->buf_cpu = NULL; | ||
90 | } | ||
91 | |||
92 | if (bt->risc_cpu) { | ||
93 | pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu, | ||
94 | bt->risc_dma); | ||
95 | bt->risc_cpu = NULL; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | static int bt878_mem_alloc(struct bt878 *bt) | ||
100 | { | ||
101 | if (!bt->buf_cpu) { | ||
102 | bt->buf_size = 128 * 1024; | ||
103 | |||
104 | bt->buf_cpu = | ||
105 | pci_alloc_consistent(bt->dev, bt->buf_size, | ||
106 | &bt->buf_dma); | ||
107 | |||
108 | if (!bt->buf_cpu) | ||
109 | return -ENOMEM; | ||
110 | |||
111 | memset(bt->buf_cpu, 0, bt->buf_size); | ||
112 | } | ||
113 | |||
114 | if (!bt->risc_cpu) { | ||
115 | bt->risc_size = PAGE_SIZE; | ||
116 | bt->risc_cpu = | ||
117 | pci_alloc_consistent(bt->dev, bt->risc_size, | ||
118 | &bt->risc_dma); | ||
119 | |||
120 | if (!bt->risc_cpu) { | ||
121 | bt878_mem_free(bt); | ||
122 | return -ENOMEM; | ||
123 | } | ||
124 | |||
125 | memset(bt->risc_cpu, 0, bt->risc_size); | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /* RISC instructions */ | ||
132 | #define RISC_WRITE (0x01 << 28) | ||
133 | #define RISC_JUMP (0x07 << 28) | ||
134 | #define RISC_SYNC (0x08 << 28) | ||
135 | |||
136 | /* RISC bits */ | ||
137 | #define RISC_WR_SOL (1 << 27) | ||
138 | #define RISC_WR_EOL (1 << 26) | ||
139 | #define RISC_IRQ (1 << 24) | ||
140 | #define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16)) | ||
141 | #define RISC_SYNC_RESYNC (1 << 15) | ||
142 | #define RISC_SYNC_FM1 0x06 | ||
143 | #define RISC_SYNC_VRO 0x0C | ||
144 | |||
145 | #define RISC_FLUSH() bt->risc_pos = 0 | ||
146 | #define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr) | ||
147 | |||
148 | static int bt878_make_risc(struct bt878 *bt) | ||
149 | { | ||
150 | bt->block_bytes = bt->buf_size >> 4; | ||
151 | bt->block_count = 1 << 4; | ||
152 | bt->line_bytes = bt->block_bytes; | ||
153 | bt->line_count = bt->block_count; | ||
154 | |||
155 | while (bt->line_bytes > 4095) { | ||
156 | bt->line_bytes >>= 1; | ||
157 | bt->line_count <<= 1; | ||
158 | } | ||
159 | |||
160 | if (bt->line_count > 255) { | ||
161 | printk(KERN_ERR "bt878: buffer size error!\n"); | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | |||
168 | static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin) | ||
169 | { | ||
170 | u32 buf_pos = 0; | ||
171 | u32 line; | ||
172 | |||
173 | RISC_FLUSH(); | ||
174 | RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin); | ||
175 | RISC_INSTR(0); | ||
176 | |||
177 | dprintk("bt878: risc len lines %u, bytes per line %u\n", | ||
178 | bt->line_count, bt->line_bytes); | ||
179 | for (line = 0; line < bt->line_count; line++) { | ||
180 | // At the beginning of every block we issue an IRQ with previous (finished) block number set | ||
181 | if (!(buf_pos % bt->block_bytes)) | ||
182 | RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | | ||
183 | RISC_IRQ | | ||
184 | RISC_STATUS(((buf_pos / | ||
185 | bt->block_bytes) + | ||
186 | (bt->block_count - | ||
187 | 1)) % | ||
188 | bt->block_count) | bt-> | ||
189 | line_bytes); | ||
190 | else | ||
191 | RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | | ||
192 | bt->line_bytes); | ||
193 | RISC_INSTR(bt->buf_dma + buf_pos); | ||
194 | buf_pos += bt->line_bytes; | ||
195 | } | ||
196 | |||
197 | RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO); | ||
198 | RISC_INSTR(0); | ||
199 | |||
200 | RISC_INSTR(RISC_JUMP); | ||
201 | RISC_INSTR(bt->risc_dma); | ||
202 | |||
203 | btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN); | ||
204 | } | ||
205 | |||
206 | /*****************************/ | ||
207 | /* Start/Stop grabbing funcs */ | ||
208 | /*****************************/ | ||
209 | |||
210 | void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, | ||
211 | u32 irq_err_ignore) | ||
212 | { | ||
213 | u32 int_mask; | ||
214 | |||
215 | dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg); | ||
216 | /* complete the writing of the risc dma program now we have | ||
217 | * the card specifics | ||
218 | */ | ||
219 | bt878_risc_program(bt, op_sync_orin); | ||
220 | controlreg &= ~0x1f; | ||
221 | controlreg |= 0x1b; | ||
222 | |||
223 | btwrite(bt->risc_dma, BT878_ARISC_START); | ||
224 | |||
225 | /* original int mask had : | ||
226 | * 6 2 8 4 0 | ||
227 | * 1111 1111 1000 0000 0000 | ||
228 | * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI | ||
229 | * Hacked for DST to: | ||
230 | * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI | ||
231 | */ | ||
232 | int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | | ||
233 | BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | | ||
234 | BT878_AFBUS | BT878_ARISCI; | ||
235 | |||
236 | |||
237 | /* ignore pesky bits */ | ||
238 | int_mask &= ~irq_err_ignore; | ||
239 | |||
240 | btwrite(int_mask, BT878_AINT_MASK); | ||
241 | btwrite(controlreg, BT878_AGPIO_DMA_CTL); | ||
242 | } | ||
243 | |||
244 | void bt878_stop(struct bt878 *bt) | ||
245 | { | ||
246 | u32 stat; | ||
247 | int i = 0; | ||
248 | |||
249 | dprintk("bt878 debug: bt878_stop\n"); | ||
250 | |||
251 | btwrite(0, BT878_AINT_MASK); | ||
252 | btand(~0x13, BT878_AGPIO_DMA_CTL); | ||
253 | |||
254 | do { | ||
255 | stat = btread(BT878_AINT_STAT); | ||
256 | if (!(stat & BT878_ARISC_EN)) | ||
257 | break; | ||
258 | i++; | ||
259 | } while (i < 500); | ||
260 | |||
261 | dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n", | ||
262 | bt->nr, i, stat); | ||
263 | } | ||
264 | |||
265 | EXPORT_SYMBOL(bt878_start); | ||
266 | EXPORT_SYMBOL(bt878_stop); | ||
267 | |||
268 | /*****************************/ | ||
269 | /* Interrupt service routine */ | ||
270 | /*****************************/ | ||
271 | |||
272 | static irqreturn_t bt878_irq(int irq, void *dev_id) | ||
273 | { | ||
274 | u32 stat, astat, mask; | ||
275 | int count; | ||
276 | struct bt878 *bt; | ||
277 | |||
278 | bt = (struct bt878 *) dev_id; | ||
279 | |||
280 | count = 0; | ||
281 | while (1) { | ||
282 | stat = btread(BT878_AINT_STAT); | ||
283 | mask = btread(BT878_AINT_MASK); | ||
284 | if (!(astat = (stat & mask))) | ||
285 | return IRQ_NONE; /* this interrupt is not for me */ | ||
286 | /* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */ | ||
287 | btwrite(astat, BT878_AINT_STAT); /* try to clear interrupt condition */ | ||
288 | |||
289 | |||
290 | if (astat & (BT878_ASCERR | BT878_AOCERR)) { | ||
291 | if (bt878_verbose) { | ||
292 | printk(KERN_INFO | ||
293 | "bt878(%d): irq%s%s risc_pc=%08x\n", | ||
294 | bt->nr, | ||
295 | (astat & BT878_ASCERR) ? " SCERR" : | ||
296 | "", | ||
297 | (astat & BT878_AOCERR) ? " OCERR" : | ||
298 | "", btread(BT878_ARISC_PC)); | ||
299 | } | ||
300 | } | ||
301 | if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) { | ||
302 | if (bt878_verbose) { | ||
303 | printk(KERN_INFO | ||
304 | "bt878(%d): irq%s%s%s risc_pc=%08x\n", | ||
305 | bt->nr, | ||
306 | (astat & BT878_APABORT) ? " PABORT" : | ||
307 | "", | ||
308 | (astat & BT878_ARIPERR) ? " RIPERR" : | ||
309 | "", | ||
310 | (astat & BT878_APPERR) ? " PPERR" : | ||
311 | "", btread(BT878_ARISC_PC)); | ||
312 | } | ||
313 | } | ||
314 | if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) { | ||
315 | if (bt878_verbose) { | ||
316 | printk(KERN_INFO | ||
317 | "bt878(%d): irq%s%s%s risc_pc=%08x\n", | ||
318 | bt->nr, | ||
319 | (astat & BT878_AFDSR) ? " FDSR" : "", | ||
320 | (astat & BT878_AFTRGT) ? " FTRGT" : | ||
321 | "", | ||
322 | (astat & BT878_AFBUS) ? " FBUS" : "", | ||
323 | btread(BT878_ARISC_PC)); | ||
324 | } | ||
325 | } | ||
326 | if (astat & BT878_ARISCI) { | ||
327 | bt->finished_block = (stat & BT878_ARISCS) >> 28; | ||
328 | tasklet_schedule(&bt->tasklet); | ||
329 | break; | ||
330 | } | ||
331 | count++; | ||
332 | if (count > 20) { | ||
333 | btwrite(0, BT878_AINT_MASK); | ||
334 | printk(KERN_ERR | ||
335 | "bt878(%d): IRQ lockup, cleared int mask\n", | ||
336 | bt->nr); | ||
337 | break; | ||
338 | } | ||
339 | } | ||
340 | return IRQ_HANDLED; | ||
341 | } | ||
342 | |||
343 | int | ||
344 | bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp) | ||
345 | { | ||
346 | int retval; | ||
347 | |||
348 | retval = 0; | ||
349 | if (mutex_lock_interruptible(&bt->gpio_lock)) | ||
350 | return -ERESTARTSYS; | ||
351 | /* special gpio signal */ | ||
352 | switch (cmd) { | ||
353 | case DST_IG_ENABLE: | ||
354 | // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable); | ||
355 | retval = bttv_gpio_enable(bt->bttv_nr, | ||
356 | mp->enb.mask, | ||
357 | mp->enb.enable); | ||
358 | break; | ||
359 | case DST_IG_WRITE: | ||
360 | // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals); | ||
361 | retval = bttv_write_gpio(bt->bttv_nr, | ||
362 | mp->outp.mask, | ||
363 | mp->outp.highvals); | ||
364 | |||
365 | break; | ||
366 | case DST_IG_READ: | ||
367 | /* read */ | ||
368 | retval = bttv_read_gpio(bt->bttv_nr, &mp->rd.value); | ||
369 | // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value); | ||
370 | break; | ||
371 | case DST_IG_TS: | ||
372 | /* Set packet size */ | ||
373 | bt->TS_Size = mp->psize; | ||
374 | break; | ||
375 | |||
376 | default: | ||
377 | retval = -EINVAL; | ||
378 | break; | ||
379 | } | ||
380 | mutex_unlock(&bt->gpio_lock); | ||
381 | return retval; | ||
382 | } | ||
383 | |||
384 | EXPORT_SYMBOL(bt878_device_control); | ||
385 | |||
386 | #define BROOKTREE_878_DEVICE(vend, dev, name) \ | ||
387 | { \ | ||
388 | .vendor = PCI_VENDOR_ID_BROOKTREE, \ | ||
389 | .device = PCI_DEVICE_ID_BROOKTREE_878, \ | ||
390 | .subvendor = (vend), .subdevice = (dev), \ | ||
391 | .driver_data = (unsigned long) name \ | ||
392 | } | ||
393 | |||
394 | static struct pci_device_id bt878_pci_tbl[] __devinitdata = { | ||
395 | BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"), | ||
396 | BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"), | ||
397 | BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"), | ||
398 | BROOKTREE_878_DEVICE(0x11bd, 0x0026, "Pinnacle PCTV SAT CI"), | ||
399 | BROOKTREE_878_DEVICE(0x1822, 0x0001, "Twinhan VisionPlus DVB"), | ||
400 | BROOKTREE_878_DEVICE(0x270f, 0xfc00, | ||
401 | "ChainTech digitop DST-1000 DVB-S"), | ||
402 | BROOKTREE_878_DEVICE(0x1461, 0x0771, "AVermedia AverTV DVB-T 771"), | ||
403 | BROOKTREE_878_DEVICE(0x18ac, 0xdb10, "DViCO FusionHDTV DVB-T Lite"), | ||
404 | BROOKTREE_878_DEVICE(0x18ac, 0xdb11, "Ultraview DVB-T Lite"), | ||
405 | BROOKTREE_878_DEVICE(0x18ac, 0xd500, "DViCO FusionHDTV 5 Lite"), | ||
406 | BROOKTREE_878_DEVICE(0x7063, 0x2000, "pcHDTV HD-2000 TV"), | ||
407 | BROOKTREE_878_DEVICE(0x1822, 0x0026, "DNTV Live! Mini"), | ||
408 | { } | ||
409 | }; | ||
410 | |||
411 | MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); | ||
412 | |||
413 | static const char * __devinit card_name(const struct pci_device_id *id) | ||
414 | { | ||
415 | return id->driver_data ? (const char *)id->driver_data : "Unknown"; | ||
416 | } | ||
417 | |||
418 | /***********************/ | ||
419 | /* PCI device handling */ | ||
420 | /***********************/ | ||
421 | |||
422 | static int __devinit bt878_probe(struct pci_dev *dev, | ||
423 | const struct pci_device_id *pci_id) | ||
424 | { | ||
425 | int result = 0; | ||
426 | unsigned char lat; | ||
427 | struct bt878 *bt; | ||
428 | #if defined(__powerpc__) | ||
429 | unsigned int cmd; | ||
430 | #endif | ||
431 | unsigned int cardid; | ||
432 | |||
433 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", | ||
434 | bt878_num); | ||
435 | if (bt878_num >= BT878_MAX) { | ||
436 | printk(KERN_ERR "bt878: Too many devices inserted\n"); | ||
437 | result = -ENOMEM; | ||
438 | goto fail0; | ||
439 | } | ||
440 | if (pci_enable_device(dev)) | ||
441 | return -EIO; | ||
442 | |||
443 | cardid = dev->subsystem_device << 16; | ||
444 | cardid |= dev->subsystem_vendor; | ||
445 | |||
446 | printk(KERN_INFO "%s: card id=[0x%x],[ %s ] has DVB functions.\n", | ||
447 | __func__, cardid, card_name(pci_id)); | ||
448 | |||
449 | bt = &bt878[bt878_num]; | ||
450 | bt->dev = dev; | ||
451 | bt->nr = bt878_num; | ||
452 | bt->shutdown = 0; | ||
453 | |||
454 | bt->id = dev->device; | ||
455 | bt->irq = dev->irq; | ||
456 | bt->bt878_adr = pci_resource_start(dev, 0); | ||
457 | if (!request_mem_region(pci_resource_start(dev, 0), | ||
458 | pci_resource_len(dev, 0), "bt878")) { | ||
459 | result = -EBUSY; | ||
460 | goto fail0; | ||
461 | } | ||
462 | |||
463 | bt->revision = dev->revision; | ||
464 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | ||
465 | |||
466 | |||
467 | printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ", | ||
468 | bt878_num, bt->id, bt->revision, dev->bus->number, | ||
469 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | ||
470 | printk("irq: %d, latency: %d, memory: 0x%lx\n", | ||
471 | bt->irq, lat, bt->bt878_adr); | ||
472 | |||
473 | |||
474 | #if defined(__powerpc__) | ||
475 | /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */ | ||
476 | /* response on cards with no firmware is not enabled by OF */ | ||
477 | pci_read_config_dword(dev, PCI_COMMAND, &cmd); | ||
478 | cmd = (cmd | PCI_COMMAND_MEMORY); | ||
479 | pci_write_config_dword(dev, PCI_COMMAND, cmd); | ||
480 | #endif | ||
481 | |||
482 | #ifdef __sparc__ | ||
483 | bt->bt878_mem = (unsigned char *) bt->bt878_adr; | ||
484 | #else | ||
485 | bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000); | ||
486 | #endif | ||
487 | |||
488 | /* clear interrupt mask */ | ||
489 | btwrite(0, BT848_INT_MASK); | ||
490 | |||
491 | result = request_irq(bt->irq, bt878_irq, | ||
492 | IRQF_SHARED | IRQF_DISABLED, "bt878", | ||
493 | (void *) bt); | ||
494 | if (result == -EINVAL) { | ||
495 | printk(KERN_ERR "bt878(%d): Bad irq number or handler\n", | ||
496 | bt878_num); | ||
497 | goto fail1; | ||
498 | } | ||
499 | if (result == -EBUSY) { | ||
500 | printk(KERN_ERR | ||
501 | "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n", | ||
502 | bt878_num, bt->irq); | ||
503 | goto fail1; | ||
504 | } | ||
505 | if (result < 0) | ||
506 | goto fail1; | ||
507 | |||
508 | pci_set_master(dev); | ||
509 | pci_set_drvdata(dev, bt); | ||
510 | |||
511 | if ((result = bt878_mem_alloc(bt))) { | ||
512 | printk(KERN_ERR "bt878: failed to allocate memory!\n"); | ||
513 | goto fail2; | ||
514 | } | ||
515 | |||
516 | bt878_make_risc(bt); | ||
517 | btwrite(0, BT878_AINT_MASK); | ||
518 | bt878_num++; | ||
519 | |||
520 | return 0; | ||
521 | |||
522 | fail2: | ||
523 | free_irq(bt->irq, bt); | ||
524 | fail1: | ||
525 | release_mem_region(pci_resource_start(bt->dev, 0), | ||
526 | pci_resource_len(bt->dev, 0)); | ||
527 | fail0: | ||
528 | pci_disable_device(dev); | ||
529 | return result; | ||
530 | } | ||
531 | |||
532 | static void __devexit bt878_remove(struct pci_dev *pci_dev) | ||
533 | { | ||
534 | u8 command; | ||
535 | struct bt878 *bt = pci_get_drvdata(pci_dev); | ||
536 | |||
537 | if (bt878_verbose) | ||
538 | printk(KERN_INFO "bt878(%d): unloading\n", bt->nr); | ||
539 | |||
540 | /* turn off all capturing, DMA and IRQs */ | ||
541 | btand(~0x13, BT878_AGPIO_DMA_CTL); | ||
542 | |||
543 | /* first disable interrupts before unmapping the memory! */ | ||
544 | btwrite(0, BT878_AINT_MASK); | ||
545 | btwrite(~0U, BT878_AINT_STAT); | ||
546 | |||
547 | /* disable PCI bus-mastering */ | ||
548 | pci_read_config_byte(bt->dev, PCI_COMMAND, &command); | ||
549 | /* Should this be &=~ ?? */ | ||
550 | command &= ~PCI_COMMAND_MASTER; | ||
551 | pci_write_config_byte(bt->dev, PCI_COMMAND, command); | ||
552 | |||
553 | free_irq(bt->irq, bt); | ||
554 | printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem); | ||
555 | if (bt->bt878_mem) | ||
556 | iounmap(bt->bt878_mem); | ||
557 | |||
558 | release_mem_region(pci_resource_start(bt->dev, 0), | ||
559 | pci_resource_len(bt->dev, 0)); | ||
560 | /* wake up any waiting processes | ||
561 | because shutdown flag is set, no new processes (in this queue) | ||
562 | are expected | ||
563 | */ | ||
564 | bt->shutdown = 1; | ||
565 | bt878_mem_free(bt); | ||
566 | |||
567 | pci_set_drvdata(pci_dev, NULL); | ||
568 | pci_disable_device(pci_dev); | ||
569 | return; | ||
570 | } | ||
571 | |||
572 | static struct pci_driver bt878_pci_driver = { | ||
573 | .name = "bt878", | ||
574 | .id_table = bt878_pci_tbl, | ||
575 | .probe = bt878_probe, | ||
576 | .remove = __devexit_p(bt878_remove), | ||
577 | }; | ||
578 | |||
579 | /*******************************/ | ||
580 | /* Module management functions */ | ||
581 | /*******************************/ | ||
582 | |||
583 | static int __init bt878_init_module(void) | ||
584 | { | ||
585 | bt878_num = 0; | ||
586 | |||
587 | printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n", | ||
588 | (BT878_VERSION_CODE >> 16) & 0xff, | ||
589 | (BT878_VERSION_CODE >> 8) & 0xff, | ||
590 | BT878_VERSION_CODE & 0xff); | ||
591 | |||
592 | return pci_register_driver(&bt878_pci_driver); | ||
593 | } | ||
594 | |||
595 | static void __exit bt878_cleanup_module(void) | ||
596 | { | ||
597 | pci_unregister_driver(&bt878_pci_driver); | ||
598 | } | ||
599 | |||
600 | module_init(bt878_init_module); | ||
601 | module_exit(bt878_cleanup_module); | ||
602 | |||
603 | MODULE_LICENSE("GPL"); | ||
604 | |||
605 | /* | ||
606 | * Local variables: | ||
607 | * c-basic-offset: 8 | ||
608 | * End: | ||
609 | */ | ||
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h deleted file mode 100644 index d19b59299d78..000000000000 --- a/drivers/media/dvb/bt8xx/bt878.h +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | /* | ||
2 | bt878.h - Bt878 audio module (register offsets) | ||
3 | |||
4 | Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef _BT878_H_ | ||
22 | #define _BT878_H_ | ||
23 | |||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/mutex.h> | ||
29 | |||
30 | #include "bt848.h" | ||
31 | #include "bttv.h" | ||
32 | |||
33 | #define BT878_VERSION_CODE 0x000000 | ||
34 | |||
35 | #define BT878_AINT_STAT 0x100 | ||
36 | #define BT878_ARISCS (0xf<<28) | ||
37 | #define BT878_ARISC_EN (1<<27) | ||
38 | #define BT878_ASCERR (1<<19) | ||
39 | #define BT878_AOCERR (1<<18) | ||
40 | #define BT878_APABORT (1<<17) | ||
41 | #define BT878_ARIPERR (1<<16) | ||
42 | #define BT878_APPERR (1<<15) | ||
43 | #define BT878_AFDSR (1<<14) | ||
44 | #define BT878_AFTRGT (1<<13) | ||
45 | #define BT878_AFBUS (1<<12) | ||
46 | #define BT878_ARISCI (1<<11) | ||
47 | #define BT878_AOFLOW (1<<3) | ||
48 | |||
49 | #define BT878_AINT_MASK 0x104 | ||
50 | |||
51 | #define BT878_AGPIO_DMA_CTL 0x10c | ||
52 | #define BT878_A_GAIN (0xf<<28) | ||
53 | #define BT878_A_G2X (1<<27) | ||
54 | #define BT878_A_PWRDN (1<<26) | ||
55 | #define BT878_A_SEL (3<<24) | ||
56 | #define BT878_DA_SCE (1<<23) | ||
57 | #define BT878_DA_LRI (1<<22) | ||
58 | #define BT878_DA_MLB (1<<21) | ||
59 | #define BT878_DA_LRD (0x1f<<16) | ||
60 | #define BT878_DA_DPM (1<<15) | ||
61 | #define BT878_DA_SBR (1<<14) | ||
62 | #define BT878_DA_ES2 (1<<13) | ||
63 | #define BT878_DA_LMT (1<<12) | ||
64 | #define BT878_DA_SDR (0xf<<8) | ||
65 | #define BT878_DA_IOM (3<<6) | ||
66 | #define BT878_DA_APP (1<<5) | ||
67 | #define BT878_ACAP_EN (1<<4) | ||
68 | #define BT878_PKTP (3<<2) | ||
69 | #define BT878_RISC_EN (1<<1) | ||
70 | #define BT878_FIFO_EN 1 | ||
71 | |||
72 | #define BT878_APACK_LEN 0x110 | ||
73 | #define BT878_AFP_LEN (0xff<<16) | ||
74 | #define BT878_ALP_LEN 0xfff | ||
75 | |||
76 | #define BT878_ARISC_START 0x114 | ||
77 | |||
78 | #define BT878_ARISC_PC 0x120 | ||
79 | |||
80 | /* BT878 FUNCTION 0 REGISTERS */ | ||
81 | #define BT878_GPIO_DMA_CTL 0x10c | ||
82 | |||
83 | /* Interrupt register */ | ||
84 | #define BT878_INT_STAT 0x100 | ||
85 | #define BT878_INT_MASK 0x104 | ||
86 | #define BT878_I2CRACK (1<<25) | ||
87 | #define BT878_I2CDONE (1<<8) | ||
88 | |||
89 | #define BT878_MAX 4 | ||
90 | |||
91 | #define BT878_RISC_SYNC_MASK (1 << 15) | ||
92 | |||
93 | |||
94 | #define BTTV_BOARD_UNKNOWN 0x00 | ||
95 | #define BTTV_BOARD_PINNACLESAT 0x5e | ||
96 | #define BTTV_BOARD_NEBULA_DIGITV 0x68 | ||
97 | #define BTTV_BOARD_PC_HDTV 0x70 | ||
98 | #define BTTV_BOARD_TWINHAN_DST 0x71 | ||
99 | #define BTTV_BOARD_AVDVBT_771 0x7b | ||
100 | #define BTTV_BOARD_AVDVBT_761 0x7c | ||
101 | #define BTTV_BOARD_DVICO_DVBT_LITE 0x80 | ||
102 | #define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 | ||
103 | |||
104 | extern int bt878_num; | ||
105 | |||
106 | struct bt878 { | ||
107 | struct mutex gpio_lock; | ||
108 | unsigned int nr; | ||
109 | unsigned int bttv_nr; | ||
110 | struct i2c_adapter *adapter; | ||
111 | struct pci_dev *dev; | ||
112 | unsigned int id; | ||
113 | unsigned int TS_Size; | ||
114 | unsigned char revision; | ||
115 | unsigned int irq; | ||
116 | unsigned long bt878_adr; | ||
117 | volatile void __iomem *bt878_mem; /* function 1 */ | ||
118 | |||
119 | volatile u32 finished_block; | ||
120 | volatile u32 last_block; | ||
121 | u32 block_count; | ||
122 | u32 block_bytes; | ||
123 | u32 line_bytes; | ||
124 | u32 line_count; | ||
125 | |||
126 | u32 buf_size; | ||
127 | u8 *buf_cpu; | ||
128 | dma_addr_t buf_dma; | ||
129 | |||
130 | u32 risc_size; | ||
131 | __le32 *risc_cpu; | ||
132 | dma_addr_t risc_dma; | ||
133 | u32 risc_pos; | ||
134 | |||
135 | struct tasklet_struct tasklet; | ||
136 | int shutdown; | ||
137 | }; | ||
138 | |||
139 | extern struct bt878 bt878[BT878_MAX]; | ||
140 | |||
141 | void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, | ||
142 | u32 irq_err_ignore); | ||
143 | void bt878_stop(struct bt878 *bt); | ||
144 | |||
145 | #if defined(__powerpc__) /* big-endian */ | ||
146 | static inline void io_st_le32(volatile unsigned __iomem *addr, unsigned val) | ||
147 | { | ||
148 | st_le32(addr, val); | ||
149 | eieio(); | ||
150 | } | ||
151 | |||
152 | #define bmtwrite(dat,adr) io_st_le32((adr),(dat)) | ||
153 | #define bmtread(adr) ld_le32((adr)) | ||
154 | #else | ||
155 | #define bmtwrite(dat,adr) writel((dat), (adr)) | ||
156 | #define bmtread(adr) readl(adr) | ||
157 | #endif | ||
158 | |||
159 | #endif | ||
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c deleted file mode 100644 index 430b3eb11815..000000000000 --- a/drivers/media/dvb/bt8xx/dst.c +++ /dev/null | |||
@@ -1,1873 +0,0 @@ | |||
1 | /* | ||
2 | Frontend/Card driver for TwinHan DST Frontend | ||
3 | Copyright (C) 2003 Jamie Honan | ||
4 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/vmalloc.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <asm/div64.h> | ||
29 | #include "dvb_frontend.h" | ||
30 | #include "dst_priv.h" | ||
31 | #include "dst_common.h" | ||
32 | |||
33 | static unsigned int verbose = 1; | ||
34 | module_param(verbose, int, 0644); | ||
35 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); | ||
36 | |||
37 | static unsigned int dst_addons; | ||
38 | module_param(dst_addons, int, 0644); | ||
39 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); | ||
40 | |||
41 | static unsigned int dst_algo; | ||
42 | module_param(dst_algo, int, 0644); | ||
43 | MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); | ||
44 | |||
45 | #define HAS_LOCK 1 | ||
46 | #define ATTEMPT_TUNE 2 | ||
47 | #define HAS_POWER 4 | ||
48 | |||
49 | #define DST_ERROR 0 | ||
50 | #define DST_NOTICE 1 | ||
51 | #define DST_INFO 2 | ||
52 | #define DST_DEBUG 3 | ||
53 | |||
54 | #define dprintk(x, y, z, format, arg...) do { \ | ||
55 | if (z) { \ | ||
56 | if ((x > DST_ERROR) && (x > y)) \ | ||
57 | printk(KERN_ERR "dst(%d) %s: " format "\n", \ | ||
58 | state->bt->nr, __func__ , ##arg); \ | ||
59 | else if ((x > DST_NOTICE) && (x > y)) \ | ||
60 | printk(KERN_NOTICE "dst(%d) %s: " format "\n", \ | ||
61 | state->bt->nr, __func__ , ##arg); \ | ||
62 | else if ((x > DST_INFO) && (x > y)) \ | ||
63 | printk(KERN_INFO "dst(%d) %s: " format "\n", \ | ||
64 | state->bt->nr, __func__ , ##arg); \ | ||
65 | else if ((x > DST_DEBUG) && (x > y)) \ | ||
66 | printk(KERN_DEBUG "dst(%d) %s: " format "\n", \ | ||
67 | state->bt->nr, __func__ , ##arg); \ | ||
68 | } else { \ | ||
69 | if (x > y) \ | ||
70 | printk(format, ##arg); \ | ||
71 | } \ | ||
72 | } while(0) | ||
73 | |||
74 | static int dst_command(struct dst_state *state, u8 *data, u8 len); | ||
75 | |||
76 | static void dst_packsize(struct dst_state *state, int psize) | ||
77 | { | ||
78 | union dst_gpio_packet bits; | ||
79 | |||
80 | bits.psize = psize; | ||
81 | bt878_device_control(state->bt, DST_IG_TS, &bits); | ||
82 | } | ||
83 | |||
84 | static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, | ||
85 | u32 outhigh, int delay) | ||
86 | { | ||
87 | union dst_gpio_packet enb; | ||
88 | union dst_gpio_packet bits; | ||
89 | int err; | ||
90 | |||
91 | enb.enb.mask = mask; | ||
92 | enb.enb.enable = enbb; | ||
93 | |||
94 | dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh); | ||
95 | if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { | ||
96 | dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb); | ||
97 | return -EREMOTEIO; | ||
98 | } | ||
99 | udelay(1000); | ||
100 | /* because complete disabling means no output, no need to do output packet */ | ||
101 | if (enbb == 0) | ||
102 | return 0; | ||
103 | if (delay) | ||
104 | msleep(10); | ||
105 | bits.outp.mask = enbb; | ||
106 | bits.outp.highvals = outhigh; | ||
107 | if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { | ||
108 | dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh); | ||
109 | return -EREMOTEIO; | ||
110 | } | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int dst_gpio_inb(struct dst_state *state, u8 *result) | ||
116 | { | ||
117 | union dst_gpio_packet rd_packet; | ||
118 | int err; | ||
119 | |||
120 | *result = 0; | ||
121 | if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { | ||
122 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err); | ||
123 | return -EREMOTEIO; | ||
124 | } | ||
125 | *result = (u8) rd_packet.rd.value; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | int rdc_reset_state(struct dst_state *state) | ||
131 | { | ||
132 | dprintk(verbose, DST_INFO, 1, "Resetting state machine"); | ||
133 | if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) { | ||
134 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); | ||
135 | return -1; | ||
136 | } | ||
137 | msleep(10); | ||
138 | if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) { | ||
139 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); | ||
140 | msleep(10); | ||
141 | return -1; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | EXPORT_SYMBOL(rdc_reset_state); | ||
147 | |||
148 | static int rdc_8820_reset(struct dst_state *state) | ||
149 | { | ||
150 | dprintk(verbose, DST_DEBUG, 1, "Resetting DST"); | ||
151 | if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) { | ||
152 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); | ||
153 | return -1; | ||
154 | } | ||
155 | udelay(1000); | ||
156 | if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) { | ||
157 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); | ||
158 | return -1; | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int dst_pio_enable(struct dst_state *state) | ||
165 | { | ||
166 | if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) { | ||
167 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); | ||
168 | return -1; | ||
169 | } | ||
170 | udelay(1000); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | int dst_pio_disable(struct dst_state *state) | ||
176 | { | ||
177 | if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) { | ||
178 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); | ||
179 | return -1; | ||
180 | } | ||
181 | if (state->type_flags & DST_TYPE_HAS_FW_1) | ||
182 | udelay(1000); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | EXPORT_SYMBOL(dst_pio_disable); | ||
187 | |||
188 | int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode) | ||
189 | { | ||
190 | u8 reply; | ||
191 | int i; | ||
192 | |||
193 | for (i = 0; i < 200; i++) { | ||
194 | if (dst_gpio_inb(state, &reply) < 0) { | ||
195 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !"); | ||
196 | return -1; | ||
197 | } | ||
198 | if ((reply & RDC_8820_PIO_0_ENABLE) == 0) { | ||
199 | dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i); | ||
200 | return 1; | ||
201 | } | ||
202 | msleep(10); | ||
203 | } | ||
204 | dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | EXPORT_SYMBOL(dst_wait_dst_ready); | ||
209 | |||
210 | int dst_error_recovery(struct dst_state *state) | ||
211 | { | ||
212 | dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors."); | ||
213 | dst_pio_disable(state); | ||
214 | msleep(10); | ||
215 | dst_pio_enable(state); | ||
216 | msleep(10); | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | EXPORT_SYMBOL(dst_error_recovery); | ||
221 | |||
222 | int dst_error_bailout(struct dst_state *state) | ||
223 | { | ||
224 | dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error."); | ||
225 | rdc_8820_reset(state); | ||
226 | dst_pio_disable(state); | ||
227 | msleep(10); | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | EXPORT_SYMBOL(dst_error_bailout); | ||
232 | |||
233 | int dst_comm_init(struct dst_state *state) | ||
234 | { | ||
235 | dprintk(verbose, DST_INFO, 1, "Initializing DST."); | ||
236 | if ((dst_pio_enable(state)) < 0) { | ||
237 | dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed"); | ||
238 | return -1; | ||
239 | } | ||
240 | if ((rdc_reset_state(state)) < 0) { | ||
241 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed."); | ||
242 | return -1; | ||
243 | } | ||
244 | if (state->type_flags & DST_TYPE_HAS_FW_1) | ||
245 | msleep(100); | ||
246 | else | ||
247 | msleep(5); | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | EXPORT_SYMBOL(dst_comm_init); | ||
252 | |||
253 | int write_dst(struct dst_state *state, u8 *data, u8 len) | ||
254 | { | ||
255 | struct i2c_msg msg = { | ||
256 | .addr = state->config->demod_address, | ||
257 | .flags = 0, | ||
258 | .buf = data, | ||
259 | .len = len | ||
260 | }; | ||
261 | |||
262 | int err; | ||
263 | u8 cnt, i; | ||
264 | |||
265 | dprintk(verbose, DST_NOTICE, 0, "writing [ "); | ||
266 | for (i = 0; i < len; i++) | ||
267 | dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]); | ||
268 | dprintk(verbose, DST_NOTICE, 0, "]\n"); | ||
269 | |||
270 | for (cnt = 0; cnt < 2; cnt++) { | ||
271 | if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { | ||
272 | dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]); | ||
273 | dst_error_recovery(state); | ||
274 | continue; | ||
275 | } else | ||
276 | break; | ||
277 | } | ||
278 | if (cnt >= 2) { | ||
279 | dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET"); | ||
280 | dst_error_bailout(state); | ||
281 | |||
282 | return -1; | ||
283 | } | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | EXPORT_SYMBOL(write_dst); | ||
288 | |||
289 | int read_dst(struct dst_state *state, u8 *ret, u8 len) | ||
290 | { | ||
291 | struct i2c_msg msg = { | ||
292 | .addr = state->config->demod_address, | ||
293 | .flags = I2C_M_RD, | ||
294 | .buf = ret, | ||
295 | .len = len | ||
296 | }; | ||
297 | |||
298 | int err; | ||
299 | int cnt; | ||
300 | |||
301 | for (cnt = 0; cnt < 2; cnt++) { | ||
302 | if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { | ||
303 | dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]); | ||
304 | dst_error_recovery(state); | ||
305 | continue; | ||
306 | } else | ||
307 | break; | ||
308 | } | ||
309 | if (cnt >= 2) { | ||
310 | dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET"); | ||
311 | dst_error_bailout(state); | ||
312 | |||
313 | return -1; | ||
314 | } | ||
315 | dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]); | ||
316 | for (err = 1; err < len; err++) | ||
317 | dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]); | ||
318 | if (err > 1) | ||
319 | dprintk(verbose, DST_DEBUG, 0, "\n"); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | EXPORT_SYMBOL(read_dst); | ||
324 | |||
325 | static int dst_set_polarization(struct dst_state *state) | ||
326 | { | ||
327 | switch (state->voltage) { | ||
328 | case SEC_VOLTAGE_13: /* Vertical */ | ||
329 | dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]"); | ||
330 | state->tx_tuna[8] &= ~0x40; | ||
331 | break; | ||
332 | case SEC_VOLTAGE_18: /* Horizontal */ | ||
333 | dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]"); | ||
334 | state->tx_tuna[8] |= 0x40; | ||
335 | break; | ||
336 | case SEC_VOLTAGE_OFF: | ||
337 | break; | ||
338 | } | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int dst_set_freq(struct dst_state *state, u32 freq) | ||
344 | { | ||
345 | state->frequency = freq; | ||
346 | dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq); | ||
347 | |||
348 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
349 | freq = freq / 1000; | ||
350 | if (freq < 950 || freq > 2150) | ||
351 | return -EINVAL; | ||
352 | state->tx_tuna[2] = (freq >> 8); | ||
353 | state->tx_tuna[3] = (u8) freq; | ||
354 | state->tx_tuna[4] = 0x01; | ||
355 | state->tx_tuna[8] &= ~0x04; | ||
356 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { | ||
357 | if (freq < 1531) | ||
358 | state->tx_tuna[8] |= 0x04; | ||
359 | } | ||
360 | } else if (state->dst_type == DST_TYPE_IS_TERR) { | ||
361 | freq = freq / 1000; | ||
362 | if (freq < 137000 || freq > 858000) | ||
363 | return -EINVAL; | ||
364 | state->tx_tuna[2] = (freq >> 16) & 0xff; | ||
365 | state->tx_tuna[3] = (freq >> 8) & 0xff; | ||
366 | state->tx_tuna[4] = (u8) freq; | ||
367 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
368 | freq = freq / 1000; | ||
369 | state->tx_tuna[2] = (freq >> 16) & 0xff; | ||
370 | state->tx_tuna[3] = (freq >> 8) & 0xff; | ||
371 | state->tx_tuna[4] = (u8) freq; | ||
372 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
373 | freq = freq / 1000; | ||
374 | if (freq < 51000 || freq > 858000) | ||
375 | return -EINVAL; | ||
376 | state->tx_tuna[2] = (freq >> 16) & 0xff; | ||
377 | state->tx_tuna[3] = (freq >> 8) & 0xff; | ||
378 | state->tx_tuna[4] = (u8) freq; | ||
379 | state->tx_tuna[5] = 0x00; /* ATSC */ | ||
380 | state->tx_tuna[6] = 0x00; | ||
381 | if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG) | ||
382 | state->tx_tuna[7] = 0x00; /* Digital */ | ||
383 | } else | ||
384 | return -EINVAL; | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth) | ||
390 | { | ||
391 | state->bandwidth = bandwidth; | ||
392 | |||
393 | if (state->dst_type != DST_TYPE_IS_TERR) | ||
394 | return -EOPNOTSUPP; | ||
395 | |||
396 | switch (bandwidth) { | ||
397 | case 6000000: | ||
398 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) | ||
399 | state->tx_tuna[7] = 0x06; | ||
400 | else { | ||
401 | state->tx_tuna[6] = 0x06; | ||
402 | state->tx_tuna[7] = 0x00; | ||
403 | } | ||
404 | break; | ||
405 | case 7000000: | ||
406 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) | ||
407 | state->tx_tuna[7] = 0x07; | ||
408 | else { | ||
409 | state->tx_tuna[6] = 0x07; | ||
410 | state->tx_tuna[7] = 0x00; | ||
411 | } | ||
412 | break; | ||
413 | case 8000000: | ||
414 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) | ||
415 | state->tx_tuna[7] = 0x08; | ||
416 | else { | ||
417 | state->tx_tuna[6] = 0x08; | ||
418 | state->tx_tuna[7] = 0x00; | ||
419 | } | ||
420 | break; | ||
421 | default: | ||
422 | return -EINVAL; | ||
423 | } | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion) | ||
429 | { | ||
430 | state->inversion = inversion; | ||
431 | switch (inversion) { | ||
432 | case INVERSION_OFF: /* Inversion = Normal */ | ||
433 | state->tx_tuna[8] &= ~0x80; | ||
434 | break; | ||
435 | case INVERSION_ON: | ||
436 | state->tx_tuna[8] |= 0x80; | ||
437 | break; | ||
438 | default: | ||
439 | return -EINVAL; | ||
440 | } | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec) | ||
446 | { | ||
447 | state->fec = fec; | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static fe_code_rate_t dst_get_fec(struct dst_state *state) | ||
452 | { | ||
453 | return state->fec; | ||
454 | } | ||
455 | |||
456 | static int dst_set_symbolrate(struct dst_state *state, u32 srate) | ||
457 | { | ||
458 | u32 symcalc; | ||
459 | u64 sval; | ||
460 | |||
461 | state->symbol_rate = srate; | ||
462 | if (state->dst_type == DST_TYPE_IS_TERR) { | ||
463 | return -EOPNOTSUPP; | ||
464 | } | ||
465 | dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); | ||
466 | srate /= 1000; | ||
467 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
468 | if (state->type_flags & DST_TYPE_HAS_SYMDIV) { | ||
469 | sval = srate; | ||
470 | sval <<= 20; | ||
471 | do_div(sval, 88000); | ||
472 | symcalc = (u32) sval; | ||
473 | dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); | ||
474 | state->tx_tuna[5] = (u8) (symcalc >> 12); | ||
475 | state->tx_tuna[6] = (u8) (symcalc >> 4); | ||
476 | state->tx_tuna[7] = (u8) (symcalc << 4); | ||
477 | } else { | ||
478 | state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; | ||
479 | state->tx_tuna[6] = (u8) (srate >> 8); | ||
480 | state->tx_tuna[7] = (u8) srate; | ||
481 | } | ||
482 | state->tx_tuna[8] &= ~0x20; | ||
483 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { | ||
484 | if (srate > 8000) | ||
485 | state->tx_tuna[8] |= 0x20; | ||
486 | } | ||
487 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
488 | dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name); | ||
489 | if (!strncmp(state->fw_name, "DCTNEW", 6)) { | ||
490 | state->tx_tuna[5] = (u8) (srate >> 8); | ||
491 | state->tx_tuna[6] = (u8) srate; | ||
492 | state->tx_tuna[7] = 0x00; | ||
493 | } else if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
494 | state->tx_tuna[5] = 0x00; | ||
495 | state->tx_tuna[6] = (u8) (srate >> 8); | ||
496 | state->tx_tuna[7] = (u8) srate; | ||
497 | } | ||
498 | } | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) | ||
503 | { | ||
504 | if (state->dst_type != DST_TYPE_IS_CABLE) | ||
505 | return -EOPNOTSUPP; | ||
506 | |||
507 | state->modulation = modulation; | ||
508 | switch (modulation) { | ||
509 | case QAM_16: | ||
510 | state->tx_tuna[8] = 0x10; | ||
511 | break; | ||
512 | case QAM_32: | ||
513 | state->tx_tuna[8] = 0x20; | ||
514 | break; | ||
515 | case QAM_64: | ||
516 | state->tx_tuna[8] = 0x40; | ||
517 | break; | ||
518 | case QAM_128: | ||
519 | state->tx_tuna[8] = 0x80; | ||
520 | break; | ||
521 | case QAM_256: | ||
522 | if (!strncmp(state->fw_name, "DCTNEW", 6)) | ||
523 | state->tx_tuna[8] = 0xff; | ||
524 | else if (!strncmp(state->fw_name, "DCT-CI", 6)) | ||
525 | state->tx_tuna[8] = 0x00; | ||
526 | break; | ||
527 | case QPSK: | ||
528 | case QAM_AUTO: | ||
529 | case VSB_8: | ||
530 | case VSB_16: | ||
531 | default: | ||
532 | return -EINVAL; | ||
533 | |||
534 | } | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static fe_modulation_t dst_get_modulation(struct dst_state *state) | ||
540 | { | ||
541 | return state->modulation; | ||
542 | } | ||
543 | |||
544 | |||
545 | u8 dst_check_sum(u8 *buf, u32 len) | ||
546 | { | ||
547 | u32 i; | ||
548 | u8 val = 0; | ||
549 | if (!len) | ||
550 | return 0; | ||
551 | for (i = 0; i < len; i++) { | ||
552 | val += buf[i]; | ||
553 | } | ||
554 | return ((~val) + 1); | ||
555 | } | ||
556 | EXPORT_SYMBOL(dst_check_sum); | ||
557 | |||
558 | static void dst_type_flags_print(struct dst_state *state) | ||
559 | { | ||
560 | u32 type_flags = state->type_flags; | ||
561 | |||
562 | dprintk(verbose, DST_ERROR, 0, "DST type flags :"); | ||
563 | if (type_flags & DST_TYPE_HAS_TS188) | ||
564 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188); | ||
565 | if (type_flags & DST_TYPE_HAS_NEWTUNE_2) | ||
566 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2); | ||
567 | if (type_flags & DST_TYPE_HAS_TS204) | ||
568 | dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); | ||
569 | if (type_flags & DST_TYPE_HAS_VLF) | ||
570 | dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF); | ||
571 | if (type_flags & DST_TYPE_HAS_SYMDIV) | ||
572 | dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); | ||
573 | if (type_flags & DST_TYPE_HAS_FW_1) | ||
574 | dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1); | ||
575 | if (type_flags & DST_TYPE_HAS_FW_2) | ||
576 | dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2); | ||
577 | if (type_flags & DST_TYPE_HAS_FW_3) | ||
578 | dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3); | ||
579 | dprintk(verbose, DST_ERROR, 0, "\n"); | ||
580 | } | ||
581 | |||
582 | |||
583 | static int dst_type_print(struct dst_state *state, u8 type) | ||
584 | { | ||
585 | char *otype; | ||
586 | switch (type) { | ||
587 | case DST_TYPE_IS_SAT: | ||
588 | otype = "satellite"; | ||
589 | break; | ||
590 | |||
591 | case DST_TYPE_IS_TERR: | ||
592 | otype = "terrestrial"; | ||
593 | break; | ||
594 | |||
595 | case DST_TYPE_IS_CABLE: | ||
596 | otype = "cable"; | ||
597 | break; | ||
598 | |||
599 | case DST_TYPE_IS_ATSC: | ||
600 | otype = "atsc"; | ||
601 | break; | ||
602 | |||
603 | default: | ||
604 | dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); | ||
605 | return -EINVAL; | ||
606 | } | ||
607 | dprintk(verbose, DST_INFO, 1, "DST type: %s", otype); | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static struct tuner_types tuner_list[] = { | ||
613 | { | ||
614 | .tuner_type = TUNER_TYPE_L64724, | ||
615 | .tuner_name = "L 64724", | ||
616 | .board_name = "UNKNOWN", | ||
617 | .fw_name = "UNKNOWN" | ||
618 | }, | ||
619 | |||
620 | { | ||
621 | .tuner_type = TUNER_TYPE_STV0299, | ||
622 | .tuner_name = "STV 0299", | ||
623 | .board_name = "VP1020", | ||
624 | .fw_name = "DST-MOT" | ||
625 | }, | ||
626 | |||
627 | { | ||
628 | .tuner_type = TUNER_TYPE_STV0299, | ||
629 | .tuner_name = "STV 0299", | ||
630 | .board_name = "VP1020", | ||
631 | .fw_name = "DST-03T" | ||
632 | }, | ||
633 | |||
634 | { | ||
635 | .tuner_type = TUNER_TYPE_MB86A15, | ||
636 | .tuner_name = "MB 86A15", | ||
637 | .board_name = "VP1022", | ||
638 | .fw_name = "DST-03T" | ||
639 | }, | ||
640 | |||
641 | { | ||
642 | .tuner_type = TUNER_TYPE_MB86A15, | ||
643 | .tuner_name = "MB 86A15", | ||
644 | .board_name = "VP1025", | ||
645 | .fw_name = "DST-03T" | ||
646 | }, | ||
647 | |||
648 | { | ||
649 | .tuner_type = TUNER_TYPE_STV0299, | ||
650 | .tuner_name = "STV 0299", | ||
651 | .board_name = "VP1030", | ||
652 | .fw_name = "DST-CI" | ||
653 | }, | ||
654 | |||
655 | { | ||
656 | .tuner_type = TUNER_TYPE_STV0299, | ||
657 | .tuner_name = "STV 0299", | ||
658 | .board_name = "VP1030", | ||
659 | .fw_name = "DSTMCI" | ||
660 | }, | ||
661 | |||
662 | { | ||
663 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
664 | .tuner_name = "UNKNOWN", | ||
665 | .board_name = "VP2021", | ||
666 | .fw_name = "DCTNEW" | ||
667 | }, | ||
668 | |||
669 | { | ||
670 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
671 | .tuner_name = "UNKNOWN", | ||
672 | .board_name = "VP2030", | ||
673 | .fw_name = "DCT-CI" | ||
674 | }, | ||
675 | |||
676 | { | ||
677 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
678 | .tuner_name = "UNKNOWN", | ||
679 | .board_name = "VP2031", | ||
680 | .fw_name = "DCT-CI" | ||
681 | }, | ||
682 | |||
683 | { | ||
684 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
685 | .tuner_name = "UNKNOWN", | ||
686 | .board_name = "VP2040", | ||
687 | .fw_name = "DCT-CI" | ||
688 | }, | ||
689 | |||
690 | { | ||
691 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
692 | .tuner_name = "UNKNOWN", | ||
693 | .board_name = "VP3020", | ||
694 | .fw_name = "DTTFTA" | ||
695 | }, | ||
696 | |||
697 | { | ||
698 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
699 | .tuner_name = "UNKNOWN", | ||
700 | .board_name = "VP3021", | ||
701 | .fw_name = "DTTFTA" | ||
702 | }, | ||
703 | |||
704 | { | ||
705 | .tuner_type = TUNER_TYPE_TDA10046, | ||
706 | .tuner_name = "TDA10046", | ||
707 | .board_name = "VP3040", | ||
708 | .fw_name = "DTT-CI" | ||
709 | }, | ||
710 | |||
711 | { | ||
712 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
713 | .tuner_name = "UNKNOWN", | ||
714 | .board_name = "VP3051", | ||
715 | .fw_name = "DTTNXT" | ||
716 | }, | ||
717 | |||
718 | { | ||
719 | .tuner_type = TUNER_TYPE_NXT200x, | ||
720 | .tuner_name = "NXT200x", | ||
721 | .board_name = "VP3220", | ||
722 | .fw_name = "ATSCDI" | ||
723 | }, | ||
724 | |||
725 | { | ||
726 | .tuner_type = TUNER_TYPE_NXT200x, | ||
727 | .tuner_name = "NXT200x", | ||
728 | .board_name = "VP3250", | ||
729 | .fw_name = "ATSCAD" | ||
730 | }, | ||
731 | }; | ||
732 | |||
733 | /* | ||
734 | Known cards list | ||
735 | Satellite | ||
736 | ------------------- | ||
737 | 200103A | ||
738 | VP-1020 DST-MOT LG(old), TS=188 | ||
739 | |||
740 | VP-1020 DST-03T LG(new), TS=204 | ||
741 | VP-1022 DST-03T LG(new), TS=204 | ||
742 | VP-1025 DST-03T LG(new), TS=204 | ||
743 | |||
744 | VP-1030 DSTMCI, LG(new), TS=188 | ||
745 | VP-1032 DSTMCI, LG(new), TS=188 | ||
746 | |||
747 | Cable | ||
748 | ------------------- | ||
749 | VP-2030 DCT-CI, Samsung, TS=204 | ||
750 | VP-2021 DCT-CI, Unknown, TS=204 | ||
751 | VP-2031 DCT-CI, Philips, TS=188 | ||
752 | VP-2040 DCT-CI, Philips, TS=188, with CA daughter board | ||
753 | VP-2040 DCT-CI, Philips, TS=204, without CA daughter board | ||
754 | |||
755 | Terrestrial | ||
756 | ------------------- | ||
757 | VP-3050 DTTNXT TS=188 | ||
758 | VP-3040 DTT-CI, Philips, TS=188 | ||
759 | VP-3040 DTT-CI, Philips, TS=204 | ||
760 | |||
761 | ATSC | ||
762 | ------------------- | ||
763 | VP-3220 ATSCDI, TS=188 | ||
764 | VP-3250 ATSCAD, TS=188 | ||
765 | |||
766 | */ | ||
767 | |||
768 | static struct dst_types dst_tlist[] = { | ||
769 | { | ||
770 | .device_id = "200103A", | ||
771 | .offset = 0, | ||
772 | .dst_type = DST_TYPE_IS_SAT, | ||
773 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, | ||
774 | .dst_feature = 0, | ||
775 | .tuner_type = 0 | ||
776 | }, /* obsolete */ | ||
777 | |||
778 | { | ||
779 | .device_id = "DST-020", | ||
780 | .offset = 0, | ||
781 | .dst_type = DST_TYPE_IS_SAT, | ||
782 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | ||
783 | .dst_feature = 0, | ||
784 | .tuner_type = 0 | ||
785 | }, /* obsolete */ | ||
786 | |||
787 | { | ||
788 | .device_id = "DST-030", | ||
789 | .offset = 0, | ||
790 | .dst_type = DST_TYPE_IS_SAT, | ||
791 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, | ||
792 | .dst_feature = 0, | ||
793 | .tuner_type = 0 | ||
794 | }, /* obsolete */ | ||
795 | |||
796 | { | ||
797 | .device_id = "DST-03T", | ||
798 | .offset = 0, | ||
799 | .dst_type = DST_TYPE_IS_SAT, | ||
800 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, | ||
801 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 | ||
802 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO, | ||
803 | .tuner_type = TUNER_TYPE_MULTI | ||
804 | }, | ||
805 | |||
806 | { | ||
807 | .device_id = "DST-MOT", | ||
808 | .offset = 0, | ||
809 | .dst_type = DST_TYPE_IS_SAT, | ||
810 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | ||
811 | .dst_feature = 0, | ||
812 | .tuner_type = 0 | ||
813 | }, /* obsolete */ | ||
814 | |||
815 | { | ||
816 | .device_id = "DST-CI", | ||
817 | .offset = 1, | ||
818 | .dst_type = DST_TYPE_IS_SAT, | ||
819 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1, | ||
820 | .dst_feature = DST_TYPE_HAS_CA, | ||
821 | .tuner_type = 0 | ||
822 | }, /* An OEM board */ | ||
823 | |||
824 | { | ||
825 | .device_id = "DSTMCI", | ||
826 | .offset = 1, | ||
827 | .dst_type = DST_TYPE_IS_SAT, | ||
828 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF, | ||
829 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | ||
830 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC, | ||
831 | .tuner_type = TUNER_TYPE_MULTI | ||
832 | }, | ||
833 | |||
834 | { | ||
835 | .device_id = "DSTFCI", | ||
836 | .offset = 1, | ||
837 | .dst_type = DST_TYPE_IS_SAT, | ||
838 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, | ||
839 | .dst_feature = 0, | ||
840 | .tuner_type = 0 | ||
841 | }, /* unknown to vendor */ | ||
842 | |||
843 | { | ||
844 | .device_id = "DCT-CI", | ||
845 | .offset = 1, | ||
846 | .dst_type = DST_TYPE_IS_CABLE, | ||
847 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF, | ||
848 | .dst_feature = DST_TYPE_HAS_CA, | ||
849 | .tuner_type = 0 | ||
850 | }, | ||
851 | |||
852 | { | ||
853 | .device_id = "DCTNEW", | ||
854 | .offset = 1, | ||
855 | .dst_type = DST_TYPE_IS_CABLE, | ||
856 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE, | ||
857 | .dst_feature = 0, | ||
858 | .tuner_type = 0 | ||
859 | }, | ||
860 | |||
861 | { | ||
862 | .device_id = "DTT-CI", | ||
863 | .offset = 1, | ||
864 | .dst_type = DST_TYPE_IS_TERR, | ||
865 | .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF, | ||
866 | .dst_feature = DST_TYPE_HAS_CA, | ||
867 | .tuner_type = 0 | ||
868 | }, | ||
869 | |||
870 | { | ||
871 | .device_id = "DTTDIG", | ||
872 | .offset = 1, | ||
873 | .dst_type = DST_TYPE_IS_TERR, | ||
874 | .type_flags = DST_TYPE_HAS_FW_2, | ||
875 | .dst_feature = 0, | ||
876 | .tuner_type = 0 | ||
877 | }, | ||
878 | |||
879 | { | ||
880 | .device_id = "DTTNXT", | ||
881 | .offset = 1, | ||
882 | .dst_type = DST_TYPE_IS_TERR, | ||
883 | .type_flags = DST_TYPE_HAS_FW_2, | ||
884 | .dst_feature = DST_TYPE_HAS_ANALOG, | ||
885 | .tuner_type = 0 | ||
886 | }, | ||
887 | |||
888 | { | ||
889 | .device_id = "ATSCDI", | ||
890 | .offset = 1, | ||
891 | .dst_type = DST_TYPE_IS_ATSC, | ||
892 | .type_flags = DST_TYPE_HAS_FW_2, | ||
893 | .dst_feature = 0, | ||
894 | .tuner_type = 0 | ||
895 | }, | ||
896 | |||
897 | { | ||
898 | .device_id = "ATSCAD", | ||
899 | .offset = 1, | ||
900 | .dst_type = DST_TYPE_IS_ATSC, | ||
901 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, | ||
902 | .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG, | ||
903 | .tuner_type = 0 | ||
904 | }, | ||
905 | |||
906 | { } | ||
907 | |||
908 | }; | ||
909 | |||
910 | static int dst_get_mac(struct dst_state *state) | ||
911 | { | ||
912 | u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
913 | get_mac[7] = dst_check_sum(get_mac, 7); | ||
914 | if (dst_command(state, get_mac, 8) < 0) { | ||
915 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
916 | return -1; | ||
917 | } | ||
918 | memset(&state->mac_address, '\0', 8); | ||
919 | memcpy(&state->mac_address, &state->rxbuffer, 6); | ||
920 | dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address); | ||
921 | |||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static int dst_fw_ver(struct dst_state *state) | ||
926 | { | ||
927 | u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
928 | get_ver[7] = dst_check_sum(get_ver, 7); | ||
929 | if (dst_command(state, get_ver, 8) < 0) { | ||
930 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
931 | return -1; | ||
932 | } | ||
933 | memcpy(&state->fw_version, &state->rxbuffer, 8); | ||
934 | dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x", | ||
935 | state->fw_version[0] >> 4, state->fw_version[0] & 0x0f, | ||
936 | state->fw_version[1], | ||
937 | state->fw_version[5], state->fw_version[6], | ||
938 | state->fw_version[4], state->fw_version[3], state->fw_version[2]); | ||
939 | |||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | static int dst_card_type(struct dst_state *state) | ||
944 | { | ||
945 | int j; | ||
946 | struct tuner_types *p_tuner_list = NULL; | ||
947 | |||
948 | u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
949 | get_type[7] = dst_check_sum(get_type, 7); | ||
950 | if (dst_command(state, get_type, 8) < 0) { | ||
951 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
952 | return -1; | ||
953 | } | ||
954 | memset(&state->card_info, '\0', 8); | ||
955 | memcpy(&state->card_info, &state->rxbuffer, 7); | ||
956 | dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); | ||
957 | |||
958 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
959 | if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { | ||
960 | state->tuner_type = p_tuner_list->tuner_type; | ||
961 | dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]", | ||
962 | p_tuner_list->tuner_name, p_tuner_list->tuner_type); | ||
963 | } | ||
964 | } | ||
965 | |||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static int dst_get_vendor(struct dst_state *state) | ||
970 | { | ||
971 | u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
972 | get_vendor[7] = dst_check_sum(get_vendor, 7); | ||
973 | if (dst_command(state, get_vendor, 8) < 0) { | ||
974 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
975 | return -1; | ||
976 | } | ||
977 | memset(&state->vendor, '\0', 8); | ||
978 | memcpy(&state->vendor, &state->rxbuffer, 7); | ||
979 | dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); | ||
980 | |||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static void debug_dst_buffer(struct dst_state *state) | ||
985 | { | ||
986 | int i; | ||
987 | |||
988 | if (verbose > 2) { | ||
989 | printk("%s: [", __func__); | ||
990 | for (i = 0; i < 8; i++) | ||
991 | printk(" %02x", state->rxbuffer[i]); | ||
992 | printk("]\n"); | ||
993 | } | ||
994 | } | ||
995 | |||
996 | static int dst_check_stv0299(struct dst_state *state) | ||
997 | { | ||
998 | u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
999 | |||
1000 | check_stv0299[7] = dst_check_sum(check_stv0299, 7); | ||
1001 | if (dst_command(state, check_stv0299, 8) < 0) { | ||
1002 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed"); | ||
1003 | return -1; | ||
1004 | } | ||
1005 | debug_dst_buffer(state); | ||
1006 | |||
1007 | if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { | ||
1008 | dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM"); | ||
1009 | state->tuner_type = TUNER_TYPE_STV0299; | ||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | return -1; | ||
1014 | } | ||
1015 | |||
1016 | static int dst_check_mb86a15(struct dst_state *state) | ||
1017 | { | ||
1018 | u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1019 | |||
1020 | check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); | ||
1021 | if (dst_command(state, check_mb86a15, 8) < 0) { | ||
1022 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed"); | ||
1023 | return -1; | ||
1024 | } | ||
1025 | debug_dst_buffer(state); | ||
1026 | |||
1027 | if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { | ||
1028 | dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM"); | ||
1029 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | return -1; | ||
1034 | } | ||
1035 | |||
1036 | static int dst_get_tuner_info(struct dst_state *state) | ||
1037 | { | ||
1038 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1039 | u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1040 | |||
1041 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); | ||
1042 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); | ||
1043 | dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE"); | ||
1044 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | ||
1045 | if (dst_command(state, get_tuner_1, 8) < 0) { | ||
1046 | dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported"); | ||
1047 | goto force; | ||
1048 | } | ||
1049 | } else { | ||
1050 | if (dst_command(state, get_tuner_2, 8) < 0) { | ||
1051 | dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported"); | ||
1052 | goto force; | ||
1053 | } | ||
1054 | } | ||
1055 | memcpy(&state->board_info, &state->rxbuffer, 8); | ||
1056 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | ||
1057 | dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); | ||
1058 | } | ||
1059 | if (state->board_info[0] == 0xbc) { | ||
1060 | if (state->dst_type != DST_TYPE_IS_ATSC) | ||
1061 | state->type_flags |= DST_TYPE_HAS_TS188; | ||
1062 | else | ||
1063 | state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; | ||
1064 | |||
1065 | if (state->board_info[1] == 0x01) { | ||
1066 | state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; | ||
1067 | dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard"); | ||
1068 | } | ||
1069 | } | ||
1070 | |||
1071 | return 0; | ||
1072 | force: | ||
1073 | if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
1074 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
1075 | dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name); | ||
1076 | } | ||
1077 | |||
1078 | return -1; | ||
1079 | } | ||
1080 | |||
1081 | static int dst_get_device_id(struct dst_state *state) | ||
1082 | { | ||
1083 | u8 reply; | ||
1084 | |||
1085 | int i, j; | ||
1086 | struct dst_types *p_dst_type = NULL; | ||
1087 | struct tuner_types *p_tuner_list = NULL; | ||
1088 | |||
1089 | u8 use_dst_type = 0; | ||
1090 | u32 use_type_flags = 0; | ||
1091 | |||
1092 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | ||
1093 | |||
1094 | state->tuner_type = 0; | ||
1095 | device_type[7] = dst_check_sum(device_type, 7); | ||
1096 | |||
1097 | if (write_dst(state, device_type, FIXED_COMM)) | ||
1098 | return -1; /* Write failed */ | ||
1099 | if ((dst_pio_disable(state)) < 0) | ||
1100 | return -1; | ||
1101 | if (read_dst(state, &reply, GET_ACK)) | ||
1102 | return -1; /* Read failure */ | ||
1103 | if (reply != ACK) { | ||
1104 | dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply); | ||
1105 | return -1; /* Unack'd write */ | ||
1106 | } | ||
1107 | if (!dst_wait_dst_ready(state, DEVICE_INIT)) | ||
1108 | return -1; /* DST not ready yet */ | ||
1109 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) | ||
1110 | return -1; | ||
1111 | |||
1112 | dst_pio_disable(state); | ||
1113 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { | ||
1114 | dprintk(verbose, DST_INFO, 1, "Checksum failure!"); | ||
1115 | return -1; /* Checksum failure */ | ||
1116 | } | ||
1117 | state->rxbuffer[7] = '\0'; | ||
1118 | |||
1119 | for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) { | ||
1120 | if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) { | ||
1121 | use_type_flags = p_dst_type->type_flags; | ||
1122 | use_dst_type = p_dst_type->dst_type; | ||
1123 | |||
1124 | /* Card capabilities */ | ||
1125 | state->dst_hw_cap = p_dst_type->dst_feature; | ||
1126 | dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id); | ||
1127 | strncpy(&state->fw_name[0], p_dst_type->device_id, 6); | ||
1128 | /* Multiple tuners */ | ||
1129 | if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { | ||
1130 | switch (use_dst_type) { | ||
1131 | case DST_TYPE_IS_SAT: | ||
1132 | /* STV0299 check */ | ||
1133 | if (dst_check_stv0299(state) < 0) { | ||
1134 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1135 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1136 | } | ||
1137 | break; | ||
1138 | default: | ||
1139 | break; | ||
1140 | } | ||
1141 | if (dst_check_mb86a15(state) < 0) | ||
1142 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1143 | /* Single tuner */ | ||
1144 | } else { | ||
1145 | state->tuner_type = p_dst_type->tuner_type; | ||
1146 | } | ||
1147 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
1148 | if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && | ||
1149 | p_tuner_list->tuner_type == state->tuner_type) { | ||
1150 | dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]", | ||
1151 | p_dst_type->device_id, p_tuner_list->tuner_name); | ||
1152 | } | ||
1153 | } | ||
1154 | break; | ||
1155 | } | ||
1156 | } | ||
1157 | |||
1158 | if (i >= ARRAY_SIZE(dst_tlist)) { | ||
1159 | dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]); | ||
1160 | dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in"); | ||
1161 | use_dst_type = DST_TYPE_IS_SAT; | ||
1162 | use_type_flags = DST_TYPE_HAS_SYMDIV; | ||
1163 | } | ||
1164 | dst_type_print(state, use_dst_type); | ||
1165 | state->type_flags = use_type_flags; | ||
1166 | state->dst_type = use_dst_type; | ||
1167 | dst_type_flags_print(state); | ||
1168 | |||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1172 | static int dst_probe(struct dst_state *state) | ||
1173 | { | ||
1174 | mutex_init(&state->dst_mutex); | ||
1175 | if (dst_addons & DST_TYPE_HAS_CA) { | ||
1176 | if ((rdc_8820_reset(state)) < 0) { | ||
1177 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | ||
1178 | return -1; | ||
1179 | } | ||
1180 | msleep(4000); | ||
1181 | } else { | ||
1182 | msleep(100); | ||
1183 | } | ||
1184 | if ((dst_comm_init(state)) < 0) { | ||
1185 | dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); | ||
1186 | return -1; | ||
1187 | } | ||
1188 | msleep(100); | ||
1189 | if (dst_get_device_id(state) < 0) { | ||
1190 | dprintk(verbose, DST_ERROR, 1, "unknown device."); | ||
1191 | return -1; | ||
1192 | } | ||
1193 | if (dst_get_mac(state) < 0) { | ||
1194 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); | ||
1195 | } | ||
1196 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { | ||
1197 | if (dst_get_tuner_info(state) < 0) | ||
1198 | dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command"); | ||
1199 | } | ||
1200 | if (state->type_flags & DST_TYPE_HAS_TS204) { | ||
1201 | dst_packsize(state, 204); | ||
1202 | } | ||
1203 | if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { | ||
1204 | if (dst_fw_ver(state) < 0) { | ||
1205 | dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); | ||
1206 | return 0; | ||
1207 | } | ||
1208 | if (dst_card_type(state) < 0) { | ||
1209 | dprintk(verbose, DST_INFO, 1, "Card: Unsupported command"); | ||
1210 | return 0; | ||
1211 | } | ||
1212 | if (dst_get_vendor(state) < 0) { | ||
1213 | dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command"); | ||
1214 | return 0; | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static int dst_command(struct dst_state *state, u8 *data, u8 len) | ||
1222 | { | ||
1223 | u8 reply; | ||
1224 | |||
1225 | mutex_lock(&state->dst_mutex); | ||
1226 | if ((dst_comm_init(state)) < 0) { | ||
1227 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); | ||
1228 | goto error; | ||
1229 | } | ||
1230 | if (write_dst(state, data, len)) { | ||
1231 | dprintk(verbose, DST_INFO, 1, "Trying to recover.. "); | ||
1232 | if ((dst_error_recovery(state)) < 0) { | ||
1233 | dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); | ||
1234 | goto error; | ||
1235 | } | ||
1236 | goto error; | ||
1237 | } | ||
1238 | if ((dst_pio_disable(state)) < 0) { | ||
1239 | dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); | ||
1240 | goto error; | ||
1241 | } | ||
1242 | if (state->type_flags & DST_TYPE_HAS_FW_1) | ||
1243 | mdelay(3); | ||
1244 | if (read_dst(state, &reply, GET_ACK)) { | ||
1245 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | ||
1246 | if ((dst_error_recovery(state)) < 0) { | ||
1247 | dprintk(verbose, DST_INFO, 1, "Recovery Failed."); | ||
1248 | goto error; | ||
1249 | } | ||
1250 | goto error; | ||
1251 | } | ||
1252 | if (reply != ACK) { | ||
1253 | dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); | ||
1254 | goto error; | ||
1255 | } | ||
1256 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) | ||
1257 | goto error; | ||
1258 | if (state->type_flags & DST_TYPE_HAS_FW_1) | ||
1259 | mdelay(3); | ||
1260 | else | ||
1261 | udelay(2000); | ||
1262 | if (!dst_wait_dst_ready(state, NO_DELAY)) | ||
1263 | goto error; | ||
1264 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { | ||
1265 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | ||
1266 | if ((dst_error_recovery(state)) < 0) { | ||
1267 | dprintk(verbose, DST_INFO, 1, "Recovery failed."); | ||
1268 | goto error; | ||
1269 | } | ||
1270 | goto error; | ||
1271 | } | ||
1272 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { | ||
1273 | dprintk(verbose, DST_INFO, 1, "checksum failure"); | ||
1274 | goto error; | ||
1275 | } | ||
1276 | mutex_unlock(&state->dst_mutex); | ||
1277 | return 0; | ||
1278 | |||
1279 | error: | ||
1280 | mutex_unlock(&state->dst_mutex); | ||
1281 | return -EIO; | ||
1282 | |||
1283 | } | ||
1284 | |||
1285 | static int dst_get_signal(struct dst_state *state) | ||
1286 | { | ||
1287 | int retval; | ||
1288 | u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; | ||
1289 | //dprintk("%s: Getting Signal strength and other parameters\n", __func__); | ||
1290 | if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { | ||
1291 | state->decode_lock = state->decode_strength = state->decode_snr = 0; | ||
1292 | return 0; | ||
1293 | } | ||
1294 | if (0 == (state->diseq_flags & HAS_LOCK)) { | ||
1295 | state->decode_lock = state->decode_strength = state->decode_snr = 0; | ||
1296 | return 0; | ||
1297 | } | ||
1298 | if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) { | ||
1299 | retval = dst_command(state, get_signal, 8); | ||
1300 | if (retval < 0) | ||
1301 | return retval; | ||
1302 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1303 | state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0; | ||
1304 | state->decode_strength = state->rxbuffer[5] << 8; | ||
1305 | state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; | ||
1306 | } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) { | ||
1307 | state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; | ||
1308 | state->decode_strength = state->rxbuffer[4] << 8; | ||
1309 | state->decode_snr = state->rxbuffer[3] << 8; | ||
1310 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
1311 | state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0; | ||
1312 | state->decode_strength = state->rxbuffer[4] << 8; | ||
1313 | state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; | ||
1314 | } | ||
1315 | state->cur_jiff = jiffies; | ||
1316 | } | ||
1317 | return 0; | ||
1318 | } | ||
1319 | |||
1320 | static int dst_tone_power_cmd(struct dst_state *state) | ||
1321 | { | ||
1322 | u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 }; | ||
1323 | |||
1324 | if (state->dst_type != DST_TYPE_IS_SAT) | ||
1325 | return -EOPNOTSUPP; | ||
1326 | paket[4] = state->tx_tuna[4]; | ||
1327 | paket[2] = state->tx_tuna[2]; | ||
1328 | paket[3] = state->tx_tuna[3]; | ||
1329 | paket[7] = dst_check_sum (paket, 7); | ||
1330 | return dst_command(state, paket, 8); | ||
1331 | } | ||
1332 | |||
1333 | static int dst_get_tuna(struct dst_state *state) | ||
1334 | { | ||
1335 | int retval; | ||
1336 | |||
1337 | if ((state->diseq_flags & ATTEMPT_TUNE) == 0) | ||
1338 | return 0; | ||
1339 | state->diseq_flags &= ~(HAS_LOCK); | ||
1340 | if (!dst_wait_dst_ready(state, NO_DELAY)) | ||
1341 | return -EIO; | ||
1342 | if ((state->type_flags & DST_TYPE_HAS_VLF) && | ||
1343 | !(state->dst_type == DST_TYPE_IS_ATSC)) | ||
1344 | |||
1345 | retval = read_dst(state, state->rx_tuna, 10); | ||
1346 | else | ||
1347 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); | ||
1348 | if (retval < 0) { | ||
1349 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); | ||
1350 | return retval; | ||
1351 | } | ||
1352 | if ((state->type_flags & DST_TYPE_HAS_VLF) && | ||
1353 | !(state->dst_type == DST_TYPE_IS_ATSC)) { | ||
1354 | |||
1355 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | ||
1356 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); | ||
1357 | return -EIO; | ||
1358 | } | ||
1359 | } else { | ||
1360 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { | ||
1361 | dprintk(verbose, DST_INFO, 1, "checksum failure? "); | ||
1362 | return -EIO; | ||
1363 | } | ||
1364 | } | ||
1365 | if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) | ||
1366 | return 0; | ||
1367 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1368 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; | ||
1369 | } else { | ||
1370 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4]; | ||
1371 | } | ||
1372 | state->decode_freq = state->decode_freq * 1000; | ||
1373 | state->decode_lock = 1; | ||
1374 | state->diseq_flags |= HAS_LOCK; | ||
1375 | |||
1376 | return 1; | ||
1377 | } | ||
1378 | |||
1379 | static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||
1380 | |||
1381 | static int dst_write_tuna(struct dvb_frontend *fe) | ||
1382 | { | ||
1383 | struct dst_state *state = fe->demodulator_priv; | ||
1384 | int retval; | ||
1385 | u8 reply; | ||
1386 | |||
1387 | dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags); | ||
1388 | state->decode_freq = 0; | ||
1389 | state->decode_lock = state->decode_strength = state->decode_snr = 0; | ||
1390 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1391 | if (!(state->diseq_flags & HAS_POWER)) | ||
1392 | dst_set_voltage(fe, SEC_VOLTAGE_13); | ||
1393 | } | ||
1394 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); | ||
1395 | mutex_lock(&state->dst_mutex); | ||
1396 | if ((dst_comm_init(state)) < 0) { | ||
1397 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); | ||
1398 | goto error; | ||
1399 | } | ||
1400 | // if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | ||
1401 | if ((state->type_flags & DST_TYPE_HAS_VLF) && | ||
1402 | (!(state->dst_type == DST_TYPE_IS_ATSC))) { | ||
1403 | |||
1404 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); | ||
1405 | retval = write_dst(state, &state->tx_tuna[0], 10); | ||
1406 | } else { | ||
1407 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); | ||
1408 | retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); | ||
1409 | } | ||
1410 | if (retval < 0) { | ||
1411 | dst_pio_disable(state); | ||
1412 | dprintk(verbose, DST_DEBUG, 1, "write not successful"); | ||
1413 | goto werr; | ||
1414 | } | ||
1415 | if ((dst_pio_disable(state)) < 0) { | ||
1416 | dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); | ||
1417 | goto error; | ||
1418 | } | ||
1419 | if ((read_dst(state, &reply, GET_ACK) < 0)) { | ||
1420 | dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); | ||
1421 | goto error; | ||
1422 | } | ||
1423 | if (reply != ACK) { | ||
1424 | dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); | ||
1425 | goto error; | ||
1426 | } | ||
1427 | state->diseq_flags |= ATTEMPT_TUNE; | ||
1428 | retval = dst_get_tuna(state); | ||
1429 | werr: | ||
1430 | mutex_unlock(&state->dst_mutex); | ||
1431 | return retval; | ||
1432 | |||
1433 | error: | ||
1434 | mutex_unlock(&state->dst_mutex); | ||
1435 | return -EIO; | ||
1436 | } | ||
1437 | |||
1438 | /* | ||
1439 | * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00 | ||
1440 | * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00 | ||
1441 | * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00 | ||
1442 | * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00 | ||
1443 | * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00 | ||
1444 | * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 | ||
1445 | * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 | ||
1446 | * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec | ||
1447 | * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8 | ||
1448 | * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4 | ||
1449 | * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0 | ||
1450 | */ | ||
1451 | |||
1452 | static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) | ||
1453 | { | ||
1454 | struct dst_state *state = fe->demodulator_priv; | ||
1455 | u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; | ||
1456 | |||
1457 | if (state->dst_type != DST_TYPE_IS_SAT) | ||
1458 | return -EOPNOTSUPP; | ||
1459 | if (cmd->msg_len > 0 && cmd->msg_len < 5) | ||
1460 | memcpy(&paket[3], cmd->msg, cmd->msg_len); | ||
1461 | else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) | ||
1462 | memcpy(&paket[2], cmd->msg, cmd->msg_len); | ||
1463 | else | ||
1464 | return -EINVAL; | ||
1465 | paket[7] = dst_check_sum(&paket[0], 7); | ||
1466 | return dst_command(state, paket, 8); | ||
1467 | } | ||
1468 | |||
1469 | static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
1470 | { | ||
1471 | int need_cmd, retval = 0; | ||
1472 | struct dst_state *state = fe->demodulator_priv; | ||
1473 | |||
1474 | state->voltage = voltage; | ||
1475 | if (state->dst_type != DST_TYPE_IS_SAT) | ||
1476 | return -EOPNOTSUPP; | ||
1477 | |||
1478 | need_cmd = 0; | ||
1479 | |||
1480 | switch (voltage) { | ||
1481 | case SEC_VOLTAGE_13: | ||
1482 | case SEC_VOLTAGE_18: | ||
1483 | if ((state->diseq_flags & HAS_POWER) == 0) | ||
1484 | need_cmd = 1; | ||
1485 | state->diseq_flags |= HAS_POWER; | ||
1486 | state->tx_tuna[4] = 0x01; | ||
1487 | break; | ||
1488 | case SEC_VOLTAGE_OFF: | ||
1489 | need_cmd = 1; | ||
1490 | state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); | ||
1491 | state->tx_tuna[4] = 0x00; | ||
1492 | break; | ||
1493 | default: | ||
1494 | return -EINVAL; | ||
1495 | } | ||
1496 | |||
1497 | if (need_cmd) | ||
1498 | retval = dst_tone_power_cmd(state); | ||
1499 | |||
1500 | return retval; | ||
1501 | } | ||
1502 | |||
1503 | static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | ||
1504 | { | ||
1505 | struct dst_state *state = fe->demodulator_priv; | ||
1506 | |||
1507 | state->tone = tone; | ||
1508 | if (state->dst_type != DST_TYPE_IS_SAT) | ||
1509 | return -EOPNOTSUPP; | ||
1510 | |||
1511 | switch (tone) { | ||
1512 | case SEC_TONE_OFF: | ||
1513 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1514 | state->tx_tuna[2] = 0x00; | ||
1515 | else | ||
1516 | state->tx_tuna[2] = 0xff; | ||
1517 | break; | ||
1518 | |||
1519 | case SEC_TONE_ON: | ||
1520 | state->tx_tuna[2] = 0x02; | ||
1521 | break; | ||
1522 | default: | ||
1523 | return -EINVAL; | ||
1524 | } | ||
1525 | return dst_tone_power_cmd(state); | ||
1526 | } | ||
1527 | |||
1528 | static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) | ||
1529 | { | ||
1530 | struct dst_state *state = fe->demodulator_priv; | ||
1531 | |||
1532 | if (state->dst_type != DST_TYPE_IS_SAT) | ||
1533 | return -EOPNOTSUPP; | ||
1534 | state->minicmd = minicmd; | ||
1535 | switch (minicmd) { | ||
1536 | case SEC_MINI_A: | ||
1537 | state->tx_tuna[3] = 0x02; | ||
1538 | break; | ||
1539 | case SEC_MINI_B: | ||
1540 | state->tx_tuna[3] = 0xff; | ||
1541 | break; | ||
1542 | } | ||
1543 | return dst_tone_power_cmd(state); | ||
1544 | } | ||
1545 | |||
1546 | |||
1547 | static int dst_init(struct dvb_frontend *fe) | ||
1548 | { | ||
1549 | struct dst_state *state = fe->demodulator_priv; | ||
1550 | |||
1551 | static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 }; | ||
1552 | static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; | ||
1553 | static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1554 | static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1555 | static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1556 | static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1557 | static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1558 | |||
1559 | state->inversion = INVERSION_OFF; | ||
1560 | state->voltage = SEC_VOLTAGE_13; | ||
1561 | state->tone = SEC_TONE_OFF; | ||
1562 | state->diseq_flags = 0; | ||
1563 | state->k22 = 0x02; | ||
1564 | state->bandwidth = 7000000; | ||
1565 | state->cur_jiff = jiffies; | ||
1566 | if (state->dst_type == DST_TYPE_IS_SAT) | ||
1567 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); | ||
1568 | else if (state->dst_type == DST_TYPE_IS_TERR) | ||
1569 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); | ||
1570 | else if (state->dst_type == DST_TYPE_IS_CABLE) | ||
1571 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); | ||
1572 | else if (state->dst_type == DST_TYPE_IS_ATSC) | ||
1573 | memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); | ||
1574 | |||
1575 | return 0; | ||
1576 | } | ||
1577 | |||
1578 | static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
1579 | { | ||
1580 | struct dst_state *state = fe->demodulator_priv; | ||
1581 | |||
1582 | *status = 0; | ||
1583 | if (state->diseq_flags & HAS_LOCK) { | ||
1584 | // dst_get_signal(state); // don't require(?) to ask MCU | ||
1585 | if (state->decode_lock) | ||
1586 | *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; | ||
1587 | } | ||
1588 | |||
1589 | return 0; | ||
1590 | } | ||
1591 | |||
1592 | static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||
1593 | { | ||
1594 | struct dst_state *state = fe->demodulator_priv; | ||
1595 | |||
1596 | int retval = dst_get_signal(state); | ||
1597 | *strength = state->decode_strength; | ||
1598 | |||
1599 | return retval; | ||
1600 | } | ||
1601 | |||
1602 | static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
1603 | { | ||
1604 | struct dst_state *state = fe->demodulator_priv; | ||
1605 | |||
1606 | int retval = dst_get_signal(state); | ||
1607 | *snr = state->decode_snr; | ||
1608 | |||
1609 | return retval; | ||
1610 | } | ||
1611 | |||
1612 | static int dst_set_frontend(struct dvb_frontend *fe) | ||
1613 | { | ||
1614 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1615 | int retval = -EINVAL; | ||
1616 | struct dst_state *state = fe->demodulator_priv; | ||
1617 | |||
1618 | if (p != NULL) { | ||
1619 | retval = dst_set_freq(state, p->frequency); | ||
1620 | if(retval != 0) | ||
1621 | return retval; | ||
1622 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | ||
1623 | |||
1624 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1625 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1626 | dst_set_inversion(state, p->inversion); | ||
1627 | dst_set_fec(state, p->fec_inner); | ||
1628 | dst_set_symbolrate(state, p->symbol_rate); | ||
1629 | dst_set_polarization(state); | ||
1630 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate); | ||
1631 | |||
1632 | } else if (state->dst_type == DST_TYPE_IS_TERR) | ||
1633 | dst_set_bandwidth(state, p->bandwidth_hz); | ||
1634 | else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
1635 | dst_set_fec(state, p->fec_inner); | ||
1636 | dst_set_symbolrate(state, p->symbol_rate); | ||
1637 | dst_set_modulation(state, p->modulation); | ||
1638 | } | ||
1639 | retval = dst_write_tuna(fe); | ||
1640 | } | ||
1641 | |||
1642 | return retval; | ||
1643 | } | ||
1644 | |||
1645 | static int dst_tune_frontend(struct dvb_frontend* fe, | ||
1646 | bool re_tune, | ||
1647 | unsigned int mode_flags, | ||
1648 | unsigned int *delay, | ||
1649 | fe_status_t *status) | ||
1650 | { | ||
1651 | struct dst_state *state = fe->demodulator_priv; | ||
1652 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1653 | |||
1654 | if (re_tune) { | ||
1655 | dst_set_freq(state, p->frequency); | ||
1656 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | ||
1657 | |||
1658 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1659 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1660 | dst_set_inversion(state, p->inversion); | ||
1661 | dst_set_fec(state, p->fec_inner); | ||
1662 | dst_set_symbolrate(state, p->symbol_rate); | ||
1663 | dst_set_polarization(state); | ||
1664 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate); | ||
1665 | |||
1666 | } else if (state->dst_type == DST_TYPE_IS_TERR) | ||
1667 | dst_set_bandwidth(state, p->bandwidth_hz); | ||
1668 | else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
1669 | dst_set_fec(state, p->fec_inner); | ||
1670 | dst_set_symbolrate(state, p->symbol_rate); | ||
1671 | dst_set_modulation(state, p->modulation); | ||
1672 | } | ||
1673 | dst_write_tuna(fe); | ||
1674 | } | ||
1675 | |||
1676 | if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) | ||
1677 | dst_read_status(fe, status); | ||
1678 | |||
1679 | *delay = HZ/10; | ||
1680 | return 0; | ||
1681 | } | ||
1682 | |||
1683 | static int dst_get_tuning_algo(struct dvb_frontend *fe) | ||
1684 | { | ||
1685 | return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW; | ||
1686 | } | ||
1687 | |||
1688 | static int dst_get_frontend(struct dvb_frontend *fe) | ||
1689 | { | ||
1690 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1691 | struct dst_state *state = fe->demodulator_priv; | ||
1692 | |||
1693 | p->frequency = state->decode_freq; | ||
1694 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1695 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1696 | p->inversion = state->inversion; | ||
1697 | p->symbol_rate = state->symbol_rate; | ||
1698 | p->fec_inner = dst_get_fec(state); | ||
1699 | } else if (state->dst_type == DST_TYPE_IS_TERR) { | ||
1700 | p->bandwidth_hz = state->bandwidth; | ||
1701 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
1702 | p->symbol_rate = state->symbol_rate; | ||
1703 | p->fec_inner = dst_get_fec(state); | ||
1704 | p->modulation = dst_get_modulation(state); | ||
1705 | } | ||
1706 | |||
1707 | return 0; | ||
1708 | } | ||
1709 | |||
1710 | static void dst_release(struct dvb_frontend *fe) | ||
1711 | { | ||
1712 | struct dst_state *state = fe->demodulator_priv; | ||
1713 | if (state->dst_ca) { | ||
1714 | dvb_unregister_device(state->dst_ca); | ||
1715 | #ifdef CONFIG_MEDIA_ATTACH | ||
1716 | symbol_put(dst_ca_attach); | ||
1717 | #endif | ||
1718 | } | ||
1719 | kfree(state); | ||
1720 | } | ||
1721 | |||
1722 | static struct dvb_frontend_ops dst_dvbt_ops; | ||
1723 | static struct dvb_frontend_ops dst_dvbs_ops; | ||
1724 | static struct dvb_frontend_ops dst_dvbc_ops; | ||
1725 | static struct dvb_frontend_ops dst_atsc_ops; | ||
1726 | |||
1727 | struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) | ||
1728 | { | ||
1729 | /* check if the ASIC is there */ | ||
1730 | if (dst_probe(state) < 0) { | ||
1731 | kfree(state); | ||
1732 | return NULL; | ||
1733 | } | ||
1734 | /* determine settings based on type */ | ||
1735 | /* create dvb_frontend */ | ||
1736 | switch (state->dst_type) { | ||
1737 | case DST_TYPE_IS_TERR: | ||
1738 | memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); | ||
1739 | break; | ||
1740 | case DST_TYPE_IS_CABLE: | ||
1741 | memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); | ||
1742 | break; | ||
1743 | case DST_TYPE_IS_SAT: | ||
1744 | memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); | ||
1745 | break; | ||
1746 | case DST_TYPE_IS_ATSC: | ||
1747 | memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); | ||
1748 | break; | ||
1749 | default: | ||
1750 | dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); | ||
1751 | kfree(state); | ||
1752 | return NULL; | ||
1753 | } | ||
1754 | state->frontend.demodulator_priv = state; | ||
1755 | |||
1756 | return state; /* Manu (DST is a card not a frontend) */ | ||
1757 | } | ||
1758 | |||
1759 | EXPORT_SYMBOL(dst_attach); | ||
1760 | |||
1761 | static struct dvb_frontend_ops dst_dvbt_ops = { | ||
1762 | .delsys = { SYS_DVBT }, | ||
1763 | .info = { | ||
1764 | .name = "DST DVB-T", | ||
1765 | .frequency_min = 137000000, | ||
1766 | .frequency_max = 858000000, | ||
1767 | .frequency_stepsize = 166667, | ||
1768 | .caps = FE_CAN_FEC_AUTO | | ||
1769 | FE_CAN_QAM_AUTO | | ||
1770 | FE_CAN_QAM_16 | | ||
1771 | FE_CAN_QAM_32 | | ||
1772 | FE_CAN_QAM_64 | | ||
1773 | FE_CAN_QAM_128 | | ||
1774 | FE_CAN_QAM_256 | | ||
1775 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
1776 | FE_CAN_GUARD_INTERVAL_AUTO | ||
1777 | }, | ||
1778 | |||
1779 | .release = dst_release, | ||
1780 | .init = dst_init, | ||
1781 | .tune = dst_tune_frontend, | ||
1782 | .set_frontend = dst_set_frontend, | ||
1783 | .get_frontend = dst_get_frontend, | ||
1784 | .get_frontend_algo = dst_get_tuning_algo, | ||
1785 | .read_status = dst_read_status, | ||
1786 | .read_signal_strength = dst_read_signal_strength, | ||
1787 | .read_snr = dst_read_snr, | ||
1788 | }; | ||
1789 | |||
1790 | static struct dvb_frontend_ops dst_dvbs_ops = { | ||
1791 | .delsys = { SYS_DVBS }, | ||
1792 | .info = { | ||
1793 | .name = "DST DVB-S", | ||
1794 | .frequency_min = 950000, | ||
1795 | .frequency_max = 2150000, | ||
1796 | .frequency_stepsize = 1000, /* kHz for QPSK frontends */ | ||
1797 | .frequency_tolerance = 29500, | ||
1798 | .symbol_rate_min = 1000000, | ||
1799 | .symbol_rate_max = 45000000, | ||
1800 | /* . symbol_rate_tolerance = ???,*/ | ||
1801 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK | ||
1802 | }, | ||
1803 | |||
1804 | .release = dst_release, | ||
1805 | .init = dst_init, | ||
1806 | .tune = dst_tune_frontend, | ||
1807 | .set_frontend = dst_set_frontend, | ||
1808 | .get_frontend = dst_get_frontend, | ||
1809 | .get_frontend_algo = dst_get_tuning_algo, | ||
1810 | .read_status = dst_read_status, | ||
1811 | .read_signal_strength = dst_read_signal_strength, | ||
1812 | .read_snr = dst_read_snr, | ||
1813 | .diseqc_send_burst = dst_send_burst, | ||
1814 | .diseqc_send_master_cmd = dst_set_diseqc, | ||
1815 | .set_voltage = dst_set_voltage, | ||
1816 | .set_tone = dst_set_tone, | ||
1817 | }; | ||
1818 | |||
1819 | static struct dvb_frontend_ops dst_dvbc_ops = { | ||
1820 | .delsys = { SYS_DVBC_ANNEX_A }, | ||
1821 | .info = { | ||
1822 | .name = "DST DVB-C", | ||
1823 | .frequency_stepsize = 62500, | ||
1824 | .frequency_min = 51000000, | ||
1825 | .frequency_max = 858000000, | ||
1826 | .symbol_rate_min = 1000000, | ||
1827 | .symbol_rate_max = 45000000, | ||
1828 | .caps = FE_CAN_FEC_AUTO | | ||
1829 | FE_CAN_QAM_AUTO | | ||
1830 | FE_CAN_QAM_16 | | ||
1831 | FE_CAN_QAM_32 | | ||
1832 | FE_CAN_QAM_64 | | ||
1833 | FE_CAN_QAM_128 | | ||
1834 | FE_CAN_QAM_256 | ||
1835 | }, | ||
1836 | |||
1837 | .release = dst_release, | ||
1838 | .init = dst_init, | ||
1839 | .tune = dst_tune_frontend, | ||
1840 | .set_frontend = dst_set_frontend, | ||
1841 | .get_frontend = dst_get_frontend, | ||
1842 | .get_frontend_algo = dst_get_tuning_algo, | ||
1843 | .read_status = dst_read_status, | ||
1844 | .read_signal_strength = dst_read_signal_strength, | ||
1845 | .read_snr = dst_read_snr, | ||
1846 | }; | ||
1847 | |||
1848 | static struct dvb_frontend_ops dst_atsc_ops = { | ||
1849 | .delsys = { SYS_ATSC }, | ||
1850 | .info = { | ||
1851 | .name = "DST ATSC", | ||
1852 | .frequency_stepsize = 62500, | ||
1853 | .frequency_min = 510000000, | ||
1854 | .frequency_max = 858000000, | ||
1855 | .symbol_rate_min = 1000000, | ||
1856 | .symbol_rate_max = 45000000, | ||
1857 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | ||
1858 | }, | ||
1859 | |||
1860 | .release = dst_release, | ||
1861 | .init = dst_init, | ||
1862 | .tune = dst_tune_frontend, | ||
1863 | .set_frontend = dst_set_frontend, | ||
1864 | .get_frontend = dst_get_frontend, | ||
1865 | .get_frontend_algo = dst_get_tuning_algo, | ||
1866 | .read_status = dst_read_status, | ||
1867 | .read_signal_strength = dst_read_signal_strength, | ||
1868 | .read_snr = dst_read_snr, | ||
1869 | }; | ||
1870 | |||
1871 | MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver"); | ||
1872 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); | ||
1873 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c deleted file mode 100644 index ee3884fbc9ce..000000000000 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ /dev/null | |||
@@ -1,726 +0,0 @@ | |||
1 | /* | ||
2 | CA-driver for TwinHan DST Frontend/Card | ||
3 | |||
4 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/string.h> | ||
27 | #include <linux/dvb/ca.h> | ||
28 | #include "dvbdev.h" | ||
29 | #include "dvb_frontend.h" | ||
30 | #include "dst_ca.h" | ||
31 | #include "dst_common.h" | ||
32 | |||
33 | #define DST_CA_ERROR 0 | ||
34 | #define DST_CA_NOTICE 1 | ||
35 | #define DST_CA_INFO 2 | ||
36 | #define DST_CA_DEBUG 3 | ||
37 | |||
38 | #define dprintk(x, y, z, format, arg...) do { \ | ||
39 | if (z) { \ | ||
40 | if ((x > DST_CA_ERROR) && (x > y)) \ | ||
41 | printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ | ||
42 | else if ((x > DST_CA_NOTICE) && (x > y)) \ | ||
43 | printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ | ||
44 | else if ((x > DST_CA_INFO) && (x > y)) \ | ||
45 | printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ | ||
46 | else if ((x > DST_CA_DEBUG) && (x > y)) \ | ||
47 | printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ | ||
48 | } else { \ | ||
49 | if (x > y) \ | ||
50 | printk(format, ## arg); \ | ||
51 | } \ | ||
52 | } while(0) | ||
53 | |||
54 | |||
55 | static DEFINE_MUTEX(dst_ca_mutex); | ||
56 | static unsigned int verbose = 5; | ||
57 | module_param(verbose, int, 0644); | ||
58 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); | ||
59 | |||
60 | /* Need some more work */ | ||
61 | static int ca_set_slot_descr(void) | ||
62 | { | ||
63 | /* We could make this more graceful ? */ | ||
64 | return -EOPNOTSUPP; | ||
65 | } | ||
66 | |||
67 | /* Need some more work */ | ||
68 | static int ca_set_pid(void) | ||
69 | { | ||
70 | /* We could make this more graceful ? */ | ||
71 | return -EOPNOTSUPP; | ||
72 | } | ||
73 | |||
74 | static void put_command_and_length(u8 *data, int command, int length) | ||
75 | { | ||
76 | data[0] = (command >> 16) & 0xff; | ||
77 | data[1] = (command >> 8) & 0xff; | ||
78 | data[2] = command & 0xff; | ||
79 | data[3] = length; | ||
80 | } | ||
81 | |||
82 | static void put_checksum(u8 *check_string, int length) | ||
83 | { | ||
84 | dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum."); | ||
85 | dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length); | ||
86 | check_string[length] = dst_check_sum (check_string, length); | ||
87 | dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]); | ||
88 | } | ||
89 | |||
90 | static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) | ||
91 | { | ||
92 | u8 reply; | ||
93 | |||
94 | mutex_lock(&state->dst_mutex); | ||
95 | dst_comm_init(state); | ||
96 | msleep(65); | ||
97 | |||
98 | if (write_dst(state, data, len)) { | ||
99 | dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); | ||
100 | dst_error_recovery(state); | ||
101 | goto error; | ||
102 | } | ||
103 | if ((dst_pio_disable(state)) < 0) { | ||
104 | dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); | ||
105 | goto error; | ||
106 | } | ||
107 | if (read_dst(state, &reply, GET_ACK) < 0) { | ||
108 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | ||
109 | dst_error_recovery(state); | ||
110 | goto error; | ||
111 | } | ||
112 | if (read) { | ||
113 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { | ||
114 | dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); | ||
115 | goto error; | ||
116 | } | ||
117 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ | ||
118 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | ||
119 | dst_error_recovery(state); | ||
120 | goto error; | ||
121 | } | ||
122 | } | ||
123 | mutex_unlock(&state->dst_mutex); | ||
124 | return 0; | ||
125 | |||
126 | error: | ||
127 | mutex_unlock(&state->dst_mutex); | ||
128 | return -EIO; | ||
129 | } | ||
130 | |||
131 | |||
132 | static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read) | ||
133 | { | ||
134 | u8 dst_ca_comm_err = 0; | ||
135 | |||
136 | while (dst_ca_comm_err < RETRIES) { | ||
137 | dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); | ||
138 | if (dst_ci_command(state, data, ca_string, len, read)) { // If error | ||
139 | dst_error_recovery(state); | ||
140 | dst_ca_comm_err++; // work required here. | ||
141 | } else { | ||
142 | break; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | if(dst_ca_comm_err == RETRIES) | ||
147 | return -1; | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | |||
153 | |||
154 | static int ca_get_app_info(struct dst_state *state) | ||
155 | { | ||
156 | int length, str_length; | ||
157 | static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; | ||
158 | |||
159 | put_checksum(&command[0], command[0]); | ||
160 | if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) { | ||
161 | dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); | ||
162 | return -1; | ||
163 | } | ||
164 | dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); | ||
165 | dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================"); | ||
166 | dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]", | ||
167 | state->messages[7], (state->messages[8] << 8) | state->messages[9], | ||
168 | (state->messages[10] << 8) | state->messages[11], __func__, (char *)(&state->messages[12])); | ||
169 | dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); | ||
170 | |||
171 | // Transform dst message to correct application_info message | ||
172 | length = state->messages[5]; | ||
173 | str_length = length - 6; | ||
174 | if (str_length < 0) { | ||
175 | str_length = 0; | ||
176 | dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering."); | ||
177 | } | ||
178 | |||
179 | // First, the command and length fields | ||
180 | put_command_and_length(&state->messages[0], CA_APP_INFO, length); | ||
181 | |||
182 | // Copy application_type, application_manufacturer and manufacturer_code | ||
183 | memcpy(&state->messages[4], &state->messages[7], 5); | ||
184 | |||
185 | // Set string length and copy string | ||
186 | state->messages[9] = str_length; | ||
187 | memcpy(&state->messages[10], &state->messages[12], str_length); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int ca_get_ca_info(struct dst_state *state) | ||
193 | { | ||
194 | int srcPtr, dstPtr, i, num_ids; | ||
195 | static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff}; | ||
196 | const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7; | ||
197 | |||
198 | put_checksum(&slot_command[0], slot_command[0]); | ||
199 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) { | ||
200 | dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); | ||
201 | return -1; | ||
202 | } | ||
203 | dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); | ||
204 | |||
205 | // Print raw data | ||
206 | dprintk(verbose, DST_CA_INFO, 0, " DST data = ["); | ||
207 | for (i = 0; i < state->messages[0] + 1; i++) { | ||
208 | dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]); | ||
209 | } | ||
210 | dprintk(verbose, DST_CA_INFO, 0, "]\n"); | ||
211 | |||
212 | // Set the command and length of the output | ||
213 | num_ids = state->messages[in_num_ids_pos]; | ||
214 | if (num_ids >= 100) { | ||
215 | num_ids = 100; | ||
216 | dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering."); | ||
217 | } | ||
218 | put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2); | ||
219 | |||
220 | dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = ["); | ||
221 | srcPtr = in_system_id_pos; | ||
222 | dstPtr = out_system_id_pos; | ||
223 | for(i = 0; i < num_ids; i++) { | ||
224 | dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]); | ||
225 | // Append to output | ||
226 | state->messages[dstPtr + 0] = state->messages[srcPtr + 0]; | ||
227 | state->messages[dstPtr + 1] = state->messages[srcPtr + 1]; | ||
228 | srcPtr += 2; | ||
229 | dstPtr += 2; | ||
230 | } | ||
231 | dprintk(verbose, DST_CA_INFO, 0, "]\n"); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg) | ||
237 | { | ||
238 | int i; | ||
239 | u8 slot_cap[256]; | ||
240 | static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff}; | ||
241 | |||
242 | put_checksum(&slot_command[0], slot_command[0]); | ||
243 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) { | ||
244 | dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); | ||
245 | return -1; | ||
246 | } | ||
247 | dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !"); | ||
248 | |||
249 | /* Will implement the rest soon */ | ||
250 | |||
251 | dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); | ||
252 | dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); | ||
253 | for (i = 0; i < slot_cap[0] + 1; i++) | ||
254 | dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); | ||
255 | dprintk(verbose, DST_CA_INFO, 0, "\n"); | ||
256 | |||
257 | p_ca_caps->slot_num = 1; | ||
258 | p_ca_caps->slot_type = 1; | ||
259 | p_ca_caps->descr_num = slot_cap[7]; | ||
260 | p_ca_caps->descr_type = 1; | ||
261 | |||
262 | if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps))) | ||
263 | return -EFAULT; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | /* Need some more work */ | ||
269 | static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) | ||
270 | { | ||
271 | return -EOPNOTSUPP; | ||
272 | } | ||
273 | |||
274 | |||
275 | static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg) | ||
276 | { | ||
277 | int i; | ||
278 | static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | ||
279 | |||
280 | u8 *slot_info = state->messages; | ||
281 | |||
282 | put_checksum(&slot_command[0], 7); | ||
283 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { | ||
284 | dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); | ||
285 | return -1; | ||
286 | } | ||
287 | dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); | ||
288 | |||
289 | /* Will implement the rest soon */ | ||
290 | |||
291 | dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]); | ||
292 | dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); | ||
293 | for (i = 0; i < 8; i++) | ||
294 | dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]); | ||
295 | dprintk(verbose, DST_CA_INFO, 0, "\n"); | ||
296 | |||
297 | if (slot_info[4] & 0x80) { | ||
298 | p_ca_slot_info->flags = CA_CI_MODULE_PRESENT; | ||
299 | p_ca_slot_info->num = 1; | ||
300 | p_ca_slot_info->type = CA_CI; | ||
301 | } else if (slot_info[4] & 0x40) { | ||
302 | p_ca_slot_info->flags = CA_CI_MODULE_READY; | ||
303 | p_ca_slot_info->num = 1; | ||
304 | p_ca_slot_info->type = CA_CI; | ||
305 | } else | ||
306 | p_ca_slot_info->flags = 0; | ||
307 | |||
308 | if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info))) | ||
309 | return -EFAULT; | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | |||
315 | static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) | ||
316 | { | ||
317 | u8 i = 0; | ||
318 | u32 command = 0; | ||
319 | |||
320 | if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) | ||
321 | return -EFAULT; | ||
322 | |||
323 | if (p_ca_message->msg) { | ||
324 | dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%*ph]", | ||
325 | 3, p_ca_message->msg); | ||
326 | |||
327 | for (i = 0; i < 3; i++) { | ||
328 | command = command | p_ca_message->msg[i]; | ||
329 | if (i < 2) | ||
330 | command = command << 8; | ||
331 | } | ||
332 | dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command); | ||
333 | |||
334 | switch (command) { | ||
335 | case CA_APP_INFO: | ||
336 | memcpy(p_ca_message->msg, state->messages, 128); | ||
337 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) | ||
338 | return -EFAULT; | ||
339 | break; | ||
340 | case CA_INFO: | ||
341 | memcpy(p_ca_message->msg, state->messages, 128); | ||
342 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) | ||
343 | return -EFAULT; | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length) | ||
352 | { | ||
353 | if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) { | ||
354 | hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */ | ||
355 | hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */ | ||
356 | } else { | ||
357 | if (length > 247) { | ||
358 | dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !"); | ||
359 | return -1; | ||
360 | } | ||
361 | hw_buffer->msg[0] = (length & 0xff) + 7; | ||
362 | hw_buffer->msg[1] = 0x40; | ||
363 | hw_buffer->msg[2] = 0x03; | ||
364 | hw_buffer->msg[3] = 0x00; | ||
365 | hw_buffer->msg[4] = 0x03; | ||
366 | hw_buffer->msg[5] = length & 0xff; | ||
367 | hw_buffer->msg[6] = 0x00; | ||
368 | |||
369 | /* | ||
370 | * Need to compute length for EN50221 section 8.3.2, for the time being | ||
371 | * assuming 8.3.2 is not applicable | ||
372 | */ | ||
373 | memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); | ||
374 | } | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) | ||
380 | { | ||
381 | if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { | ||
382 | dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed."); | ||
383 | dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST."); | ||
384 | rdc_reset_state(state); | ||
385 | return -1; | ||
386 | } | ||
387 | dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success."); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static u32 asn_1_decode(u8 *asn_1_array) | ||
393 | { | ||
394 | u8 length_field = 0, word_count = 0, count = 0; | ||
395 | u32 length = 0; | ||
396 | |||
397 | length_field = asn_1_array[0]; | ||
398 | dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field); | ||
399 | if (length_field < 0x80) { | ||
400 | length = length_field & 0x7f; | ||
401 | dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length); | ||
402 | } else { | ||
403 | word_count = length_field & 0x7f; | ||
404 | for (count = 0; count < word_count; count++) { | ||
405 | length = length << 8; | ||
406 | length += asn_1_array[count + 1]; | ||
407 | dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); | ||
408 | } | ||
409 | } | ||
410 | return length; | ||
411 | } | ||
412 | |||
413 | static int debug_string(u8 *msg, u32 length, u32 offset) | ||
414 | { | ||
415 | u32 i; | ||
416 | |||
417 | dprintk(verbose, DST_CA_DEBUG, 0, " String=[ "); | ||
418 | for (i = offset; i < length; i++) | ||
419 | dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]); | ||
420 | dprintk(verbose, DST_CA_DEBUG, 0, "]\n"); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | |||
426 | static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) | ||
427 | { | ||
428 | u32 length = 0; | ||
429 | u8 tag_length = 8; | ||
430 | |||
431 | length = asn_1_decode(&p_ca_message->msg[3]); | ||
432 | dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length); | ||
433 | debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */ | ||
434 | |||
435 | memset(hw_buffer->msg, '\0', length); | ||
436 | handle_dst_tag(state, p_ca_message, hw_buffer, length); | ||
437 | put_checksum(hw_buffer->msg, hw_buffer->msg[0]); | ||
438 | |||
439 | debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */ | ||
440 | write_to_8820(state, hw_buffer, (length + tag_length), reply); | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | |||
446 | /* Board supports CA PMT reply ? */ | ||
447 | static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) | ||
448 | { | ||
449 | int ca_pmt_reply_test = 0; | ||
450 | |||
451 | /* Do test board */ | ||
452 | /* Not there yet but soon */ | ||
453 | |||
454 | /* CA PMT Reply capable */ | ||
455 | if (ca_pmt_reply_test) { | ||
456 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) { | ||
457 | dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !"); | ||
458 | return -1; | ||
459 | } | ||
460 | |||
461 | /* Process CA PMT Reply */ | ||
462 | /* will implement soon */ | ||
463 | dprintk(verbose, DST_CA_ERROR, 1, " Not there yet"); | ||
464 | } | ||
465 | /* CA PMT Reply not capable */ | ||
466 | if (!ca_pmt_reply_test) { | ||
467 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) { | ||
468 | dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !"); | ||
469 | return -1; | ||
470 | } | ||
471 | dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !"); | ||
472 | /* put a dummy message */ | ||
473 | |||
474 | } | ||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) | ||
479 | { | ||
480 | int i = 0; | ||
481 | |||
482 | u32 command = 0; | ||
483 | struct ca_msg *hw_buffer; | ||
484 | int result = 0; | ||
485 | |||
486 | if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | ||
487 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | ||
488 | return -ENOMEM; | ||
489 | } | ||
490 | dprintk(verbose, DST_CA_DEBUG, 1, " "); | ||
491 | |||
492 | if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) { | ||
493 | result = -EFAULT; | ||
494 | goto free_mem_and_exit; | ||
495 | } | ||
496 | |||
497 | |||
498 | if (p_ca_message->msg) { | ||
499 | /* EN50221 tag */ | ||
500 | command = 0; | ||
501 | |||
502 | for (i = 0; i < 3; i++) { | ||
503 | command = command | p_ca_message->msg[i]; | ||
504 | if (i < 2) | ||
505 | command = command << 8; | ||
506 | } | ||
507 | dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command); | ||
508 | |||
509 | switch (command) { | ||
510 | case CA_PMT: | ||
511 | dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); | ||
512 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started | ||
513 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); | ||
514 | result = -1; | ||
515 | goto free_mem_and_exit; | ||
516 | } | ||
517 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); | ||
518 | break; | ||
519 | case CA_PMT_REPLY: | ||
520 | dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY"); | ||
521 | /* Have to handle the 2 basic types of cards here */ | ||
522 | if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { | ||
523 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); | ||
524 | result = -1; | ||
525 | goto free_mem_and_exit; | ||
526 | } | ||
527 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); | ||
528 | break; | ||
529 | case CA_APP_INFO_ENQUIRY: // only for debugging | ||
530 | dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information"); | ||
531 | |||
532 | if ((ca_get_app_info(state)) < 0) { | ||
533 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); | ||
534 | result = -1; | ||
535 | goto free_mem_and_exit; | ||
536 | } | ||
537 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); | ||
538 | break; | ||
539 | case CA_INFO_ENQUIRY: | ||
540 | dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information"); | ||
541 | |||
542 | if ((ca_get_ca_info(state)) < 0) { | ||
543 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !"); | ||
544 | result = -1; | ||
545 | goto free_mem_and_exit; | ||
546 | } | ||
547 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !"); | ||
548 | break; | ||
549 | } | ||
550 | } | ||
551 | free_mem_and_exit: | ||
552 | kfree (hw_buffer); | ||
553 | |||
554 | return result; | ||
555 | } | ||
556 | |||
557 | static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg) | ||
558 | { | ||
559 | struct dvb_device *dvbdev; | ||
560 | struct dst_state *state; | ||
561 | struct ca_slot_info *p_ca_slot_info; | ||
562 | struct ca_caps *p_ca_caps; | ||
563 | struct ca_msg *p_ca_message; | ||
564 | void __user *arg = (void __user *)ioctl_arg; | ||
565 | int result = 0; | ||
566 | |||
567 | mutex_lock(&dst_ca_mutex); | ||
568 | dvbdev = file->private_data; | ||
569 | state = (struct dst_state *)dvbdev->priv; | ||
570 | p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); | ||
571 | p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); | ||
572 | p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); | ||
573 | if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) { | ||
574 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | ||
575 | result = -ENOMEM; | ||
576 | goto free_mem_and_exit; | ||
577 | } | ||
578 | |||
579 | /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ | ||
580 | switch (cmd) { | ||
581 | case CA_SEND_MSG: | ||
582 | dprintk(verbose, DST_CA_INFO, 1, " Sending message"); | ||
583 | if ((ca_send_message(state, p_ca_message, arg)) < 0) { | ||
584 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); | ||
585 | result = -1; | ||
586 | goto free_mem_and_exit; | ||
587 | } | ||
588 | break; | ||
589 | case CA_GET_MSG: | ||
590 | dprintk(verbose, DST_CA_INFO, 1, " Getting message"); | ||
591 | if ((ca_get_message(state, p_ca_message, arg)) < 0) { | ||
592 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); | ||
593 | result = -1; | ||
594 | goto free_mem_and_exit; | ||
595 | } | ||
596 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); | ||
597 | break; | ||
598 | case CA_RESET: | ||
599 | dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST"); | ||
600 | dst_error_bailout(state); | ||
601 | msleep(4000); | ||
602 | break; | ||
603 | case CA_GET_SLOT_INFO: | ||
604 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); | ||
605 | if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { | ||
606 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); | ||
607 | result = -1; | ||
608 | goto free_mem_and_exit; | ||
609 | } | ||
610 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); | ||
611 | break; | ||
612 | case CA_GET_CAP: | ||
613 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); | ||
614 | if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { | ||
615 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); | ||
616 | result = -1; | ||
617 | goto free_mem_and_exit; | ||
618 | } | ||
619 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); | ||
620 | break; | ||
621 | case CA_GET_DESCR_INFO: | ||
622 | dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); | ||
623 | if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { | ||
624 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); | ||
625 | result = -1; | ||
626 | goto free_mem_and_exit; | ||
627 | } | ||
628 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); | ||
629 | break; | ||
630 | case CA_SET_DESCR: | ||
631 | dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); | ||
632 | if ((ca_set_slot_descr()) < 0) { | ||
633 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); | ||
634 | result = -1; | ||
635 | goto free_mem_and_exit; | ||
636 | } | ||
637 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); | ||
638 | break; | ||
639 | case CA_SET_PID: | ||
640 | dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); | ||
641 | if ((ca_set_pid()) < 0) { | ||
642 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); | ||
643 | result = -1; | ||
644 | goto free_mem_and_exit; | ||
645 | } | ||
646 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); | ||
647 | default: | ||
648 | result = -EOPNOTSUPP; | ||
649 | }; | ||
650 | free_mem_and_exit: | ||
651 | kfree (p_ca_message); | ||
652 | kfree (p_ca_slot_info); | ||
653 | kfree (p_ca_caps); | ||
654 | |||
655 | mutex_unlock(&dst_ca_mutex); | ||
656 | return result; | ||
657 | } | ||
658 | |||
659 | static int dst_ca_open(struct inode *inode, struct file *file) | ||
660 | { | ||
661 | dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file); | ||
662 | try_module_get(THIS_MODULE); | ||
663 | |||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static int dst_ca_release(struct inode *inode, struct file *file) | ||
668 | { | ||
669 | dprintk(verbose, DST_CA_DEBUG, 1, " Device closed."); | ||
670 | module_put(THIS_MODULE); | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) | ||
676 | { | ||
677 | ssize_t bytes_read = 0; | ||
678 | |||
679 | dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); | ||
680 | |||
681 | return bytes_read; | ||
682 | } | ||
683 | |||
684 | static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset) | ||
685 | { | ||
686 | dprintk(verbose, DST_CA_DEBUG, 1, " Device write."); | ||
687 | |||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | static const struct file_operations dst_ca_fops = { | ||
692 | .owner = THIS_MODULE, | ||
693 | .unlocked_ioctl = dst_ca_ioctl, | ||
694 | .open = dst_ca_open, | ||
695 | .release = dst_ca_release, | ||
696 | .read = dst_ca_read, | ||
697 | .write = dst_ca_write, | ||
698 | .llseek = noop_llseek, | ||
699 | }; | ||
700 | |||
701 | static struct dvb_device dvbdev_ca = { | ||
702 | .priv = NULL, | ||
703 | .users = 1, | ||
704 | .readers = 1, | ||
705 | .writers = 1, | ||
706 | .fops = &dst_ca_fops | ||
707 | }; | ||
708 | |||
709 | struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter) | ||
710 | { | ||
711 | struct dvb_device *dvbdev; | ||
712 | |||
713 | dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device"); | ||
714 | if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) { | ||
715 | dst->dst_ca = dvbdev; | ||
716 | return dst->dst_ca; | ||
717 | } | ||
718 | |||
719 | return NULL; | ||
720 | } | ||
721 | |||
722 | EXPORT_SYMBOL(dst_ca_attach); | ||
723 | |||
724 | MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver"); | ||
725 | MODULE_AUTHOR("Manu Abraham"); | ||
726 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/bt8xx/dst_ca.h b/drivers/media/dvb/bt8xx/dst_ca.h deleted file mode 100644 index 59cd0ddd6d8e..000000000000 --- a/drivers/media/dvb/bt8xx/dst_ca.h +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | CA-driver for TwinHan DST Frontend/Card | ||
3 | |||
4 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef _DST_CA_H_ | ||
22 | #define _DST_CA_H_ | ||
23 | |||
24 | #define RETRIES 5 | ||
25 | |||
26 | |||
27 | #define CA_APP_INFO_ENQUIRY 0x9f8020 | ||
28 | #define CA_APP_INFO 0x9f8021 | ||
29 | #define CA_ENTER_MENU 0x9f8022 | ||
30 | #define CA_INFO_ENQUIRY 0x9f8030 | ||
31 | #define CA_INFO 0x9f8031 | ||
32 | #define CA_PMT 0x9f8032 | ||
33 | #define CA_PMT_REPLY 0x9f8033 | ||
34 | |||
35 | #define CA_CLOSE_MMI 0x9f8800 | ||
36 | #define CA_DISPLAY_CONTROL 0x9f8801 | ||
37 | #define CA_DISPLAY_REPLY 0x9f8802 | ||
38 | #define CA_TEXT_LAST 0x9f8803 | ||
39 | #define CA_TEXT_MORE 0x9f8804 | ||
40 | #define CA_KEYPAD_CONTROL 0x9f8805 | ||
41 | #define CA_KEYPRESS 0x9f8806 | ||
42 | |||
43 | #define CA_ENQUIRY 0x9f8807 | ||
44 | #define CA_ANSWER 0x9f8808 | ||
45 | #define CA_MENU_LAST 0x9f8809 | ||
46 | #define CA_MENU_MORE 0x9f880a | ||
47 | #define CA_MENU_ANSWER 0x9f880b | ||
48 | #define CA_LIST_LAST 0x9f880c | ||
49 | #define CA_LIST_MORE 0x9f880d | ||
50 | |||
51 | |||
52 | struct dst_ca_private { | ||
53 | struct dst_state *dst; | ||
54 | struct dvb_device *dvbdev; | ||
55 | }; | ||
56 | |||
57 | |||
58 | #endif | ||
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h deleted file mode 100644 index d70d98f1a571..000000000000 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | /* | ||
2 | Frontend-driver for TwinHan DST Frontend | ||
3 | |||
4 | Copyright (C) 2003 Jamie Honan | ||
5 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef DST_COMMON_H | ||
23 | #define DST_COMMON_H | ||
24 | |||
25 | #include <linux/dvb/frontend.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include "bt878.h" | ||
29 | |||
30 | #include "dst_ca.h" | ||
31 | |||
32 | |||
33 | #define NO_DELAY 0 | ||
34 | #define LONG_DELAY 1 | ||
35 | #define DEVICE_INIT 2 | ||
36 | |||
37 | #define DELAY 1 | ||
38 | |||
39 | #define DST_TYPE_IS_SAT 0 | ||
40 | #define DST_TYPE_IS_TERR 1 | ||
41 | #define DST_TYPE_IS_CABLE 2 | ||
42 | #define DST_TYPE_IS_ATSC 3 | ||
43 | |||
44 | #define DST_TYPE_HAS_TS188 1 | ||
45 | #define DST_TYPE_HAS_TS204 2 | ||
46 | #define DST_TYPE_HAS_SYMDIV 4 | ||
47 | #define DST_TYPE_HAS_FW_1 8 | ||
48 | #define DST_TYPE_HAS_FW_2 16 | ||
49 | #define DST_TYPE_HAS_FW_3 32 | ||
50 | #define DST_TYPE_HAS_FW_BUILD 64 | ||
51 | #define DST_TYPE_HAS_OBS_REGS 128 | ||
52 | #define DST_TYPE_HAS_INC_COUNT 256 | ||
53 | #define DST_TYPE_HAS_MULTI_FE 512 | ||
54 | #define DST_TYPE_HAS_NEWTUNE_2 1024 | ||
55 | #define DST_TYPE_HAS_DBOARD 2048 | ||
56 | #define DST_TYPE_HAS_VLF 4096 | ||
57 | |||
58 | /* Card capability list */ | ||
59 | |||
60 | #define DST_TYPE_HAS_MAC 1 | ||
61 | #define DST_TYPE_HAS_DISEQC3 2 | ||
62 | #define DST_TYPE_HAS_DISEQC4 4 | ||
63 | #define DST_TYPE_HAS_DISEQC5 8 | ||
64 | #define DST_TYPE_HAS_MOTO 16 | ||
65 | #define DST_TYPE_HAS_CA 32 | ||
66 | #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ | ||
67 | #define DST_TYPE_HAS_SESSION 128 | ||
68 | |||
69 | #define TUNER_TYPE_MULTI 1 | ||
70 | #define TUNER_TYPE_UNKNOWN 2 | ||
71 | /* DVB-S */ | ||
72 | #define TUNER_TYPE_L64724 4 | ||
73 | #define TUNER_TYPE_STV0299 8 | ||
74 | #define TUNER_TYPE_MB86A15 16 | ||
75 | |||
76 | /* DVB-T */ | ||
77 | #define TUNER_TYPE_TDA10046 32 | ||
78 | |||
79 | /* ATSC */ | ||
80 | #define TUNER_TYPE_NXT200x 64 | ||
81 | |||
82 | |||
83 | #define RDC_8820_PIO_0_DISABLE 0 | ||
84 | #define RDC_8820_PIO_0_ENABLE 1 | ||
85 | #define RDC_8820_INT 2 | ||
86 | #define RDC_8820_RESET 4 | ||
87 | |||
88 | /* DST Communication */ | ||
89 | #define GET_REPLY 1 | ||
90 | #define NO_REPLY 0 | ||
91 | |||
92 | #define GET_ACK 1 | ||
93 | #define FIXED_COMM 8 | ||
94 | |||
95 | #define ACK 0xff | ||
96 | |||
97 | struct dst_state { | ||
98 | |||
99 | struct i2c_adapter* i2c; | ||
100 | |||
101 | struct bt878* bt; | ||
102 | |||
103 | /* configuration settings */ | ||
104 | const struct dst_config* config; | ||
105 | |||
106 | struct dvb_frontend frontend; | ||
107 | |||
108 | /* private ASIC data */ | ||
109 | u8 tx_tuna[10]; | ||
110 | u8 rx_tuna[10]; | ||
111 | u8 rxbuffer[10]; | ||
112 | u8 diseq_flags; | ||
113 | u8 dst_type; | ||
114 | u32 type_flags; | ||
115 | u32 frequency; /* intermediate frequency in kHz for QPSK */ | ||
116 | fe_spectral_inversion_t inversion; | ||
117 | u32 symbol_rate; /* symbol rate in Symbols per second */ | ||
118 | fe_code_rate_t fec; | ||
119 | fe_sec_voltage_t voltage; | ||
120 | fe_sec_tone_mode_t tone; | ||
121 | u32 decode_freq; | ||
122 | u8 decode_lock; | ||
123 | u16 decode_strength; | ||
124 | u16 decode_snr; | ||
125 | unsigned long cur_jiff; | ||
126 | u8 k22; | ||
127 | u32 bandwidth; | ||
128 | u32 dst_hw_cap; | ||
129 | u8 dst_fw_version; | ||
130 | fe_sec_mini_cmd_t minicmd; | ||
131 | fe_modulation_t modulation; | ||
132 | u8 messages[256]; | ||
133 | u8 mac_address[8]; | ||
134 | u8 fw_version[8]; | ||
135 | u8 card_info[8]; | ||
136 | u8 vendor[8]; | ||
137 | u8 board_info[8]; | ||
138 | u32 tuner_type; | ||
139 | char *tuner_name; | ||
140 | struct mutex dst_mutex; | ||
141 | u8 fw_name[8]; | ||
142 | struct dvb_device *dst_ca; | ||
143 | }; | ||
144 | |||
145 | struct tuner_types { | ||
146 | u32 tuner_type; | ||
147 | char *tuner_name; | ||
148 | char *board_name; | ||
149 | char *fw_name; | ||
150 | }; | ||
151 | |||
152 | struct dst_types { | ||
153 | char *device_id; | ||
154 | int offset; | ||
155 | u8 dst_type; | ||
156 | u32 type_flags; | ||
157 | u32 dst_feature; | ||
158 | u32 tuner_type; | ||
159 | }; | ||
160 | |||
161 | struct dst_config | ||
162 | { | ||
163 | /* the ASIC i2c address */ | ||
164 | u8 demod_address; | ||
165 | }; | ||
166 | |||
167 | int rdc_reset_state(struct dst_state *state); | ||
168 | |||
169 | int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode); | ||
170 | int dst_pio_disable(struct dst_state *state); | ||
171 | int dst_error_recovery(struct dst_state* state); | ||
172 | int dst_error_bailout(struct dst_state *state); | ||
173 | int dst_comm_init(struct dst_state* state); | ||
174 | |||
175 | int write_dst(struct dst_state *state, u8 * data, u8 len); | ||
176 | int read_dst(struct dst_state *state, u8 * ret, u8 len); | ||
177 | u8 dst_check_sum(u8 * buf, u32 len); | ||
178 | struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter); | ||
179 | struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter); | ||
180 | |||
181 | |||
182 | #endif // DST_COMMON_H | ||
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h deleted file mode 100644 index 3974a4c6ebe7..000000000000 --- a/drivers/media/dvb/bt8xx/dst_priv.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend | ||
3 | * | ||
4 | * Copyright (C) 2003 Jamie Honan | ||
5 | */ | ||
6 | |||
7 | struct dst_gpio_enable { | ||
8 | u32 mask; | ||
9 | u32 enable; | ||
10 | }; | ||
11 | |||
12 | struct dst_gpio_output { | ||
13 | u32 mask; | ||
14 | u32 highvals; | ||
15 | }; | ||
16 | |||
17 | struct dst_gpio_read { | ||
18 | unsigned long value; | ||
19 | }; | ||
20 | |||
21 | union dst_gpio_packet { | ||
22 | struct dst_gpio_enable enb; | ||
23 | struct dst_gpio_output outp; | ||
24 | struct dst_gpio_read rd; | ||
25 | int psize; | ||
26 | }; | ||
27 | |||
28 | #define DST_IG_ENABLE 0 | ||
29 | #define DST_IG_WRITE 1 | ||
30 | #define DST_IG_READ 2 | ||
31 | #define DST_IG_TS 3 | ||
32 | |||
33 | struct bt878; | ||
34 | |||
35 | int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); | ||
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c deleted file mode 100644 index 81fab9adc1ca..000000000000 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ /dev/null | |||
@@ -1,975 +0,0 @@ | |||
1 | /* | ||
2 | * Bt8xx based DVB adapter driver | ||
3 | * | ||
4 | * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #define pr_fmt(fmt) "dvb_bt8xx: " fmt | ||
23 | |||
24 | #include <linux/bitops.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/i2c.h> | ||
32 | |||
33 | #include "dmxdev.h" | ||
34 | #include "dvbdev.h" | ||
35 | #include "dvb_demux.h" | ||
36 | #include "dvb_frontend.h" | ||
37 | #include "dvb-bt8xx.h" | ||
38 | #include "bt878.h" | ||
39 | |||
40 | static int debug; | ||
41 | |||
42 | module_param(debug, int, 0644); | ||
43 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | ||
44 | |||
45 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
46 | |||
47 | #define dprintk( args... ) \ | ||
48 | do { \ | ||
49 | if (debug) printk(KERN_DEBUG args); \ | ||
50 | } while (0) | ||
51 | |||
52 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ | ||
53 | |||
54 | static void dvb_bt8xx_task(unsigned long data) | ||
55 | { | ||
56 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data; | ||
57 | |||
58 | //printk("%d ", card->bt->finished_block); | ||
59 | |||
60 | while (card->bt->last_block != card->bt->finished_block) { | ||
61 | (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) | ||
62 | (&card->demux, | ||
63 | &card->bt->buf_cpu[card->bt->last_block * | ||
64 | card->bt->block_bytes], | ||
65 | card->bt->block_bytes); | ||
66 | card->bt->last_block = (card->bt->last_block + 1) % | ||
67 | card->bt->block_count; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
72 | { | ||
73 | struct dvb_demux*dvbdmx = dvbdmxfeed->demux; | ||
74 | struct dvb_bt8xx_card *card = dvbdmx->priv; | ||
75 | int rc; | ||
76 | |||
77 | dprintk("dvb_bt8xx: start_feed\n"); | ||
78 | |||
79 | if (!dvbdmx->dmx.frontend) | ||
80 | return -EINVAL; | ||
81 | |||
82 | mutex_lock(&card->lock); | ||
83 | card->nfeeds++; | ||
84 | rc = card->nfeeds; | ||
85 | if (card->nfeeds == 1) | ||
86 | bt878_start(card->bt, card->gpio_mode, | ||
87 | card->op_sync_orin, card->irq_err_ignore); | ||
88 | mutex_unlock(&card->lock); | ||
89 | return rc; | ||
90 | } | ||
91 | |||
92 | static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
93 | { | ||
94 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
95 | struct dvb_bt8xx_card *card = dvbdmx->priv; | ||
96 | |||
97 | dprintk("dvb_bt8xx: stop_feed\n"); | ||
98 | |||
99 | if (!dvbdmx->dmx.frontend) | ||
100 | return -EINVAL; | ||
101 | |||
102 | mutex_lock(&card->lock); | ||
103 | card->nfeeds--; | ||
104 | if (card->nfeeds == 0) | ||
105 | bt878_stop(card->bt); | ||
106 | mutex_unlock(&card->lock); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev) | ||
112 | { | ||
113 | if ((adev->subsystem_vendor == bdev->subsystem_vendor) && | ||
114 | (adev->subsystem_device == bdev->subsystem_device) && | ||
115 | (adev->bus->number == bdev->bus->number) && | ||
116 | (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn))) | ||
117 | return 1; | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) | ||
122 | { | ||
123 | unsigned int card_nr; | ||
124 | |||
125 | /* Hmm, n squared. Hope n is small */ | ||
126 | for (card_nr = 0; card_nr < bt878_num; card_nr++) | ||
127 | if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev)) | ||
128 | return &bt878[card_nr]; | ||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) | ||
133 | { | ||
134 | static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 }; | ||
135 | static u8 mt352_reset [] = { 0x50, 0x80 }; | ||
136 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | ||
137 | static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 }; | ||
138 | static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 }; | ||
139 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; | ||
140 | |||
141 | mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); | ||
142 | udelay(2000); | ||
143 | mt352_write(fe, mt352_reset, sizeof(mt352_reset)); | ||
144 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); | ||
145 | |||
146 | mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); | ||
147 | mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); | ||
148 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend *fe, u8* pllbuf, int buf_len) | ||
154 | { | ||
155 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
156 | u32 div; | ||
157 | unsigned char bs = 0; | ||
158 | unsigned char cp = 0; | ||
159 | |||
160 | if (buf_len < 5) | ||
161 | return -EINVAL; | ||
162 | |||
163 | div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | ||
164 | |||
165 | if (c->frequency < 542000000) | ||
166 | cp = 0xb4; | ||
167 | else if (c->frequency < 771000000) | ||
168 | cp = 0xbc; | ||
169 | else | ||
170 | cp = 0xf4; | ||
171 | |||
172 | if (c->frequency == 0) | ||
173 | bs = 0x03; | ||
174 | else if (c->frequency < 443250000) | ||
175 | bs = 0x02; | ||
176 | else | ||
177 | bs = 0x08; | ||
178 | |||
179 | pllbuf[0] = 0x60; | ||
180 | pllbuf[1] = div >> 8; | ||
181 | pllbuf[2] = div & 0xff; | ||
182 | pllbuf[3] = cp; | ||
183 | pllbuf[4] = bs; | ||
184 | |||
185 | return 5; | ||
186 | } | ||
187 | |||
188 | static struct mt352_config thomson_dtt7579_config = { | ||
189 | .demod_address = 0x0f, | ||
190 | .demod_init = thomson_dtt7579_demod_init, | ||
191 | }; | ||
192 | |||
193 | static struct zl10353_config thomson_dtt7579_zl10353_config = { | ||
194 | .demod_address = 0x0f, | ||
195 | }; | ||
196 | |||
197 | static int cx24108_tuner_set_params(struct dvb_frontend *fe) | ||
198 | { | ||
199 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
200 | u32 freq = c->frequency; | ||
201 | int i, a, n, pump; | ||
202 | u32 band, pll; | ||
203 | u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, | ||
204 | 1576000,1718000,1856000,2036000,2150000}; | ||
205 | u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, | ||
206 | 0x00102000,0x00104000,0x00108000,0x00110000, | ||
207 | 0x00120000,0x00140000}; | ||
208 | |||
209 | #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ | ||
210 | dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n", freq); | ||
211 | |||
212 | /* This is really the bit driving the tuner chip cx24108 */ | ||
213 | |||
214 | if (freq<950000) | ||
215 | freq = 950000; /* kHz */ | ||
216 | else if (freq>2150000) | ||
217 | freq = 2150000; /* satellite IF is 950..2150MHz */ | ||
218 | |||
219 | /* decide which VCO to use for the input frequency */ | ||
220 | for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++); | ||
221 | dprintk("cx24108 debug: select vco #%d (f=%d)\n", i, freq); | ||
222 | band=bandsel[i]; | ||
223 | /* the gain values must be set by SetSymbolrate */ | ||
224 | /* compute the pll divider needed, from Conexant data sheet, | ||
225 | resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, | ||
226 | depending on the divider bit. It is set to /4 on the 2 lowest | ||
227 | bands */ | ||
228 | n=((i<=2?2:1)*freq*10L)/(XTAL/100); | ||
229 | a=n%32; n/=32; if(a==0) n--; | ||
230 | pump=(freq<(osci[i-1]+osci[i])/2); | ||
231 | pll=0xf8000000| | ||
232 | ((pump?1:2)<<(14+11))| | ||
233 | ((n&0x1ff)<<(5+11))| | ||
234 | ((a&0x1f)<<11); | ||
235 | /* everything is shifted left 11 bits to left-align the bits in the | ||
236 | 32bit word. Output to the tuner goes MSB-aligned, after all */ | ||
237 | dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n", pump, n, a); | ||
238 | cx24110_pll_write(fe,band); | ||
239 | /* set vga and vca to their widest-band settings, as a precaution. | ||
240 | SetSymbolrate might not be called to set this up */ | ||
241 | cx24110_pll_write(fe,0x500c0000); | ||
242 | cx24110_pll_write(fe,0x83f1f800); | ||
243 | cx24110_pll_write(fe,pll); | ||
244 | //writereg(client,0x56,0x7f); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int pinnsat_tuner_init(struct dvb_frontend* fe) | ||
250 | { | ||
251 | struct dvb_bt8xx_card *card = fe->dvb->priv; | ||
252 | |||
253 | bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */ | ||
254 | bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */ | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int pinnsat_tuner_sleep(struct dvb_frontend* fe) | ||
260 | { | ||
261 | struct dvb_bt8xx_card *card = fe->dvb->priv; | ||
262 | |||
263 | bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */ | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static struct cx24110_config pctvsat_config = { | ||
269 | .demod_address = 0x55, | ||
270 | }; | ||
271 | |||
272 | static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend *fe) | ||
273 | { | ||
274 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
275 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | ||
276 | u8 cfg, cpump, band_select; | ||
277 | u8 data[4]; | ||
278 | u32 div; | ||
279 | struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
280 | |||
281 | div = (36000000 + c->frequency + 83333) / 166666; | ||
282 | cfg = 0x88; | ||
283 | |||
284 | if (c->frequency < 175000000) | ||
285 | cpump = 2; | ||
286 | else if (c->frequency < 390000000) | ||
287 | cpump = 1; | ||
288 | else if (c->frequency < 470000000) | ||
289 | cpump = 2; | ||
290 | else if (c->frequency < 750000000) | ||
291 | cpump = 2; | ||
292 | else | ||
293 | cpump = 3; | ||
294 | |||
295 | if (c->frequency < 175000000) | ||
296 | band_select = 0x0e; | ||
297 | else if (c->frequency < 470000000) | ||
298 | band_select = 0x05; | ||
299 | else | ||
300 | band_select = 0x03; | ||
301 | |||
302 | data[0] = (div >> 8) & 0x7f; | ||
303 | data[1] = div & 0xff; | ||
304 | data[2] = ((div >> 10) & 0x60) | cfg; | ||
305 | data[3] = (cpump << 6) | band_select; | ||
306 | |||
307 | if (fe->ops.i2c_gate_ctrl) | ||
308 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
309 | i2c_transfer(card->i2c_adapter, &msg, 1); | ||
310 | return (div * 166666 - 36000000); | ||
311 | } | ||
312 | |||
313 | static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) | ||
314 | { | ||
315 | struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv; | ||
316 | |||
317 | return request_firmware(fw, name, &bt->bt->dev->dev); | ||
318 | } | ||
319 | |||
320 | static struct sp887x_config microtune_mt7202dtf_config = { | ||
321 | .demod_address = 0x70, | ||
322 | .request_firmware = microtune_mt7202dtf_request_firmware, | ||
323 | }; | ||
324 | |||
325 | static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | ||
326 | { | ||
327 | static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d }; | ||
328 | static u8 mt352_reset [] = { 0x50, 0x80 }; | ||
329 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | ||
330 | static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, | ||
331 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | ||
332 | static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; | ||
333 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; | ||
334 | |||
335 | mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); | ||
336 | udelay(2000); | ||
337 | mt352_write(fe, mt352_reset, sizeof(mt352_reset)); | ||
338 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); | ||
339 | |||
340 | mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg)); | ||
341 | udelay(2000); | ||
342 | mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra)); | ||
343 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len) | ||
349 | { | ||
350 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
351 | u32 div; | ||
352 | unsigned char bs = 0; | ||
353 | unsigned char cp = 0; | ||
354 | |||
355 | if (buf_len < 5) return -EINVAL; | ||
356 | |||
357 | div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | ||
358 | |||
359 | if (c->frequency < 150000000) | ||
360 | cp = 0xB4; | ||
361 | else if (c->frequency < 173000000) | ||
362 | cp = 0xBC; | ||
363 | else if (c->frequency < 250000000) | ||
364 | cp = 0xB4; | ||
365 | else if (c->frequency < 400000000) | ||
366 | cp = 0xBC; | ||
367 | else if (c->frequency < 420000000) | ||
368 | cp = 0xF4; | ||
369 | else if (c->frequency < 470000000) | ||
370 | cp = 0xFC; | ||
371 | else if (c->frequency < 600000000) | ||
372 | cp = 0xBC; | ||
373 | else if (c->frequency < 730000000) | ||
374 | cp = 0xF4; | ||
375 | else | ||
376 | cp = 0xFC; | ||
377 | |||
378 | if (c->frequency < 150000000) | ||
379 | bs = 0x01; | ||
380 | else if (c->frequency < 173000000) | ||
381 | bs = 0x01; | ||
382 | else if (c->frequency < 250000000) | ||
383 | bs = 0x02; | ||
384 | else if (c->frequency < 400000000) | ||
385 | bs = 0x02; | ||
386 | else if (c->frequency < 420000000) | ||
387 | bs = 0x02; | ||
388 | else if (c->frequency < 470000000) | ||
389 | bs = 0x02; | ||
390 | else if (c->frequency < 600000000) | ||
391 | bs = 0x08; | ||
392 | else if (c->frequency < 730000000) | ||
393 | bs = 0x08; | ||
394 | else | ||
395 | bs = 0x08; | ||
396 | |||
397 | pllbuf[0] = 0x61; | ||
398 | pllbuf[1] = div >> 8; | ||
399 | pllbuf[2] = div & 0xff; | ||
400 | pllbuf[3] = cp; | ||
401 | pllbuf[4] = bs; | ||
402 | |||
403 | return 5; | ||
404 | } | ||
405 | |||
406 | static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { | ||
407 | .demod_address = 0x0f, | ||
408 | .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, | ||
409 | }; | ||
410 | |||
411 | static struct dst_config dst_config = { | ||
412 | .demod_address = 0x55, | ||
413 | }; | ||
414 | |||
415 | static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) | ||
416 | { | ||
417 | struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv; | ||
418 | |||
419 | return request_firmware(fw, name, &bt->bt->dev->dev); | ||
420 | } | ||
421 | |||
422 | static void or51211_setmode(struct dvb_frontend * fe, int mode) | ||
423 | { | ||
424 | struct dvb_bt8xx_card *bt = fe->dvb->priv; | ||
425 | bttv_write_gpio(bt->bttv_nr, 0x0002, mode); /* Reset */ | ||
426 | msleep(20); | ||
427 | } | ||
428 | |||
429 | static void or51211_reset(struct dvb_frontend * fe) | ||
430 | { | ||
431 | struct dvb_bt8xx_card *bt = fe->dvb->priv; | ||
432 | |||
433 | /* RESET DEVICE | ||
434 | * reset is controlled by GPIO-0 | ||
435 | * when set to 0 causes reset and when to 1 for normal op | ||
436 | * must remain reset for 128 clock cycles on a 50Mhz clock | ||
437 | * also PRM1 PRM2 & PRM4 are controlled by GPIO-1,GPIO-2 & GPIO-4 | ||
438 | * We assume that the reset has be held low long enough or we | ||
439 | * have been reset by a power on. When the driver is unloaded | ||
440 | * reset set to 0 so if reloaded we have been reset. | ||
441 | */ | ||
442 | /* reset & PRM1,2&4 are outputs */ | ||
443 | int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F); | ||
444 | if (ret != 0) | ||
445 | printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret); | ||
446 | bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */ | ||
447 | msleep(20); | ||
448 | /* Now set for normal operation */ | ||
449 | bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001); | ||
450 | /* wait for operation to begin */ | ||
451 | msleep(500); | ||
452 | } | ||
453 | |||
454 | static void or51211_sleep(struct dvb_frontend * fe) | ||
455 | { | ||
456 | struct dvb_bt8xx_card *bt = fe->dvb->priv; | ||
457 | bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000); | ||
458 | } | ||
459 | |||
460 | static struct or51211_config or51211_config = { | ||
461 | .demod_address = 0x15, | ||
462 | .request_firmware = or51211_request_firmware, | ||
463 | .setmode = or51211_setmode, | ||
464 | .reset = or51211_reset, | ||
465 | .sleep = or51211_sleep, | ||
466 | }; | ||
467 | |||
468 | static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend *fe) | ||
469 | { | ||
470 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
471 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | ||
472 | u8 buf[4]; | ||
473 | u32 div; | ||
474 | struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
475 | |||
476 | div = (c->frequency + 36166667) / 166667; | ||
477 | |||
478 | buf[0] = (div >> 8) & 0x7F; | ||
479 | buf[1] = div & 0xFF; | ||
480 | buf[2] = 0x85; | ||
481 | if ((c->frequency >= 47000000) && (c->frequency < 153000000)) | ||
482 | buf[3] = 0x01; | ||
483 | else if ((c->frequency >= 153000000) && (c->frequency < 430000000)) | ||
484 | buf[3] = 0x02; | ||
485 | else if ((c->frequency >= 430000000) && (c->frequency < 824000000)) | ||
486 | buf[3] = 0x0C; | ||
487 | else if ((c->frequency >= 824000000) && (c->frequency < 863000000)) | ||
488 | buf[3] = 0x8C; | ||
489 | else | ||
490 | return -EINVAL; | ||
491 | |||
492 | if (fe->ops.i2c_gate_ctrl) | ||
493 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
494 | i2c_transfer(card->i2c_adapter, &msg, 1); | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static struct nxt6000_config vp3021_alps_tded4_config = { | ||
499 | .demod_address = 0x0a, | ||
500 | .clock_inversion = 1, | ||
501 | }; | ||
502 | |||
503 | static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) | ||
504 | { | ||
505 | static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d }; | ||
506 | static u8 mt352_reset [] = { 0x50, 0x80 }; | ||
507 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | ||
508 | static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 }; | ||
509 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; | ||
510 | |||
511 | mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); | ||
512 | udelay(2000); | ||
513 | mt352_write(fe, mt352_reset, sizeof(mt352_reset)); | ||
514 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); | ||
515 | mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg)); | ||
516 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len) | ||
522 | { | ||
523 | u32 div; | ||
524 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
525 | |||
526 | if (buf_len < 5) | ||
527 | return -EINVAL; | ||
528 | |||
529 | div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | ||
530 | |||
531 | pllbuf[0] = 0x61; | ||
532 | pllbuf[1] = (div >> 8) & 0x7F; | ||
533 | pllbuf[2] = div & 0xFF; | ||
534 | pllbuf[3] = 0x85; | ||
535 | |||
536 | dprintk("frequency %u, div %u\n", c->frequency, div); | ||
537 | |||
538 | if (c->frequency < 470000000) | ||
539 | pllbuf[4] = 0x02; | ||
540 | else if (c->frequency > 823000000) | ||
541 | pllbuf[4] = 0x88; | ||
542 | else | ||
543 | pllbuf[4] = 0x08; | ||
544 | |||
545 | if (c->bandwidth_hz == 8000000) | ||
546 | pllbuf[4] |= 0x04; | ||
547 | |||
548 | return 5; | ||
549 | } | ||
550 | |||
551 | static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) | ||
552 | { | ||
553 | /* | ||
554 | * Reset the frontend, must be called before trying | ||
555 | * to initialise the MT352 or mt352_attach | ||
556 | * will fail. Same goes for the nxt6000 frontend. | ||
557 | * | ||
558 | */ | ||
559 | |||
560 | int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08); | ||
561 | if (ret != 0) | ||
562 | printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret); | ||
563 | |||
564 | /* Pulse the reset line */ | ||
565 | bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */ | ||
566 | bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */ | ||
567 | msleep(100); | ||
568 | |||
569 | bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */ | ||
570 | } | ||
571 | |||
572 | static struct mt352_config digitv_alps_tded4_config = { | ||
573 | .demod_address = 0x0a, | ||
574 | .demod_init = digitv_alps_tded4_demod_init, | ||
575 | }; | ||
576 | |||
577 | static struct lgdt330x_config tdvs_tua6034_config = { | ||
578 | .demod_address = 0x0e, | ||
579 | .demod_chip = LGDT3303, | ||
580 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | ||
581 | }; | ||
582 | |||
583 | static void lgdt330x_reset(struct dvb_bt8xx_card *bt) | ||
584 | { | ||
585 | /* Set pin 27 of the lgdt3303 chip high to reset the frontend */ | ||
586 | |||
587 | /* Pulse the reset line */ | ||
588 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ | ||
589 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */ | ||
590 | msleep(100); | ||
591 | |||
592 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ | ||
593 | msleep(100); | ||
594 | } | ||
595 | |||
596 | static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | ||
597 | { | ||
598 | struct dst_state* state = NULL; | ||
599 | |||
600 | switch(type) { | ||
601 | case BTTV_BOARD_DVICO_DVBT_LITE: | ||
602 | card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter); | ||
603 | |||
604 | if (card->fe == NULL) | ||
605 | card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config, | ||
606 | card->i2c_adapter); | ||
607 | |||
608 | if (card->fe != NULL) { | ||
609 | card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs; | ||
610 | card->fe->ops.info.frequency_min = 174000000; | ||
611 | card->fe->ops.info.frequency_max = 862000000; | ||
612 | } | ||
613 | break; | ||
614 | |||
615 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | ||
616 | lgdt330x_reset(card); | ||
617 | card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); | ||
618 | if (card->fe != NULL) { | ||
619 | dvb_attach(simple_tuner_attach, card->fe, | ||
620 | card->i2c_adapter, 0x61, | ||
621 | TUNER_LG_TDVS_H06XF); | ||
622 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | ||
623 | } | ||
624 | break; | ||
625 | |||
626 | case BTTV_BOARD_NEBULA_DIGITV: | ||
627 | /* | ||
628 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); | ||
629 | * this would be a cleaner solution than trying each frontend in turn. | ||
630 | */ | ||
631 | |||
632 | /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ | ||
633 | digitv_alps_tded4_reset(card); | ||
634 | card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter); | ||
635 | if (card->fe != NULL) { | ||
636 | card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; | ||
637 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); | ||
638 | break; | ||
639 | } | ||
640 | |||
641 | /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */ | ||
642 | digitv_alps_tded4_reset(card); | ||
643 | card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter); | ||
644 | |||
645 | if (card->fe != NULL) { | ||
646 | card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; | ||
647 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); | ||
648 | } | ||
649 | break; | ||
650 | |||
651 | case BTTV_BOARD_AVDVBT_761: | ||
652 | card->fe = dvb_attach(sp887x_attach, µtune_mt7202dtf_config, card->i2c_adapter); | ||
653 | if (card->fe) { | ||
654 | card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params; | ||
655 | } | ||
656 | break; | ||
657 | |||
658 | case BTTV_BOARD_AVDVBT_771: | ||
659 | card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); | ||
660 | if (card->fe != NULL) { | ||
661 | card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs; | ||
662 | card->fe->ops.info.frequency_min = 174000000; | ||
663 | card->fe->ops.info.frequency_max = 862000000; | ||
664 | } | ||
665 | break; | ||
666 | |||
667 | case BTTV_BOARD_TWINHAN_DST: | ||
668 | /* DST is not a frontend driver !!! */ | ||
669 | state = kmalloc(sizeof (struct dst_state), GFP_KERNEL); | ||
670 | if (!state) { | ||
671 | pr_err("No memory\n"); | ||
672 | break; | ||
673 | } | ||
674 | /* Setup the Card */ | ||
675 | state->config = &dst_config; | ||
676 | state->i2c = card->i2c_adapter; | ||
677 | state->bt = card->bt; | ||
678 | state->dst_ca = NULL; | ||
679 | /* DST is not a frontend, attaching the ASIC */ | ||
680 | if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) { | ||
681 | pr_err("%s: Could not find a Twinhan DST\n", __func__); | ||
682 | break; | ||
683 | } | ||
684 | /* Attach other DST peripherals if any */ | ||
685 | /* Conditional Access device */ | ||
686 | card->fe = &state->frontend; | ||
687 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) | ||
688 | dvb_attach(dst_ca_attach, state, &card->dvb_adapter); | ||
689 | break; | ||
690 | |||
691 | case BTTV_BOARD_PINNACLESAT: | ||
692 | card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter); | ||
693 | if (card->fe) { | ||
694 | card->fe->ops.tuner_ops.init = pinnsat_tuner_init; | ||
695 | card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep; | ||
696 | card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params; | ||
697 | } | ||
698 | break; | ||
699 | |||
700 | case BTTV_BOARD_PC_HDTV: | ||
701 | card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter); | ||
702 | if (card->fe != NULL) | ||
703 | dvb_attach(simple_tuner_attach, card->fe, | ||
704 | card->i2c_adapter, 0x61, | ||
705 | TUNER_PHILIPS_FCV1236D); | ||
706 | break; | ||
707 | } | ||
708 | |||
709 | if (card->fe == NULL) | ||
710 | pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", | ||
711 | card->bt->dev->vendor, | ||
712 | card->bt->dev->device, | ||
713 | card->bt->dev->subsystem_vendor, | ||
714 | card->bt->dev->subsystem_device); | ||
715 | else | ||
716 | if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { | ||
717 | pr_err("Frontend registration failed!\n"); | ||
718 | dvb_frontend_detach(card->fe); | ||
719 | card->fe = NULL; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | ||
724 | { | ||
725 | int result; | ||
726 | |||
727 | result = dvb_register_adapter(&card->dvb_adapter, card->card_name, | ||
728 | THIS_MODULE, &card->bt->dev->dev, | ||
729 | adapter_nr); | ||
730 | if (result < 0) { | ||
731 | pr_err("dvb_register_adapter failed (errno = %d)\n", result); | ||
732 | return result; | ||
733 | } | ||
734 | card->dvb_adapter.priv = card; | ||
735 | |||
736 | card->bt->adapter = card->i2c_adapter; | ||
737 | |||
738 | memset(&card->demux, 0, sizeof(struct dvb_demux)); | ||
739 | |||
740 | card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING; | ||
741 | |||
742 | card->demux.priv = card; | ||
743 | card->demux.filternum = 256; | ||
744 | card->demux.feednum = 256; | ||
745 | card->demux.start_feed = dvb_bt8xx_start_feed; | ||
746 | card->demux.stop_feed = dvb_bt8xx_stop_feed; | ||
747 | card->demux.write_to_decoder = NULL; | ||
748 | |||
749 | result = dvb_dmx_init(&card->demux); | ||
750 | if (result < 0) { | ||
751 | pr_err("dvb_dmx_init failed (errno = %d)\n", result); | ||
752 | goto err_unregister_adaptor; | ||
753 | } | ||
754 | |||
755 | card->dmxdev.filternum = 256; | ||
756 | card->dmxdev.demux = &card->demux.dmx; | ||
757 | card->dmxdev.capabilities = 0; | ||
758 | |||
759 | result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter); | ||
760 | if (result < 0) { | ||
761 | pr_err("dvb_dmxdev_init failed (errno = %d)\n", result); | ||
762 | goto err_dmx_release; | ||
763 | } | ||
764 | |||
765 | card->fe_hw.source = DMX_FRONTEND_0; | ||
766 | |||
767 | result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw); | ||
768 | if (result < 0) { | ||
769 | pr_err("dvb_dmx_init failed (errno = %d)\n", result); | ||
770 | goto err_dmxdev_release; | ||
771 | } | ||
772 | |||
773 | card->fe_mem.source = DMX_MEMORY_FE; | ||
774 | |||
775 | result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem); | ||
776 | if (result < 0) { | ||
777 | pr_err("dvb_dmx_init failed (errno = %d)\n", result); | ||
778 | goto err_remove_hw_frontend; | ||
779 | } | ||
780 | |||
781 | result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw); | ||
782 | if (result < 0) { | ||
783 | pr_err("dvb_dmx_init failed (errno = %d)\n", result); | ||
784 | goto err_remove_mem_frontend; | ||
785 | } | ||
786 | |||
787 | result = dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx); | ||
788 | if (result < 0) { | ||
789 | pr_err("dvb_net_init failed (errno = %d)\n", result); | ||
790 | goto err_disconnect_frontend; | ||
791 | } | ||
792 | |||
793 | tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card); | ||
794 | |||
795 | frontend_init(card, type); | ||
796 | |||
797 | return 0; | ||
798 | |||
799 | err_disconnect_frontend: | ||
800 | card->demux.dmx.disconnect_frontend(&card->demux.dmx); | ||
801 | err_remove_mem_frontend: | ||
802 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); | ||
803 | err_remove_hw_frontend: | ||
804 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); | ||
805 | err_dmxdev_release: | ||
806 | dvb_dmxdev_release(&card->dmxdev); | ||
807 | err_dmx_release: | ||
808 | dvb_dmx_release(&card->demux); | ||
809 | err_unregister_adaptor: | ||
810 | dvb_unregister_adapter(&card->dvb_adapter); | ||
811 | return result; | ||
812 | } | ||
813 | |||
814 | static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) | ||
815 | { | ||
816 | struct dvb_bt8xx_card *card; | ||
817 | struct pci_dev* bttv_pci_dev; | ||
818 | int ret; | ||
819 | |||
820 | if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) | ||
821 | return -ENOMEM; | ||
822 | |||
823 | mutex_init(&card->lock); | ||
824 | card->bttv_nr = sub->core->nr; | ||
825 | strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name)); | ||
826 | card->i2c_adapter = &sub->core->i2c_adap; | ||
827 | |||
828 | switch(sub->core->type) { | ||
829 | case BTTV_BOARD_PINNACLESAT: | ||
830 | card->gpio_mode = 0x0400c060; | ||
831 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, | ||
832 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ | ||
833 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
834 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
835 | break; | ||
836 | |||
837 | case BTTV_BOARD_DVICO_DVBT_LITE: | ||
838 | card->gpio_mode = 0x0400C060; | ||
839 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
840 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
841 | /* 26, 15, 14, 6, 5 | ||
842 | * A_PWRDN DA_DPM DA_SBR DA_IOM_DA | ||
843 | * DA_APP(parallel) */ | ||
844 | break; | ||
845 | |||
846 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | ||
847 | card->gpio_mode = 0x0400c060; | ||
848 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
849 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
850 | break; | ||
851 | |||
852 | case BTTV_BOARD_NEBULA_DIGITV: | ||
853 | case BTTV_BOARD_AVDVBT_761: | ||
854 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); | ||
855 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
856 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
857 | /* A_PWRDN DA_SBR DA_APP (high speed serial) */ | ||
858 | break; | ||
859 | |||
860 | case BTTV_BOARD_AVDVBT_771: //case 0x07711461: | ||
861 | card->gpio_mode = 0x0400402B; | ||
862 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
863 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
864 | /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ | ||
865 | break; | ||
866 | |||
867 | case BTTV_BOARD_TWINHAN_DST: | ||
868 | card->gpio_mode = 0x2204f2c; | ||
869 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
870 | card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | | ||
871 | BT878_APPERR | BT878_AFBUS; | ||
872 | /* 25,21,14,11,10,9,8,3,2 then | ||
873 | * 0x33 = 5,4,1,0 | ||
874 | * A_SEL=SML, DA_MLB, DA_SBR, | ||
875 | * DA_SDR=f, fifo trigger = 32 DWORDS | ||
876 | * IOM = 0 == audio A/D | ||
877 | * DPM = 0 == digital audio mode | ||
878 | * == async data parallel port | ||
879 | * then 0x33 (13 is set by start_capture) | ||
880 | * DA_APP = async data parallel port, | ||
881 | * ACAP_EN = 1, | ||
882 | * RISC+FIFO ENABLE */ | ||
883 | break; | ||
884 | |||
885 | case BTTV_BOARD_PC_HDTV: | ||
886 | card->gpio_mode = 0x0100EC7B; | ||
887 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
888 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
889 | break; | ||
890 | |||
891 | default: | ||
892 | pr_err("Unknown bttv card type: %d\n", sub->core->type); | ||
893 | kfree(card); | ||
894 | return -ENODEV; | ||
895 | } | ||
896 | |||
897 | dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name); | ||
898 | |||
899 | if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) { | ||
900 | pr_err("no pci device for card %d\n", card->bttv_nr); | ||
901 | kfree(card); | ||
902 | return -ENODEV; | ||
903 | } | ||
904 | |||
905 | if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) { | ||
906 | pr_err("unable to determine DMA core of card %d,\n", card->bttv_nr); | ||
907 | pr_err("if you have the ALSA bt87x audio driver installed, try removing it.\n"); | ||
908 | |||
909 | kfree(card); | ||
910 | return -ENODEV; | ||
911 | } | ||
912 | |||
913 | mutex_init(&card->bt->gpio_lock); | ||
914 | card->bt->bttv_nr = sub->core->nr; | ||
915 | |||
916 | if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) { | ||
917 | kfree(card); | ||
918 | return ret; | ||
919 | } | ||
920 | |||
921 | dev_set_drvdata(&sub->dev, card); | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static void dvb_bt8xx_remove(struct bttv_sub_device *sub) | ||
926 | { | ||
927 | struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev); | ||
928 | |||
929 | dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr); | ||
930 | |||
931 | bt878_stop(card->bt); | ||
932 | tasklet_kill(&card->bt->tasklet); | ||
933 | dvb_net_release(&card->dvbnet); | ||
934 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); | ||
935 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); | ||
936 | dvb_dmxdev_release(&card->dmxdev); | ||
937 | dvb_dmx_release(&card->demux); | ||
938 | if (card->fe) { | ||
939 | dvb_unregister_frontend(card->fe); | ||
940 | dvb_frontend_detach(card->fe); | ||
941 | } | ||
942 | dvb_unregister_adapter(&card->dvb_adapter); | ||
943 | |||
944 | kfree(card); | ||
945 | } | ||
946 | |||
947 | static struct bttv_sub_driver driver = { | ||
948 | .drv = { | ||
949 | .name = "dvb-bt8xx", | ||
950 | }, | ||
951 | .probe = dvb_bt8xx_probe, | ||
952 | .remove = dvb_bt8xx_remove, | ||
953 | /* FIXME: | ||
954 | * .shutdown = dvb_bt8xx_shutdown, | ||
955 | * .suspend = dvb_bt8xx_suspend, | ||
956 | * .resume = dvb_bt8xx_resume, | ||
957 | */ | ||
958 | }; | ||
959 | |||
960 | static int __init dvb_bt8xx_init(void) | ||
961 | { | ||
962 | return bttv_sub_register(&driver, "dvb"); | ||
963 | } | ||
964 | |||
965 | static void __exit dvb_bt8xx_exit(void) | ||
966 | { | ||
967 | bttv_sub_unregister(&driver); | ||
968 | } | ||
969 | |||
970 | module_init(dvb_bt8xx_init); | ||
971 | module_exit(dvb_bt8xx_exit); | ||
972 | |||
973 | MODULE_DESCRIPTION("Bt8xx based DVB adapter driver"); | ||
974 | MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>"); | ||
975 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h deleted file mode 100644 index 4499ed2ac0ed..000000000000 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | /* | ||
2 | * Bt8xx based DVB adapter driver | ||
3 | * | ||
4 | * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org> | ||
5 | * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> | ||
6 | * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH | ||
7 | * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef DVB_BT8XX_H | ||
26 | #define DVB_BT8XX_H | ||
27 | |||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/mutex.h> | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_net.h" | ||
32 | #include "bttv.h" | ||
33 | #include "mt352.h" | ||
34 | #include "sp887x.h" | ||
35 | #include "dst_common.h" | ||
36 | #include "nxt6000.h" | ||
37 | #include "cx24110.h" | ||
38 | #include "or51211.h" | ||
39 | #include "lgdt330x.h" | ||
40 | #include "zl10353.h" | ||
41 | #include "tuner-simple.h" | ||
42 | |||
43 | struct dvb_bt8xx_card { | ||
44 | struct mutex lock; | ||
45 | int nfeeds; | ||
46 | char card_name[32]; | ||
47 | struct dvb_adapter dvb_adapter; | ||
48 | struct bt878 *bt; | ||
49 | unsigned int bttv_nr; | ||
50 | struct dvb_demux demux; | ||
51 | struct dmxdev dmxdev; | ||
52 | struct dmx_frontend fe_hw; | ||
53 | struct dmx_frontend fe_mem; | ||
54 | u32 gpio_mode; | ||
55 | u32 op_sync_orin; | ||
56 | u32 irq_err_ignore; | ||
57 | struct i2c_adapter *i2c_adapter; | ||
58 | struct dvb_net dvbnet; | ||
59 | |||
60 | struct dvb_frontend* fe; | ||
61 | }; | ||
62 | |||
63 | #endif /* DVB_BT8XX_H */ | ||
diff --git a/drivers/media/dvb/ddbridge/Kconfig b/drivers/media/dvb/ddbridge/Kconfig deleted file mode 100644 index d099e1a12c85..000000000000 --- a/drivers/media/dvb/ddbridge/Kconfig +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | config DVB_DDBRIDGE | ||
2 | tristate "Digital Devices bridge support" | ||
3 | depends on DVB_CORE && PCI && I2C | ||
4 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
5 | select DVB_STV6110x if !DVB_FE_CUSTOMISE | ||
6 | select DVB_STV090x if !DVB_FE_CUSTOMISE | ||
7 | select DVB_DRXK if !DVB_FE_CUSTOMISE | ||
8 | select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE | ||
9 | ---help--- | ||
10 | Support for cards with the Digital Devices PCI express bridge: | ||
11 | - Octopus PCIe Bridge | ||
12 | - Octopus mini PCIe Bridge | ||
13 | - Octopus LE | ||
14 | - DuoFlex S2 Octopus | ||
15 | - DuoFlex CT Octopus | ||
16 | - cineS2(v6) | ||
17 | |||
18 | Say Y if you own such a card and want to use it. | ||
diff --git a/drivers/media/dvb/ddbridge/Makefile b/drivers/media/dvb/ddbridge/Makefile deleted file mode 100644 index 9d083c98ce58..000000000000 --- a/drivers/media/dvb/ddbridge/Makefile +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the ddbridge device driver | ||
3 | # | ||
4 | |||
5 | ddbridge-objs := ddbridge-core.o | ||
6 | |||
7 | obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o | ||
8 | |||
9 | ccflags-y += -Idrivers/media/dvb-core/ | ||
10 | ccflags-y += -Idrivers/media/dvb-frontends/ | ||
11 | ccflags-y += -Idrivers/media/common/tuners/ | ||
12 | |||
13 | # For the staging CI driver cxd2099 | ||
14 | ccflags-y += -Idrivers/staging/media/cxd2099/ | ||
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c deleted file mode 100644 index ebf3f05839d2..000000000000 --- a/drivers/media/dvb/ddbridge/ddbridge-core.c +++ /dev/null | |||
@@ -1,1723 +0,0 @@ | |||
1 | /* | ||
2 | * ddbridge.c: Digital Devices PCIe bridge driver | ||
3 | * | ||
4 | * Copyright (C) 2010-2011 Digital Devices GmbH | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 only, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/poll.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/pci.h> | ||
32 | #include <linux/pci_ids.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/swab.h> | ||
36 | #include <linux/vmalloc.h> | ||
37 | #include "ddbridge.h" | ||
38 | |||
39 | #include "ddbridge-regs.h" | ||
40 | |||
41 | #include "tda18271c2dd.h" | ||
42 | #include "stv6110x.h" | ||
43 | #include "stv090x.h" | ||
44 | #include "lnbh24.h" | ||
45 | #include "drxk.h" | ||
46 | |||
47 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
48 | |||
49 | /* MSI had problems with lost interrupts, fixed but needs testing */ | ||
50 | #undef CONFIG_PCI_MSI | ||
51 | |||
52 | /******************************************************************************/ | ||
53 | |||
54 | static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) | ||
55 | { | ||
56 | struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, | ||
57 | .buf = val, .len = 1 } }; | ||
58 | return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; | ||
59 | } | ||
60 | |||
61 | static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) | ||
62 | { | ||
63 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
64 | .buf = ®, .len = 1 }, | ||
65 | {.addr = adr, .flags = I2C_M_RD, | ||
66 | .buf = val, .len = 1 } }; | ||
67 | return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||
68 | } | ||
69 | |||
70 | static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, | ||
71 | u16 reg, u8 *val) | ||
72 | { | ||
73 | u8 msg[2] = {reg>>8, reg&0xff}; | ||
74 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
75 | .buf = msg, .len = 2}, | ||
76 | {.addr = adr, .flags = I2C_M_RD, | ||
77 | .buf = val, .len = 1} }; | ||
78 | return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||
79 | } | ||
80 | |||
81 | static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) | ||
82 | { | ||
83 | struct ddb *dev = i2c->dev; | ||
84 | int stat; | ||
85 | u32 val; | ||
86 | |||
87 | i2c->done = 0; | ||
88 | ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND); | ||
89 | stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ); | ||
90 | if (stat <= 0) { | ||
91 | printk(KERN_ERR "I2C timeout\n"); | ||
92 | { /* MSI debugging*/ | ||
93 | u32 istat = ddbreadl(INTERRUPT_STATUS); | ||
94 | printk(KERN_ERR "IRS %08x\n", istat); | ||
95 | ddbwritel(istat, INTERRUPT_ACK); | ||
96 | } | ||
97 | return -EIO; | ||
98 | } | ||
99 | val = ddbreadl(i2c->regs+I2C_COMMAND); | ||
100 | if (val & 0x70000) | ||
101 | return -EIO; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, | ||
106 | struct i2c_msg msg[], int num) | ||
107 | { | ||
108 | struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter); | ||
109 | struct ddb *dev = i2c->dev; | ||
110 | u8 addr = 0; | ||
111 | |||
112 | if (num) | ||
113 | addr = msg[0].addr; | ||
114 | |||
115 | if (num == 2 && msg[1].flags & I2C_M_RD && | ||
116 | !(msg[0].flags & I2C_M_RD)) { | ||
117 | memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, | ||
118 | msg[0].buf, msg[0].len); | ||
119 | ddbwritel(msg[0].len|(msg[1].len << 16), | ||
120 | i2c->regs+I2C_TASKLENGTH); | ||
121 | if (!ddb_i2c_cmd(i2c, addr, 1)) { | ||
122 | memcpy_fromio(msg[1].buf, | ||
123 | dev->regs + I2C_TASKMEM_BASE + i2c->rbuf, | ||
124 | msg[1].len); | ||
125 | return num; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | if (num == 1 && !(msg[0].flags & I2C_M_RD)) { | ||
130 | ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len); | ||
131 | ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH); | ||
132 | if (!ddb_i2c_cmd(i2c, addr, 2)) | ||
133 | return num; | ||
134 | } | ||
135 | if (num == 1 && (msg[0].flags & I2C_M_RD)) { | ||
136 | ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); | ||
137 | if (!ddb_i2c_cmd(i2c, addr, 3)) { | ||
138 | ddbcpyfrom(msg[0].buf, | ||
139 | I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); | ||
140 | return num; | ||
141 | } | ||
142 | } | ||
143 | return -EIO; | ||
144 | } | ||
145 | |||
146 | |||
147 | static u32 ddb_i2c_functionality(struct i2c_adapter *adap) | ||
148 | { | ||
149 | return I2C_FUNC_SMBUS_EMUL; | ||
150 | } | ||
151 | |||
152 | struct i2c_algorithm ddb_i2c_algo = { | ||
153 | .master_xfer = ddb_i2c_master_xfer, | ||
154 | .functionality = ddb_i2c_functionality, | ||
155 | }; | ||
156 | |||
157 | static void ddb_i2c_release(struct ddb *dev) | ||
158 | { | ||
159 | int i; | ||
160 | struct ddb_i2c *i2c; | ||
161 | struct i2c_adapter *adap; | ||
162 | |||
163 | for (i = 0; i < dev->info->port_num; i++) { | ||
164 | i2c = &dev->i2c[i]; | ||
165 | adap = &i2c->adap; | ||
166 | i2c_del_adapter(adap); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static int ddb_i2c_init(struct ddb *dev) | ||
171 | { | ||
172 | int i, j, stat = 0; | ||
173 | struct ddb_i2c *i2c; | ||
174 | struct i2c_adapter *adap; | ||
175 | |||
176 | for (i = 0; i < dev->info->port_num; i++) { | ||
177 | i2c = &dev->i2c[i]; | ||
178 | i2c->dev = dev; | ||
179 | i2c->nr = i; | ||
180 | i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); | ||
181 | i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); | ||
182 | i2c->regs = 0x80 + i * 0x20; | ||
183 | ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING); | ||
184 | ddbwritel((i2c->rbuf << 16) | i2c->wbuf, | ||
185 | i2c->regs + I2C_TASKADDRESS); | ||
186 | init_waitqueue_head(&i2c->wq); | ||
187 | |||
188 | adap = &i2c->adap; | ||
189 | i2c_set_adapdata(adap, i2c); | ||
190 | #ifdef I2C_ADAP_CLASS_TV_DIGITAL | ||
191 | adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; | ||
192 | #else | ||
193 | #ifdef I2C_CLASS_TV_ANALOG | ||
194 | adap->class = I2C_CLASS_TV_ANALOG; | ||
195 | #endif | ||
196 | #endif | ||
197 | strcpy(adap->name, "ddbridge"); | ||
198 | adap->algo = &ddb_i2c_algo; | ||
199 | adap->algo_data = (void *)i2c; | ||
200 | adap->dev.parent = &dev->pdev->dev; | ||
201 | stat = i2c_add_adapter(adap); | ||
202 | if (stat) | ||
203 | break; | ||
204 | } | ||
205 | if (stat) | ||
206 | for (j = 0; j < i; j++) { | ||
207 | i2c = &dev->i2c[j]; | ||
208 | adap = &i2c->adap; | ||
209 | i2c_del_adapter(adap); | ||
210 | } | ||
211 | return stat; | ||
212 | } | ||
213 | |||
214 | |||
215 | /******************************************************************************/ | ||
216 | /******************************************************************************/ | ||
217 | /******************************************************************************/ | ||
218 | |||
219 | #if 0 | ||
220 | static void set_table(struct ddb *dev, u32 off, | ||
221 | dma_addr_t *pbuf, u32 num) | ||
222 | { | ||
223 | u32 i, base; | ||
224 | u64 mem; | ||
225 | |||
226 | base = DMA_BASE_ADDRESS_TABLE + off; | ||
227 | for (i = 0; i < num; i++) { | ||
228 | mem = pbuf[i]; | ||
229 | ddbwritel(mem & 0xffffffff, base + i * 8); | ||
230 | ddbwritel(mem >> 32, base + i * 8 + 4); | ||
231 | } | ||
232 | } | ||
233 | #endif | ||
234 | |||
235 | static void ddb_address_table(struct ddb *dev) | ||
236 | { | ||
237 | u32 i, j, base; | ||
238 | u64 mem; | ||
239 | dma_addr_t *pbuf; | ||
240 | |||
241 | for (i = 0; i < dev->info->port_num * 2; i++) { | ||
242 | base = DMA_BASE_ADDRESS_TABLE + i * 0x100; | ||
243 | pbuf = dev->input[i].pbuf; | ||
244 | for (j = 0; j < dev->input[i].dma_buf_num; j++) { | ||
245 | mem = pbuf[j]; | ||
246 | ddbwritel(mem & 0xffffffff, base + j * 8); | ||
247 | ddbwritel(mem >> 32, base + j * 8 + 4); | ||
248 | } | ||
249 | } | ||
250 | for (i = 0; i < dev->info->port_num; i++) { | ||
251 | base = DMA_BASE_ADDRESS_TABLE + 0x800 + i * 0x100; | ||
252 | pbuf = dev->output[i].pbuf; | ||
253 | for (j = 0; j < dev->output[i].dma_buf_num; j++) { | ||
254 | mem = pbuf[j]; | ||
255 | ddbwritel(mem & 0xffffffff, base + j * 8); | ||
256 | ddbwritel(mem >> 32, base + j * 8 + 4); | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | |||
261 | static void io_free(struct pci_dev *pdev, u8 **vbuf, | ||
262 | dma_addr_t *pbuf, u32 size, int num) | ||
263 | { | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < num; i++) { | ||
267 | if (vbuf[i]) { | ||
268 | pci_free_consistent(pdev, size, vbuf[i], pbuf[i]); | ||
269 | vbuf[i] = 0; | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static int io_alloc(struct pci_dev *pdev, u8 **vbuf, | ||
275 | dma_addr_t *pbuf, u32 size, int num) | ||
276 | { | ||
277 | int i; | ||
278 | |||
279 | for (i = 0; i < num; i++) { | ||
280 | vbuf[i] = pci_alloc_consistent(pdev, size, &pbuf[i]); | ||
281 | if (!vbuf[i]) | ||
282 | return -ENOMEM; | ||
283 | } | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int ddb_buffers_alloc(struct ddb *dev) | ||
288 | { | ||
289 | int i; | ||
290 | struct ddb_port *port; | ||
291 | |||
292 | for (i = 0; i < dev->info->port_num; i++) { | ||
293 | port = &dev->port[i]; | ||
294 | switch (port->class) { | ||
295 | case DDB_PORT_TUNER: | ||
296 | if (io_alloc(dev->pdev, port->input[0]->vbuf, | ||
297 | port->input[0]->pbuf, | ||
298 | port->input[0]->dma_buf_size, | ||
299 | port->input[0]->dma_buf_num) < 0) | ||
300 | return -1; | ||
301 | if (io_alloc(dev->pdev, port->input[1]->vbuf, | ||
302 | port->input[1]->pbuf, | ||
303 | port->input[1]->dma_buf_size, | ||
304 | port->input[1]->dma_buf_num) < 0) | ||
305 | return -1; | ||
306 | break; | ||
307 | case DDB_PORT_CI: | ||
308 | if (io_alloc(dev->pdev, port->input[0]->vbuf, | ||
309 | port->input[0]->pbuf, | ||
310 | port->input[0]->dma_buf_size, | ||
311 | port->input[0]->dma_buf_num) < 0) | ||
312 | return -1; | ||
313 | if (io_alloc(dev->pdev, port->output->vbuf, | ||
314 | port->output->pbuf, | ||
315 | port->output->dma_buf_size, | ||
316 | port->output->dma_buf_num) < 0) | ||
317 | return -1; | ||
318 | break; | ||
319 | default: | ||
320 | break; | ||
321 | } | ||
322 | } | ||
323 | ddb_address_table(dev); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static void ddb_buffers_free(struct ddb *dev) | ||
328 | { | ||
329 | int i; | ||
330 | struct ddb_port *port; | ||
331 | |||
332 | for (i = 0; i < dev->info->port_num; i++) { | ||
333 | port = &dev->port[i]; | ||
334 | io_free(dev->pdev, port->input[0]->vbuf, | ||
335 | port->input[0]->pbuf, | ||
336 | port->input[0]->dma_buf_size, | ||
337 | port->input[0]->dma_buf_num); | ||
338 | io_free(dev->pdev, port->input[1]->vbuf, | ||
339 | port->input[1]->pbuf, | ||
340 | port->input[1]->dma_buf_size, | ||
341 | port->input[1]->dma_buf_num); | ||
342 | io_free(dev->pdev, port->output->vbuf, | ||
343 | port->output->pbuf, | ||
344 | port->output->dma_buf_size, | ||
345 | port->output->dma_buf_num); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | static void ddb_input_start(struct ddb_input *input) | ||
350 | { | ||
351 | struct ddb *dev = input->port->dev; | ||
352 | |||
353 | spin_lock_irq(&input->lock); | ||
354 | input->cbuf = 0; | ||
355 | input->coff = 0; | ||
356 | |||
357 | /* reset */ | ||
358 | ddbwritel(0, TS_INPUT_CONTROL(input->nr)); | ||
359 | ddbwritel(2, TS_INPUT_CONTROL(input->nr)); | ||
360 | ddbwritel(0, TS_INPUT_CONTROL(input->nr)); | ||
361 | |||
362 | ddbwritel((1 << 16) | | ||
363 | (input->dma_buf_num << 11) | | ||
364 | (input->dma_buf_size >> 7), | ||
365 | DMA_BUFFER_SIZE(input->nr)); | ||
366 | ddbwritel(0, DMA_BUFFER_ACK(input->nr)); | ||
367 | |||
368 | ddbwritel(1, DMA_BASE_WRITE); | ||
369 | ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); | ||
370 | ddbwritel(9, TS_INPUT_CONTROL(input->nr)); | ||
371 | input->running = 1; | ||
372 | spin_unlock_irq(&input->lock); | ||
373 | } | ||
374 | |||
375 | static void ddb_input_stop(struct ddb_input *input) | ||
376 | { | ||
377 | struct ddb *dev = input->port->dev; | ||
378 | |||
379 | spin_lock_irq(&input->lock); | ||
380 | ddbwritel(0, TS_INPUT_CONTROL(input->nr)); | ||
381 | ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); | ||
382 | input->running = 0; | ||
383 | spin_unlock_irq(&input->lock); | ||
384 | } | ||
385 | |||
386 | static void ddb_output_start(struct ddb_output *output) | ||
387 | { | ||
388 | struct ddb *dev = output->port->dev; | ||
389 | |||
390 | spin_lock_irq(&output->lock); | ||
391 | output->cbuf = 0; | ||
392 | output->coff = 0; | ||
393 | ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); | ||
394 | ddbwritel(2, TS_OUTPUT_CONTROL(output->nr)); | ||
395 | ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); | ||
396 | ddbwritel(0x3c, TS_OUTPUT_CONTROL(output->nr)); | ||
397 | ddbwritel((1 << 16) | | ||
398 | (output->dma_buf_num << 11) | | ||
399 | (output->dma_buf_size >> 7), | ||
400 | DMA_BUFFER_SIZE(output->nr + 8)); | ||
401 | ddbwritel(0, DMA_BUFFER_ACK(output->nr + 8)); | ||
402 | |||
403 | ddbwritel(1, DMA_BASE_READ); | ||
404 | ddbwritel(3, DMA_BUFFER_CONTROL(output->nr + 8)); | ||
405 | /* ddbwritel(0xbd, TS_OUTPUT_CONTROL(output->nr)); */ | ||
406 | ddbwritel(0x1d, TS_OUTPUT_CONTROL(output->nr)); | ||
407 | output->running = 1; | ||
408 | spin_unlock_irq(&output->lock); | ||
409 | } | ||
410 | |||
411 | static void ddb_output_stop(struct ddb_output *output) | ||
412 | { | ||
413 | struct ddb *dev = output->port->dev; | ||
414 | |||
415 | spin_lock_irq(&output->lock); | ||
416 | ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); | ||
417 | ddbwritel(0, DMA_BUFFER_CONTROL(output->nr + 8)); | ||
418 | output->running = 0; | ||
419 | spin_unlock_irq(&output->lock); | ||
420 | } | ||
421 | |||
422 | static u32 ddb_output_free(struct ddb_output *output) | ||
423 | { | ||
424 | u32 idx, off, stat = output->stat; | ||
425 | s32 diff; | ||
426 | |||
427 | idx = (stat >> 11) & 0x1f; | ||
428 | off = (stat & 0x7ff) << 7; | ||
429 | |||
430 | if (output->cbuf != idx) { | ||
431 | if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && | ||
432 | (output->dma_buf_size - output->coff <= 188)) | ||
433 | return 0; | ||
434 | return 188; | ||
435 | } | ||
436 | diff = off - output->coff; | ||
437 | if (diff <= 0 || diff > 188) | ||
438 | return 188; | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static ssize_t ddb_output_write(struct ddb_output *output, | ||
443 | const u8 *buf, size_t count) | ||
444 | { | ||
445 | struct ddb *dev = output->port->dev; | ||
446 | u32 idx, off, stat = output->stat; | ||
447 | u32 left = count, len; | ||
448 | |||
449 | idx = (stat >> 11) & 0x1f; | ||
450 | off = (stat & 0x7ff) << 7; | ||
451 | |||
452 | while (left) { | ||
453 | len = output->dma_buf_size - output->coff; | ||
454 | if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && | ||
455 | (off == 0)) { | ||
456 | if (len <= 188) | ||
457 | break; | ||
458 | len -= 188; | ||
459 | } | ||
460 | if (output->cbuf == idx) { | ||
461 | if (off > output->coff) { | ||
462 | #if 1 | ||
463 | len = off - output->coff; | ||
464 | len -= (len % 188); | ||
465 | if (len <= 188) | ||
466 | |||
467 | #endif | ||
468 | break; | ||
469 | len -= 188; | ||
470 | } | ||
471 | } | ||
472 | if (len > left) | ||
473 | len = left; | ||
474 | if (copy_from_user(output->vbuf[output->cbuf] + output->coff, | ||
475 | buf, len)) | ||
476 | return -EIO; | ||
477 | left -= len; | ||
478 | buf += len; | ||
479 | output->coff += len; | ||
480 | if (output->coff == output->dma_buf_size) { | ||
481 | output->coff = 0; | ||
482 | output->cbuf = ((output->cbuf + 1) % output->dma_buf_num); | ||
483 | } | ||
484 | ddbwritel((output->cbuf << 11) | (output->coff >> 7), | ||
485 | DMA_BUFFER_ACK(output->nr + 8)); | ||
486 | } | ||
487 | return count - left; | ||
488 | } | ||
489 | |||
490 | static u32 ddb_input_avail(struct ddb_input *input) | ||
491 | { | ||
492 | struct ddb *dev = input->port->dev; | ||
493 | u32 idx, off, stat = input->stat; | ||
494 | u32 ctrl = ddbreadl(DMA_BUFFER_CONTROL(input->nr)); | ||
495 | |||
496 | idx = (stat >> 11) & 0x1f; | ||
497 | off = (stat & 0x7ff) << 7; | ||
498 | |||
499 | if (ctrl & 4) { | ||
500 | printk(KERN_ERR "IA %d %d %08x\n", idx, off, ctrl); | ||
501 | ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr)); | ||
502 | return 0; | ||
503 | } | ||
504 | if (input->cbuf != idx) | ||
505 | return 188; | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static ssize_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count) | ||
510 | { | ||
511 | struct ddb *dev = input->port->dev; | ||
512 | u32 left = count; | ||
513 | u32 idx, free, stat = input->stat; | ||
514 | int ret; | ||
515 | |||
516 | idx = (stat >> 11) & 0x1f; | ||
517 | |||
518 | while (left) { | ||
519 | if (input->cbuf == idx) | ||
520 | return count - left; | ||
521 | free = input->dma_buf_size - input->coff; | ||
522 | if (free > left) | ||
523 | free = left; | ||
524 | ret = copy_to_user(buf, input->vbuf[input->cbuf] + | ||
525 | input->coff, free); | ||
526 | if (ret) | ||
527 | return -EFAULT; | ||
528 | input->coff += free; | ||
529 | if (input->coff == input->dma_buf_size) { | ||
530 | input->coff = 0; | ||
531 | input->cbuf = (input->cbuf+1) % input->dma_buf_num; | ||
532 | } | ||
533 | left -= free; | ||
534 | ddbwritel((input->cbuf << 11) | (input->coff >> 7), | ||
535 | DMA_BUFFER_ACK(input->nr)); | ||
536 | } | ||
537 | return count; | ||
538 | } | ||
539 | |||
540 | /******************************************************************************/ | ||
541 | /******************************************************************************/ | ||
542 | /******************************************************************************/ | ||
543 | |||
544 | #if 0 | ||
545 | static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe) | ||
546 | { | ||
547 | int i; | ||
548 | |||
549 | for (i = 0; i < dev->info->port_num * 2; i++) { | ||
550 | if (dev->input[i].fe == fe) | ||
551 | return &dev->input[i]; | ||
552 | } | ||
553 | return NULL; | ||
554 | } | ||
555 | #endif | ||
556 | |||
557 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
558 | { | ||
559 | struct ddb_input *input = fe->sec_priv; | ||
560 | struct ddb_port *port = input->port; | ||
561 | int status; | ||
562 | |||
563 | if (enable) { | ||
564 | mutex_lock(&port->i2c_gate_lock); | ||
565 | status = input->gate_ctrl(fe, 1); | ||
566 | } else { | ||
567 | status = input->gate_ctrl(fe, 0); | ||
568 | mutex_unlock(&port->i2c_gate_lock); | ||
569 | } | ||
570 | return status; | ||
571 | } | ||
572 | |||
573 | static int demod_attach_drxk(struct ddb_input *input) | ||
574 | { | ||
575 | struct i2c_adapter *i2c = &input->port->i2c->adap; | ||
576 | struct dvb_frontend *fe; | ||
577 | struct drxk_config config; | ||
578 | |||
579 | memset(&config, 0, sizeof(config)); | ||
580 | config.microcode_name = "drxk_a3.mc"; | ||
581 | config.qam_demod_parameter_count = 4; | ||
582 | config.adr = 0x29 + (input->nr & 1); | ||
583 | |||
584 | fe = input->fe = dvb_attach(drxk_attach, &config, i2c); | ||
585 | if (!input->fe) { | ||
586 | printk(KERN_ERR "No DRXK found!\n"); | ||
587 | return -ENODEV; | ||
588 | } | ||
589 | fe->sec_priv = input; | ||
590 | input->gate_ctrl = fe->ops.i2c_gate_ctrl; | ||
591 | fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static int tuner_attach_tda18271(struct ddb_input *input) | ||
596 | { | ||
597 | struct i2c_adapter *i2c = &input->port->i2c->adap; | ||
598 | struct dvb_frontend *fe; | ||
599 | |||
600 | if (input->fe->ops.i2c_gate_ctrl) | ||
601 | input->fe->ops.i2c_gate_ctrl(input->fe, 1); | ||
602 | fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60); | ||
603 | if (!fe) { | ||
604 | printk(KERN_ERR "No TDA18271 found!\n"); | ||
605 | return -ENODEV; | ||
606 | } | ||
607 | if (input->fe->ops.i2c_gate_ctrl) | ||
608 | input->fe->ops.i2c_gate_ctrl(input->fe, 0); | ||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | /******************************************************************************/ | ||
613 | /******************************************************************************/ | ||
614 | /******************************************************************************/ | ||
615 | |||
616 | static struct stv090x_config stv0900 = { | ||
617 | .device = STV0900, | ||
618 | .demod_mode = STV090x_DUAL, | ||
619 | .clk_mode = STV090x_CLK_EXT, | ||
620 | |||
621 | .xtal = 27000000, | ||
622 | .address = 0x69, | ||
623 | |||
624 | .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
625 | .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
626 | |||
627 | .repeater_level = STV090x_RPTLEVEL_16, | ||
628 | |||
629 | .adc1_range = STV090x_ADC_1Vpp, | ||
630 | .adc2_range = STV090x_ADC_1Vpp, | ||
631 | |||
632 | .diseqc_envelope_mode = true, | ||
633 | }; | ||
634 | |||
635 | static struct stv090x_config stv0900_aa = { | ||
636 | .device = STV0900, | ||
637 | .demod_mode = STV090x_DUAL, | ||
638 | .clk_mode = STV090x_CLK_EXT, | ||
639 | |||
640 | .xtal = 27000000, | ||
641 | .address = 0x68, | ||
642 | |||
643 | .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
644 | .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
645 | |||
646 | .repeater_level = STV090x_RPTLEVEL_16, | ||
647 | |||
648 | .adc1_range = STV090x_ADC_1Vpp, | ||
649 | .adc2_range = STV090x_ADC_1Vpp, | ||
650 | |||
651 | .diseqc_envelope_mode = true, | ||
652 | }; | ||
653 | |||
654 | static struct stv6110x_config stv6110a = { | ||
655 | .addr = 0x60, | ||
656 | .refclk = 27000000, | ||
657 | .clk_div = 1, | ||
658 | }; | ||
659 | |||
660 | static struct stv6110x_config stv6110b = { | ||
661 | .addr = 0x63, | ||
662 | .refclk = 27000000, | ||
663 | .clk_div = 1, | ||
664 | }; | ||
665 | |||
666 | static int demod_attach_stv0900(struct ddb_input *input, int type) | ||
667 | { | ||
668 | struct i2c_adapter *i2c = &input->port->i2c->adap; | ||
669 | struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; | ||
670 | |||
671 | input->fe = dvb_attach(stv090x_attach, feconf, i2c, | ||
672 | (input->nr & 1) ? STV090x_DEMODULATOR_1 | ||
673 | : STV090x_DEMODULATOR_0); | ||
674 | if (!input->fe) { | ||
675 | printk(KERN_ERR "No STV0900 found!\n"); | ||
676 | return -ENODEV; | ||
677 | } | ||
678 | if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0, | ||
679 | 0, (input->nr & 1) ? | ||
680 | (0x09 - type) : (0x0b - type))) { | ||
681 | printk(KERN_ERR "No LNBH24 found!\n"); | ||
682 | return -ENODEV; | ||
683 | } | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | static int tuner_attach_stv6110(struct ddb_input *input, int type) | ||
688 | { | ||
689 | struct i2c_adapter *i2c = &input->port->i2c->adap; | ||
690 | struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; | ||
691 | struct stv6110x_config *tunerconf = (input->nr & 1) ? | ||
692 | &stv6110b : &stv6110a; | ||
693 | struct stv6110x_devctl *ctl; | ||
694 | |||
695 | ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c); | ||
696 | if (!ctl) { | ||
697 | printk(KERN_ERR "No STV6110X found!\n"); | ||
698 | return -ENODEV; | ||
699 | } | ||
700 | printk(KERN_INFO "attach tuner input %d adr %02x\n", | ||
701 | input->nr, tunerconf->addr); | ||
702 | |||
703 | feconf->tuner_init = ctl->tuner_init; | ||
704 | feconf->tuner_sleep = ctl->tuner_sleep; | ||
705 | feconf->tuner_set_mode = ctl->tuner_set_mode; | ||
706 | feconf->tuner_set_frequency = ctl->tuner_set_frequency; | ||
707 | feconf->tuner_get_frequency = ctl->tuner_get_frequency; | ||
708 | feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
709 | feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
710 | feconf->tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
711 | feconf->tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
712 | feconf->tuner_set_refclk = ctl->tuner_set_refclk; | ||
713 | feconf->tuner_get_status = ctl->tuner_get_status; | ||
714 | |||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, | ||
719 | int (*start_feed)(struct dvb_demux_feed *), | ||
720 | int (*stop_feed)(struct dvb_demux_feed *), | ||
721 | void *priv) | ||
722 | { | ||
723 | dvbdemux->priv = priv; | ||
724 | |||
725 | dvbdemux->filternum = 256; | ||
726 | dvbdemux->feednum = 256; | ||
727 | dvbdemux->start_feed = start_feed; | ||
728 | dvbdemux->stop_feed = stop_feed; | ||
729 | dvbdemux->write_to_decoder = NULL; | ||
730 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | | ||
731 | DMX_SECTION_FILTERING | | ||
732 | DMX_MEMORY_BASED_FILTERING); | ||
733 | return dvb_dmx_init(dvbdemux); | ||
734 | } | ||
735 | |||
736 | static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, | ||
737 | struct dvb_demux *dvbdemux, | ||
738 | struct dmx_frontend *hw_frontend, | ||
739 | struct dmx_frontend *mem_frontend, | ||
740 | struct dvb_adapter *dvb_adapter) | ||
741 | { | ||
742 | int ret; | ||
743 | |||
744 | dmxdev->filternum = 256; | ||
745 | dmxdev->demux = &dvbdemux->dmx; | ||
746 | dmxdev->capabilities = 0; | ||
747 | ret = dvb_dmxdev_init(dmxdev, dvb_adapter); | ||
748 | if (ret < 0) | ||
749 | return ret; | ||
750 | |||
751 | hw_frontend->source = DMX_FRONTEND_0; | ||
752 | dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); | ||
753 | mem_frontend->source = DMX_MEMORY_FE; | ||
754 | dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); | ||
755 | return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); | ||
756 | } | ||
757 | |||
758 | static int start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
759 | { | ||
760 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
761 | struct ddb_input *input = dvbdmx->priv; | ||
762 | |||
763 | if (!input->users) | ||
764 | ddb_input_start(input); | ||
765 | |||
766 | return ++input->users; | ||
767 | } | ||
768 | |||
769 | static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
770 | { | ||
771 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
772 | struct ddb_input *input = dvbdmx->priv; | ||
773 | |||
774 | if (--input->users) | ||
775 | return input->users; | ||
776 | |||
777 | ddb_input_stop(input); | ||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | |||
782 | static void dvb_input_detach(struct ddb_input *input) | ||
783 | { | ||
784 | struct dvb_adapter *adap = &input->adap; | ||
785 | struct dvb_demux *dvbdemux = &input->demux; | ||
786 | |||
787 | switch (input->attached) { | ||
788 | case 5: | ||
789 | if (input->fe2) | ||
790 | dvb_unregister_frontend(input->fe2); | ||
791 | if (input->fe) { | ||
792 | dvb_unregister_frontend(input->fe); | ||
793 | dvb_frontend_detach(input->fe); | ||
794 | input->fe = NULL; | ||
795 | } | ||
796 | case 4: | ||
797 | dvb_net_release(&input->dvbnet); | ||
798 | |||
799 | case 3: | ||
800 | dvbdemux->dmx.close(&dvbdemux->dmx); | ||
801 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | ||
802 | &input->hw_frontend); | ||
803 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | ||
804 | &input->mem_frontend); | ||
805 | dvb_dmxdev_release(&input->dmxdev); | ||
806 | |||
807 | case 2: | ||
808 | dvb_dmx_release(&input->demux); | ||
809 | |||
810 | case 1: | ||
811 | dvb_unregister_adapter(adap); | ||
812 | } | ||
813 | input->attached = 0; | ||
814 | } | ||
815 | |||
816 | static int dvb_input_attach(struct ddb_input *input) | ||
817 | { | ||
818 | int ret; | ||
819 | struct ddb_port *port = input->port; | ||
820 | struct dvb_adapter *adap = &input->adap; | ||
821 | struct dvb_demux *dvbdemux = &input->demux; | ||
822 | |||
823 | ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, | ||
824 | &input->port->dev->pdev->dev, | ||
825 | adapter_nr); | ||
826 | if (ret < 0) { | ||
827 | printk(KERN_ERR "ddbridge: Could not register adapter." | ||
828 | "Check if you enabled enough adapters in dvb-core!\n"); | ||
829 | return ret; | ||
830 | } | ||
831 | input->attached = 1; | ||
832 | |||
833 | ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", | ||
834 | start_feed, | ||
835 | stop_feed, input); | ||
836 | if (ret < 0) | ||
837 | return ret; | ||
838 | input->attached = 2; | ||
839 | |||
840 | ret = my_dvb_dmxdev_ts_card_init(&input->dmxdev, &input->demux, | ||
841 | &input->hw_frontend, | ||
842 | &input->mem_frontend, adap); | ||
843 | if (ret < 0) | ||
844 | return ret; | ||
845 | input->attached = 3; | ||
846 | |||
847 | ret = dvb_net_init(adap, &input->dvbnet, input->dmxdev.demux); | ||
848 | if (ret < 0) | ||
849 | return ret; | ||
850 | input->attached = 4; | ||
851 | |||
852 | input->fe = 0; | ||
853 | switch (port->type) { | ||
854 | case DDB_TUNER_DVBS_ST: | ||
855 | if (demod_attach_stv0900(input, 0) < 0) | ||
856 | return -ENODEV; | ||
857 | if (tuner_attach_stv6110(input, 0) < 0) | ||
858 | return -ENODEV; | ||
859 | if (input->fe) { | ||
860 | if (dvb_register_frontend(adap, input->fe) < 0) | ||
861 | return -ENODEV; | ||
862 | } | ||
863 | break; | ||
864 | case DDB_TUNER_DVBS_ST_AA: | ||
865 | if (demod_attach_stv0900(input, 1) < 0) | ||
866 | return -ENODEV; | ||
867 | if (tuner_attach_stv6110(input, 1) < 0) | ||
868 | return -ENODEV; | ||
869 | if (input->fe) { | ||
870 | if (dvb_register_frontend(adap, input->fe) < 0) | ||
871 | return -ENODEV; | ||
872 | } | ||
873 | break; | ||
874 | case DDB_TUNER_DVBCT_TR: | ||
875 | if (demod_attach_drxk(input) < 0) | ||
876 | return -ENODEV; | ||
877 | if (tuner_attach_tda18271(input) < 0) | ||
878 | return -ENODEV; | ||
879 | if (input->fe) { | ||
880 | if (dvb_register_frontend(adap, input->fe) < 0) | ||
881 | return -ENODEV; | ||
882 | } | ||
883 | if (input->fe2) { | ||
884 | if (dvb_register_frontend(adap, input->fe2) < 0) | ||
885 | return -ENODEV; | ||
886 | input->fe2->tuner_priv = input->fe->tuner_priv; | ||
887 | memcpy(&input->fe2->ops.tuner_ops, | ||
888 | &input->fe->ops.tuner_ops, | ||
889 | sizeof(struct dvb_tuner_ops)); | ||
890 | } | ||
891 | break; | ||
892 | } | ||
893 | input->attached = 5; | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | /****************************************************************************/ | ||
898 | /****************************************************************************/ | ||
899 | |||
900 | static ssize_t ts_write(struct file *file, const char *buf, | ||
901 | size_t count, loff_t *ppos) | ||
902 | { | ||
903 | struct dvb_device *dvbdev = file->private_data; | ||
904 | struct ddb_output *output = dvbdev->priv; | ||
905 | size_t left = count; | ||
906 | int stat; | ||
907 | |||
908 | while (left) { | ||
909 | if (ddb_output_free(output) < 188) { | ||
910 | if (file->f_flags & O_NONBLOCK) | ||
911 | break; | ||
912 | if (wait_event_interruptible( | ||
913 | output->wq, ddb_output_free(output) >= 188) < 0) | ||
914 | break; | ||
915 | } | ||
916 | stat = ddb_output_write(output, buf, left); | ||
917 | if (stat < 0) | ||
918 | break; | ||
919 | buf += stat; | ||
920 | left -= stat; | ||
921 | } | ||
922 | return (left == count) ? -EAGAIN : (count - left); | ||
923 | } | ||
924 | |||
925 | static ssize_t ts_read(struct file *file, char *buf, | ||
926 | size_t count, loff_t *ppos) | ||
927 | { | ||
928 | struct dvb_device *dvbdev = file->private_data; | ||
929 | struct ddb_output *output = dvbdev->priv; | ||
930 | struct ddb_input *input = output->port->input[0]; | ||
931 | int left, read; | ||
932 | |||
933 | count -= count % 188; | ||
934 | left = count; | ||
935 | while (left) { | ||
936 | if (ddb_input_avail(input) < 188) { | ||
937 | if (file->f_flags & O_NONBLOCK) | ||
938 | break; | ||
939 | if (wait_event_interruptible( | ||
940 | input->wq, ddb_input_avail(input) >= 188) < 0) | ||
941 | break; | ||
942 | } | ||
943 | read = ddb_input_read(input, buf, left); | ||
944 | if (read < 0) | ||
945 | return read; | ||
946 | left -= read; | ||
947 | buf += read; | ||
948 | } | ||
949 | return (left == count) ? -EAGAIN : (count - left); | ||
950 | } | ||
951 | |||
952 | static unsigned int ts_poll(struct file *file, poll_table *wait) | ||
953 | { | ||
954 | /* | ||
955 | struct dvb_device *dvbdev = file->private_data; | ||
956 | struct ddb_output *output = dvbdev->priv; | ||
957 | struct ddb_input *input = output->port->input[0]; | ||
958 | */ | ||
959 | unsigned int mask = 0; | ||
960 | |||
961 | #if 0 | ||
962 | if (data_avail_to_read) | ||
963 | mask |= POLLIN | POLLRDNORM; | ||
964 | if (data_avail_to_write) | ||
965 | mask |= POLLOUT | POLLWRNORM; | ||
966 | |||
967 | poll_wait(file, &read_queue, wait); | ||
968 | poll_wait(file, &write_queue, wait); | ||
969 | #endif | ||
970 | return mask; | ||
971 | } | ||
972 | |||
973 | static const struct file_operations ci_fops = { | ||
974 | .owner = THIS_MODULE, | ||
975 | .read = ts_read, | ||
976 | .write = ts_write, | ||
977 | .open = dvb_generic_open, | ||
978 | .release = dvb_generic_release, | ||
979 | .poll = ts_poll, | ||
980 | .mmap = 0, | ||
981 | }; | ||
982 | |||
983 | static struct dvb_device dvbdev_ci = { | ||
984 | .priv = 0, | ||
985 | .readers = -1, | ||
986 | .writers = -1, | ||
987 | .users = -1, | ||
988 | .fops = &ci_fops, | ||
989 | }; | ||
990 | |||
991 | /****************************************************************************/ | ||
992 | /****************************************************************************/ | ||
993 | /****************************************************************************/ | ||
994 | |||
995 | static void input_tasklet(unsigned long data) | ||
996 | { | ||
997 | struct ddb_input *input = (struct ddb_input *) data; | ||
998 | struct ddb *dev = input->port->dev; | ||
999 | |||
1000 | spin_lock(&input->lock); | ||
1001 | if (!input->running) { | ||
1002 | spin_unlock(&input->lock); | ||
1003 | return; | ||
1004 | } | ||
1005 | input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); | ||
1006 | |||
1007 | if (input->port->class == DDB_PORT_TUNER) { | ||
1008 | if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) | ||
1009 | printk(KERN_ERR "Overflow input %d\n", input->nr); | ||
1010 | while (input->cbuf != ((input->stat >> 11) & 0x1f) | ||
1011 | || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) { | ||
1012 | dvb_dmx_swfilter_packets(&input->demux, | ||
1013 | input->vbuf[input->cbuf], | ||
1014 | input->dma_buf_size / 188); | ||
1015 | |||
1016 | input->cbuf = (input->cbuf + 1) % input->dma_buf_num; | ||
1017 | ddbwritel((input->cbuf << 11), | ||
1018 | DMA_BUFFER_ACK(input->nr)); | ||
1019 | input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); | ||
1020 | } | ||
1021 | } | ||
1022 | if (input->port->class == DDB_PORT_CI) | ||
1023 | wake_up(&input->wq); | ||
1024 | spin_unlock(&input->lock); | ||
1025 | } | ||
1026 | |||
1027 | static void output_tasklet(unsigned long data) | ||
1028 | { | ||
1029 | struct ddb_output *output = (struct ddb_output *) data; | ||
1030 | struct ddb *dev = output->port->dev; | ||
1031 | |||
1032 | spin_lock(&output->lock); | ||
1033 | if (!output->running) { | ||
1034 | spin_unlock(&output->lock); | ||
1035 | return; | ||
1036 | } | ||
1037 | output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8)); | ||
1038 | wake_up(&output->wq); | ||
1039 | spin_unlock(&output->lock); | ||
1040 | } | ||
1041 | |||
1042 | |||
1043 | struct cxd2099_cfg cxd_cfg = { | ||
1044 | .bitrate = 62000, | ||
1045 | .adr = 0x40, | ||
1046 | .polarity = 1, | ||
1047 | .clock_mode = 1, | ||
1048 | }; | ||
1049 | |||
1050 | static int ddb_ci_attach(struct ddb_port *port) | ||
1051 | { | ||
1052 | int ret; | ||
1053 | |||
1054 | ret = dvb_register_adapter(&port->output->adap, | ||
1055 | "DDBridge", | ||
1056 | THIS_MODULE, | ||
1057 | &port->dev->pdev->dev, | ||
1058 | adapter_nr); | ||
1059 | if (ret < 0) | ||
1060 | return ret; | ||
1061 | port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); | ||
1062 | if (!port->en) { | ||
1063 | dvb_unregister_adapter(&port->output->adap); | ||
1064 | return -ENODEV; | ||
1065 | } | ||
1066 | ddb_input_start(port->input[0]); | ||
1067 | ddb_output_start(port->output); | ||
1068 | dvb_ca_en50221_init(&port->output->adap, | ||
1069 | port->en, 0, 1); | ||
1070 | ret = dvb_register_device(&port->output->adap, &port->output->dev, | ||
1071 | &dvbdev_ci, (void *) port->output, | ||
1072 | DVB_DEVICE_SEC); | ||
1073 | return ret; | ||
1074 | } | ||
1075 | |||
1076 | static int ddb_port_attach(struct ddb_port *port) | ||
1077 | { | ||
1078 | int ret = 0; | ||
1079 | |||
1080 | switch (port->class) { | ||
1081 | case DDB_PORT_TUNER: | ||
1082 | ret = dvb_input_attach(port->input[0]); | ||
1083 | if (ret < 0) | ||
1084 | break; | ||
1085 | ret = dvb_input_attach(port->input[1]); | ||
1086 | break; | ||
1087 | case DDB_PORT_CI: | ||
1088 | ret = ddb_ci_attach(port); | ||
1089 | break; | ||
1090 | default: | ||
1091 | break; | ||
1092 | } | ||
1093 | if (ret < 0) | ||
1094 | printk(KERN_ERR "port_attach on port %d failed\n", port->nr); | ||
1095 | return ret; | ||
1096 | } | ||
1097 | |||
1098 | static int ddb_ports_attach(struct ddb *dev) | ||
1099 | { | ||
1100 | int i, ret = 0; | ||
1101 | struct ddb_port *port; | ||
1102 | |||
1103 | for (i = 0; i < dev->info->port_num; i++) { | ||
1104 | port = &dev->port[i]; | ||
1105 | ret = ddb_port_attach(port); | ||
1106 | if (ret < 0) | ||
1107 | break; | ||
1108 | } | ||
1109 | return ret; | ||
1110 | } | ||
1111 | |||
1112 | static void ddb_ports_detach(struct ddb *dev) | ||
1113 | { | ||
1114 | int i; | ||
1115 | struct ddb_port *port; | ||
1116 | |||
1117 | for (i = 0; i < dev->info->port_num; i++) { | ||
1118 | port = &dev->port[i]; | ||
1119 | switch (port->class) { | ||
1120 | case DDB_PORT_TUNER: | ||
1121 | dvb_input_detach(port->input[0]); | ||
1122 | dvb_input_detach(port->input[1]); | ||
1123 | break; | ||
1124 | case DDB_PORT_CI: | ||
1125 | if (port->output->dev) | ||
1126 | dvb_unregister_device(port->output->dev); | ||
1127 | if (port->en) { | ||
1128 | ddb_input_stop(port->input[0]); | ||
1129 | ddb_output_stop(port->output); | ||
1130 | dvb_ca_en50221_release(port->en); | ||
1131 | kfree(port->en); | ||
1132 | port->en = 0; | ||
1133 | dvb_unregister_adapter(&port->output->adap); | ||
1134 | } | ||
1135 | break; | ||
1136 | } | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | /****************************************************************************/ | ||
1141 | /****************************************************************************/ | ||
1142 | |||
1143 | static int port_has_ci(struct ddb_port *port) | ||
1144 | { | ||
1145 | u8 val; | ||
1146 | return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1; | ||
1147 | } | ||
1148 | |||
1149 | static int port_has_stv0900(struct ddb_port *port) | ||
1150 | { | ||
1151 | u8 val; | ||
1152 | if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) | ||
1153 | return 0; | ||
1154 | return 1; | ||
1155 | } | ||
1156 | |||
1157 | static int port_has_stv0900_aa(struct ddb_port *port) | ||
1158 | { | ||
1159 | u8 val; | ||
1160 | if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0) | ||
1161 | return 0; | ||
1162 | return 1; | ||
1163 | } | ||
1164 | |||
1165 | static int port_has_drxks(struct ddb_port *port) | ||
1166 | { | ||
1167 | u8 val; | ||
1168 | if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) | ||
1169 | return 0; | ||
1170 | if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) | ||
1171 | return 0; | ||
1172 | return 1; | ||
1173 | } | ||
1174 | |||
1175 | static void ddb_port_probe(struct ddb_port *port) | ||
1176 | { | ||
1177 | struct ddb *dev = port->dev; | ||
1178 | char *modname = "NO MODULE"; | ||
1179 | |||
1180 | port->class = DDB_PORT_NONE; | ||
1181 | |||
1182 | if (port_has_ci(port)) { | ||
1183 | modname = "CI"; | ||
1184 | port->class = DDB_PORT_CI; | ||
1185 | ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); | ||
1186 | } else if (port_has_stv0900(port)) { | ||
1187 | modname = "DUAL DVB-S2"; | ||
1188 | port->class = DDB_PORT_TUNER; | ||
1189 | port->type = DDB_TUNER_DVBS_ST; | ||
1190 | ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); | ||
1191 | } else if (port_has_stv0900_aa(port)) { | ||
1192 | modname = "DUAL DVB-S2"; | ||
1193 | port->class = DDB_PORT_TUNER; | ||
1194 | port->type = DDB_TUNER_DVBS_ST_AA; | ||
1195 | ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); | ||
1196 | } else if (port_has_drxks(port)) { | ||
1197 | modname = "DUAL DVB-C/T"; | ||
1198 | port->class = DDB_PORT_TUNER; | ||
1199 | port->type = DDB_TUNER_DVBCT_TR; | ||
1200 | ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); | ||
1201 | } | ||
1202 | printk(KERN_INFO "Port %d (TAB %d): %s\n", | ||
1203 | port->nr, port->nr+1, modname); | ||
1204 | } | ||
1205 | |||
1206 | static void ddb_input_init(struct ddb_port *port, int nr) | ||
1207 | { | ||
1208 | struct ddb *dev = port->dev; | ||
1209 | struct ddb_input *input = &dev->input[nr]; | ||
1210 | |||
1211 | input->nr = nr; | ||
1212 | input->port = port; | ||
1213 | input->dma_buf_num = INPUT_DMA_BUFS; | ||
1214 | input->dma_buf_size = INPUT_DMA_SIZE; | ||
1215 | ddbwritel(0, TS_INPUT_CONTROL(nr)); | ||
1216 | ddbwritel(2, TS_INPUT_CONTROL(nr)); | ||
1217 | ddbwritel(0, TS_INPUT_CONTROL(nr)); | ||
1218 | ddbwritel(0, DMA_BUFFER_ACK(nr)); | ||
1219 | tasklet_init(&input->tasklet, input_tasklet, (unsigned long) input); | ||
1220 | spin_lock_init(&input->lock); | ||
1221 | init_waitqueue_head(&input->wq); | ||
1222 | } | ||
1223 | |||
1224 | static void ddb_output_init(struct ddb_port *port, int nr) | ||
1225 | { | ||
1226 | struct ddb *dev = port->dev; | ||
1227 | struct ddb_output *output = &dev->output[nr]; | ||
1228 | output->nr = nr; | ||
1229 | output->port = port; | ||
1230 | output->dma_buf_num = OUTPUT_DMA_BUFS; | ||
1231 | output->dma_buf_size = OUTPUT_DMA_SIZE; | ||
1232 | |||
1233 | ddbwritel(0, TS_OUTPUT_CONTROL(nr)); | ||
1234 | ddbwritel(2, TS_OUTPUT_CONTROL(nr)); | ||
1235 | ddbwritel(0, TS_OUTPUT_CONTROL(nr)); | ||
1236 | tasklet_init(&output->tasklet, output_tasklet, (unsigned long) output); | ||
1237 | init_waitqueue_head(&output->wq); | ||
1238 | } | ||
1239 | |||
1240 | static void ddb_ports_init(struct ddb *dev) | ||
1241 | { | ||
1242 | int i; | ||
1243 | struct ddb_port *port; | ||
1244 | |||
1245 | for (i = 0; i < dev->info->port_num; i++) { | ||
1246 | port = &dev->port[i]; | ||
1247 | port->dev = dev; | ||
1248 | port->nr = i; | ||
1249 | port->i2c = &dev->i2c[i]; | ||
1250 | port->input[0] = &dev->input[2 * i]; | ||
1251 | port->input[1] = &dev->input[2 * i + 1]; | ||
1252 | port->output = &dev->output[i]; | ||
1253 | |||
1254 | mutex_init(&port->i2c_gate_lock); | ||
1255 | ddb_port_probe(port); | ||
1256 | ddb_input_init(port, 2 * i); | ||
1257 | ddb_input_init(port, 2 * i + 1); | ||
1258 | ddb_output_init(port, i); | ||
1259 | } | ||
1260 | } | ||
1261 | |||
1262 | static void ddb_ports_release(struct ddb *dev) | ||
1263 | { | ||
1264 | int i; | ||
1265 | struct ddb_port *port; | ||
1266 | |||
1267 | for (i = 0; i < dev->info->port_num; i++) { | ||
1268 | port = &dev->port[i]; | ||
1269 | port->dev = dev; | ||
1270 | tasklet_kill(&port->input[0]->tasklet); | ||
1271 | tasklet_kill(&port->input[1]->tasklet); | ||
1272 | tasklet_kill(&port->output->tasklet); | ||
1273 | } | ||
1274 | } | ||
1275 | |||
1276 | /****************************************************************************/ | ||
1277 | /****************************************************************************/ | ||
1278 | /****************************************************************************/ | ||
1279 | |||
1280 | static void irq_handle_i2c(struct ddb *dev, int n) | ||
1281 | { | ||
1282 | struct ddb_i2c *i2c = &dev->i2c[n]; | ||
1283 | |||
1284 | i2c->done = 1; | ||
1285 | wake_up(&i2c->wq); | ||
1286 | } | ||
1287 | |||
1288 | static irqreturn_t irq_handler(int irq, void *dev_id) | ||
1289 | { | ||
1290 | struct ddb *dev = (struct ddb *) dev_id; | ||
1291 | u32 s = ddbreadl(INTERRUPT_STATUS); | ||
1292 | |||
1293 | if (!s) | ||
1294 | return IRQ_NONE; | ||
1295 | |||
1296 | do { | ||
1297 | ddbwritel(s, INTERRUPT_ACK); | ||
1298 | |||
1299 | if (s & 0x00000001) | ||
1300 | irq_handle_i2c(dev, 0); | ||
1301 | if (s & 0x00000002) | ||
1302 | irq_handle_i2c(dev, 1); | ||
1303 | if (s & 0x00000004) | ||
1304 | irq_handle_i2c(dev, 2); | ||
1305 | if (s & 0x00000008) | ||
1306 | irq_handle_i2c(dev, 3); | ||
1307 | |||
1308 | if (s & 0x00000100) | ||
1309 | tasklet_schedule(&dev->input[0].tasklet); | ||
1310 | if (s & 0x00000200) | ||
1311 | tasklet_schedule(&dev->input[1].tasklet); | ||
1312 | if (s & 0x00000400) | ||
1313 | tasklet_schedule(&dev->input[2].tasklet); | ||
1314 | if (s & 0x00000800) | ||
1315 | tasklet_schedule(&dev->input[3].tasklet); | ||
1316 | if (s & 0x00001000) | ||
1317 | tasklet_schedule(&dev->input[4].tasklet); | ||
1318 | if (s & 0x00002000) | ||
1319 | tasklet_schedule(&dev->input[5].tasklet); | ||
1320 | if (s & 0x00004000) | ||
1321 | tasklet_schedule(&dev->input[6].tasklet); | ||
1322 | if (s & 0x00008000) | ||
1323 | tasklet_schedule(&dev->input[7].tasklet); | ||
1324 | |||
1325 | if (s & 0x00010000) | ||
1326 | tasklet_schedule(&dev->output[0].tasklet); | ||
1327 | if (s & 0x00020000) | ||
1328 | tasklet_schedule(&dev->output[1].tasklet); | ||
1329 | if (s & 0x00040000) | ||
1330 | tasklet_schedule(&dev->output[2].tasklet); | ||
1331 | if (s & 0x00080000) | ||
1332 | tasklet_schedule(&dev->output[3].tasklet); | ||
1333 | |||
1334 | /* if (s & 0x000f0000) printk(KERN_DEBUG "%08x\n", istat); */ | ||
1335 | } while ((s = ddbreadl(INTERRUPT_STATUS))); | ||
1336 | |||
1337 | return IRQ_HANDLED; | ||
1338 | } | ||
1339 | |||
1340 | /******************************************************************************/ | ||
1341 | /******************************************************************************/ | ||
1342 | /******************************************************************************/ | ||
1343 | |||
1344 | static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) | ||
1345 | { | ||
1346 | u32 data, shift; | ||
1347 | |||
1348 | if (wlen > 4) | ||
1349 | ddbwritel(1, SPI_CONTROL); | ||
1350 | while (wlen > 4) { | ||
1351 | /* FIXME: check for big-endian */ | ||
1352 | data = swab32(*(u32 *)wbuf); | ||
1353 | wbuf += 4; | ||
1354 | wlen -= 4; | ||
1355 | ddbwritel(data, SPI_DATA); | ||
1356 | while (ddbreadl(SPI_CONTROL) & 0x0004) | ||
1357 | ; | ||
1358 | } | ||
1359 | |||
1360 | if (rlen) | ||
1361 | ddbwritel(0x0001 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); | ||
1362 | else | ||
1363 | ddbwritel(0x0003 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); | ||
1364 | |||
1365 | data = 0; | ||
1366 | shift = ((4 - wlen) * 8); | ||
1367 | while (wlen) { | ||
1368 | data <<= 8; | ||
1369 | data |= *wbuf; | ||
1370 | wlen--; | ||
1371 | wbuf++; | ||
1372 | } | ||
1373 | if (shift) | ||
1374 | data <<= shift; | ||
1375 | ddbwritel(data, SPI_DATA); | ||
1376 | while (ddbreadl(SPI_CONTROL) & 0x0004) | ||
1377 | ; | ||
1378 | |||
1379 | if (!rlen) { | ||
1380 | ddbwritel(0, SPI_CONTROL); | ||
1381 | return 0; | ||
1382 | } | ||
1383 | if (rlen > 4) | ||
1384 | ddbwritel(1, SPI_CONTROL); | ||
1385 | |||
1386 | while (rlen > 4) { | ||
1387 | ddbwritel(0xffffffff, SPI_DATA); | ||
1388 | while (ddbreadl(SPI_CONTROL) & 0x0004) | ||
1389 | ; | ||
1390 | data = ddbreadl(SPI_DATA); | ||
1391 | *(u32 *) rbuf = swab32(data); | ||
1392 | rbuf += 4; | ||
1393 | rlen -= 4; | ||
1394 | } | ||
1395 | ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); | ||
1396 | ddbwritel(0xffffffff, SPI_DATA); | ||
1397 | while (ddbreadl(SPI_CONTROL) & 0x0004) | ||
1398 | ; | ||
1399 | |||
1400 | data = ddbreadl(SPI_DATA); | ||
1401 | ddbwritel(0, SPI_CONTROL); | ||
1402 | |||
1403 | if (rlen < 4) | ||
1404 | data <<= ((4 - rlen) * 8); | ||
1405 | |||
1406 | while (rlen > 0) { | ||
1407 | *rbuf = ((data >> 24) & 0xff); | ||
1408 | data <<= 8; | ||
1409 | rbuf++; | ||
1410 | rlen--; | ||
1411 | } | ||
1412 | return 0; | ||
1413 | } | ||
1414 | |||
1415 | #define DDB_MAGIC 'd' | ||
1416 | |||
1417 | struct ddb_flashio { | ||
1418 | __u8 *write_buf; | ||
1419 | __u32 write_len; | ||
1420 | __u8 *read_buf; | ||
1421 | __u32 read_len; | ||
1422 | }; | ||
1423 | |||
1424 | #define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) | ||
1425 | |||
1426 | #define DDB_NAME "ddbridge" | ||
1427 | |||
1428 | static u32 ddb_num; | ||
1429 | static struct ddb *ddbs[32]; | ||
1430 | static struct class *ddb_class; | ||
1431 | static int ddb_major; | ||
1432 | |||
1433 | static int ddb_open(struct inode *inode, struct file *file) | ||
1434 | { | ||
1435 | struct ddb *dev = ddbs[iminor(inode)]; | ||
1436 | |||
1437 | file->private_data = dev; | ||
1438 | return 0; | ||
1439 | } | ||
1440 | |||
1441 | static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
1442 | { | ||
1443 | struct ddb *dev = file->private_data; | ||
1444 | void *parg = (void *)arg; | ||
1445 | int res; | ||
1446 | |||
1447 | switch (cmd) { | ||
1448 | case IOCTL_DDB_FLASHIO: | ||
1449 | { | ||
1450 | struct ddb_flashio fio; | ||
1451 | u8 *rbuf, *wbuf; | ||
1452 | |||
1453 | if (copy_from_user(&fio, parg, sizeof(fio))) | ||
1454 | return -EFAULT; | ||
1455 | |||
1456 | if (fio.write_len > 1028 || fio.read_len > 1028) | ||
1457 | return -EINVAL; | ||
1458 | if (fio.write_len + fio.read_len > 1028) | ||
1459 | return -EINVAL; | ||
1460 | |||
1461 | wbuf = &dev->iobuf[0]; | ||
1462 | rbuf = wbuf + fio.write_len; | ||
1463 | |||
1464 | if (copy_from_user(wbuf, fio.write_buf, fio.write_len)) | ||
1465 | return -EFAULT; | ||
1466 | res = flashio(dev, wbuf, fio.write_len, rbuf, fio.read_len); | ||
1467 | if (res) | ||
1468 | return res; | ||
1469 | if (copy_to_user(fio.read_buf, rbuf, fio.read_len)) | ||
1470 | return -EFAULT; | ||
1471 | break; | ||
1472 | } | ||
1473 | default: | ||
1474 | return -ENOTTY; | ||
1475 | } | ||
1476 | return 0; | ||
1477 | } | ||
1478 | |||
1479 | static const struct file_operations ddb_fops = { | ||
1480 | .unlocked_ioctl = ddb_ioctl, | ||
1481 | .open = ddb_open, | ||
1482 | }; | ||
1483 | |||
1484 | static char *ddb_devnode(struct device *device, umode_t *mode) | ||
1485 | { | ||
1486 | struct ddb *dev = dev_get_drvdata(device); | ||
1487 | |||
1488 | return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); | ||
1489 | } | ||
1490 | |||
1491 | static int ddb_class_create(void) | ||
1492 | { | ||
1493 | ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); | ||
1494 | if (ddb_major < 0) | ||
1495 | return ddb_major; | ||
1496 | |||
1497 | ddb_class = class_create(THIS_MODULE, DDB_NAME); | ||
1498 | if (IS_ERR(ddb_class)) { | ||
1499 | unregister_chrdev(ddb_major, DDB_NAME); | ||
1500 | return -1; | ||
1501 | } | ||
1502 | ddb_class->devnode = ddb_devnode; | ||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static void ddb_class_destroy(void) | ||
1507 | { | ||
1508 | class_destroy(ddb_class); | ||
1509 | unregister_chrdev(ddb_major, DDB_NAME); | ||
1510 | } | ||
1511 | |||
1512 | static int ddb_device_create(struct ddb *dev) | ||
1513 | { | ||
1514 | dev->nr = ddb_num++; | ||
1515 | dev->ddb_dev = device_create(ddb_class, NULL, | ||
1516 | MKDEV(ddb_major, dev->nr), | ||
1517 | dev, "ddbridge%d", dev->nr); | ||
1518 | ddbs[dev->nr] = dev; | ||
1519 | if (IS_ERR(dev->ddb_dev)) | ||
1520 | return -1; | ||
1521 | return 0; | ||
1522 | } | ||
1523 | |||
1524 | static void ddb_device_destroy(struct ddb *dev) | ||
1525 | { | ||
1526 | ddb_num--; | ||
1527 | if (IS_ERR(dev->ddb_dev)) | ||
1528 | return; | ||
1529 | device_destroy(ddb_class, MKDEV(ddb_major, 0)); | ||
1530 | } | ||
1531 | |||
1532 | |||
1533 | /****************************************************************************/ | ||
1534 | /****************************************************************************/ | ||
1535 | /****************************************************************************/ | ||
1536 | |||
1537 | static void ddb_unmap(struct ddb *dev) | ||
1538 | { | ||
1539 | if (dev->regs) | ||
1540 | iounmap(dev->regs); | ||
1541 | vfree(dev); | ||
1542 | } | ||
1543 | |||
1544 | |||
1545 | static void __devexit ddb_remove(struct pci_dev *pdev) | ||
1546 | { | ||
1547 | struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); | ||
1548 | |||
1549 | ddb_ports_detach(dev); | ||
1550 | ddb_i2c_release(dev); | ||
1551 | |||
1552 | ddbwritel(0, INTERRUPT_ENABLE); | ||
1553 | free_irq(dev->pdev->irq, dev); | ||
1554 | #ifdef CONFIG_PCI_MSI | ||
1555 | if (dev->msi) | ||
1556 | pci_disable_msi(dev->pdev); | ||
1557 | #endif | ||
1558 | ddb_ports_release(dev); | ||
1559 | ddb_buffers_free(dev); | ||
1560 | ddb_device_destroy(dev); | ||
1561 | |||
1562 | ddb_unmap(dev); | ||
1563 | pci_set_drvdata(pdev, 0); | ||
1564 | pci_disable_device(pdev); | ||
1565 | } | ||
1566 | |||
1567 | |||
1568 | static int __devinit ddb_probe(struct pci_dev *pdev, | ||
1569 | const struct pci_device_id *id) | ||
1570 | { | ||
1571 | struct ddb *dev; | ||
1572 | int stat = 0; | ||
1573 | int irq_flag = IRQF_SHARED; | ||
1574 | |||
1575 | if (pci_enable_device(pdev) < 0) | ||
1576 | return -ENODEV; | ||
1577 | |||
1578 | dev = vmalloc(sizeof(struct ddb)); | ||
1579 | if (dev == NULL) | ||
1580 | return -ENOMEM; | ||
1581 | memset(dev, 0, sizeof(struct ddb)); | ||
1582 | |||
1583 | dev->pdev = pdev; | ||
1584 | pci_set_drvdata(pdev, dev); | ||
1585 | dev->info = (struct ddb_info *) id->driver_data; | ||
1586 | printk(KERN_INFO "DDBridge driver detected: %s\n", dev->info->name); | ||
1587 | |||
1588 | dev->regs = ioremap(pci_resource_start(dev->pdev, 0), | ||
1589 | pci_resource_len(dev->pdev, 0)); | ||
1590 | if (!dev->regs) { | ||
1591 | stat = -ENOMEM; | ||
1592 | goto fail; | ||
1593 | } | ||
1594 | printk(KERN_INFO "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4)); | ||
1595 | |||
1596 | #ifdef CONFIG_PCI_MSI | ||
1597 | if (pci_msi_enabled()) | ||
1598 | stat = pci_enable_msi(dev->pdev); | ||
1599 | if (stat) { | ||
1600 | printk(KERN_INFO ": MSI not available.\n"); | ||
1601 | } else { | ||
1602 | irq_flag = 0; | ||
1603 | dev->msi = 1; | ||
1604 | } | ||
1605 | #endif | ||
1606 | stat = request_irq(dev->pdev->irq, irq_handler, | ||
1607 | irq_flag, "DDBridge", (void *) dev); | ||
1608 | if (stat < 0) | ||
1609 | goto fail1; | ||
1610 | ddbwritel(0, DMA_BASE_WRITE); | ||
1611 | ddbwritel(0, DMA_BASE_READ); | ||
1612 | ddbwritel(0xffffffff, INTERRUPT_ACK); | ||
1613 | ddbwritel(0xfff0f, INTERRUPT_ENABLE); | ||
1614 | ddbwritel(0, MSI1_ENABLE); | ||
1615 | |||
1616 | if (ddb_i2c_init(dev) < 0) | ||
1617 | goto fail1; | ||
1618 | ddb_ports_init(dev); | ||
1619 | if (ddb_buffers_alloc(dev) < 0) { | ||
1620 | printk(KERN_INFO ": Could not allocate buffer memory\n"); | ||
1621 | goto fail2; | ||
1622 | } | ||
1623 | if (ddb_ports_attach(dev) < 0) | ||
1624 | goto fail3; | ||
1625 | ddb_device_create(dev); | ||
1626 | return 0; | ||
1627 | |||
1628 | fail3: | ||
1629 | ddb_ports_detach(dev); | ||
1630 | printk(KERN_ERR "fail3\n"); | ||
1631 | ddb_ports_release(dev); | ||
1632 | fail2: | ||
1633 | printk(KERN_ERR "fail2\n"); | ||
1634 | ddb_buffers_free(dev); | ||
1635 | fail1: | ||
1636 | printk(KERN_ERR "fail1\n"); | ||
1637 | if (dev->msi) | ||
1638 | pci_disable_msi(dev->pdev); | ||
1639 | free_irq(dev->pdev->irq, dev); | ||
1640 | fail: | ||
1641 | printk(KERN_ERR "fail\n"); | ||
1642 | ddb_unmap(dev); | ||
1643 | pci_set_drvdata(pdev, 0); | ||
1644 | pci_disable_device(pdev); | ||
1645 | return -1; | ||
1646 | } | ||
1647 | |||
1648 | /******************************************************************************/ | ||
1649 | /******************************************************************************/ | ||
1650 | /******************************************************************************/ | ||
1651 | |||
1652 | static struct ddb_info ddb_none = { | ||
1653 | .type = DDB_NONE, | ||
1654 | .name = "Digital Devices PCIe bridge", | ||
1655 | }; | ||
1656 | |||
1657 | static struct ddb_info ddb_octopus = { | ||
1658 | .type = DDB_OCTOPUS, | ||
1659 | .name = "Digital Devices Octopus DVB adapter", | ||
1660 | .port_num = 4, | ||
1661 | }; | ||
1662 | |||
1663 | static struct ddb_info ddb_octopus_le = { | ||
1664 | .type = DDB_OCTOPUS, | ||
1665 | .name = "Digital Devices Octopus LE DVB adapter", | ||
1666 | .port_num = 2, | ||
1667 | }; | ||
1668 | |||
1669 | static struct ddb_info ddb_v6 = { | ||
1670 | .type = DDB_OCTOPUS, | ||
1671 | .name = "Digital Devices Cine S2 V6 DVB adapter", | ||
1672 | .port_num = 3, | ||
1673 | }; | ||
1674 | |||
1675 | #define DDVID 0xdd01 /* Digital Devices Vendor ID */ | ||
1676 | |||
1677 | #define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ | ||
1678 | .vendor = _vend, .device = _dev, \ | ||
1679 | .subvendor = _subvend, .subdevice = _subdev, \ | ||
1680 | .driver_data = (unsigned long)&_driverdata } | ||
1681 | |||
1682 | static const struct pci_device_id ddb_id_tbl[] __devinitdata = { | ||
1683 | DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), | ||
1684 | DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), | ||
1685 | DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), | ||
1686 | DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus), | ||
1687 | DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), | ||
1688 | /* in case sub-ids got deleted in flash */ | ||
1689 | DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||
1690 | {0} | ||
1691 | }; | ||
1692 | MODULE_DEVICE_TABLE(pci, ddb_id_tbl); | ||
1693 | |||
1694 | |||
1695 | static struct pci_driver ddb_pci_driver = { | ||
1696 | .name = "DDBridge", | ||
1697 | .id_table = ddb_id_tbl, | ||
1698 | .probe = ddb_probe, | ||
1699 | .remove = __devexit_p(ddb_remove), | ||
1700 | }; | ||
1701 | |||
1702 | static __init int module_init_ddbridge(void) | ||
1703 | { | ||
1704 | printk(KERN_INFO "Digital Devices PCIE bridge driver, " | ||
1705 | "Copyright (C) 2010-11 Digital Devices GmbH\n"); | ||
1706 | if (ddb_class_create()) | ||
1707 | return -1; | ||
1708 | return pci_register_driver(&ddb_pci_driver); | ||
1709 | } | ||
1710 | |||
1711 | static __exit void module_exit_ddbridge(void) | ||
1712 | { | ||
1713 | pci_unregister_driver(&ddb_pci_driver); | ||
1714 | ddb_class_destroy(); | ||
1715 | } | ||
1716 | |||
1717 | module_init(module_init_ddbridge); | ||
1718 | module_exit(module_exit_ddbridge); | ||
1719 | |||
1720 | MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); | ||
1721 | MODULE_AUTHOR("Ralph Metzler"); | ||
1722 | MODULE_LICENSE("GPL"); | ||
1723 | MODULE_VERSION("0.5"); | ||
diff --git a/drivers/media/dvb/ddbridge/ddbridge-regs.h b/drivers/media/dvb/ddbridge/ddbridge-regs.h deleted file mode 100644 index a3ccb318b500..000000000000 --- a/drivers/media/dvb/ddbridge/ddbridge-regs.h +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | /* | ||
2 | * ddbridge-regs.h: Digital Devices PCIe bridge driver | ||
3 | * | ||
4 | * Copyright (C) 2010-2011 Digital Devices GmbH | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 only, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
22 | */ | ||
23 | |||
24 | /* DD-DVBBridgeV1.h 273 2010-09-17 05:03:16Z manfred */ | ||
25 | |||
26 | /* Register Definitions */ | ||
27 | |||
28 | #define CUR_REGISTERMAP_VERSION 0x10000 | ||
29 | |||
30 | #define HARDWARE_VERSION 0x00 | ||
31 | #define REGISTERMAP_VERSION 0x04 | ||
32 | |||
33 | /* ------------------------------------------------------------------------- */ | ||
34 | /* SPI Controller */ | ||
35 | |||
36 | #define SPI_CONTROL 0x10 | ||
37 | #define SPI_DATA 0x14 | ||
38 | |||
39 | /* ------------------------------------------------------------------------- */ | ||
40 | |||
41 | /* Interrupt controller */ | ||
42 | /* How many MSI's are available depends on HW (Min 2 max 8) */ | ||
43 | /* How many are usable also depends on Host platform */ | ||
44 | |||
45 | #define INTERRUPT_BASE (0x40) | ||
46 | |||
47 | #define INTERRUPT_ENABLE (INTERRUPT_BASE + 0x00) | ||
48 | #define MSI0_ENABLE (INTERRUPT_BASE + 0x00) | ||
49 | #define MSI1_ENABLE (INTERRUPT_BASE + 0x04) | ||
50 | #define MSI2_ENABLE (INTERRUPT_BASE + 0x08) | ||
51 | #define MSI3_ENABLE (INTERRUPT_BASE + 0x0C) | ||
52 | #define MSI4_ENABLE (INTERRUPT_BASE + 0x10) | ||
53 | #define MSI5_ENABLE (INTERRUPT_BASE + 0x14) | ||
54 | #define MSI6_ENABLE (INTERRUPT_BASE + 0x18) | ||
55 | #define MSI7_ENABLE (INTERRUPT_BASE + 0x1C) | ||
56 | |||
57 | #define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20) | ||
58 | #define INTERRUPT_ACK (INTERRUPT_BASE + 0x20) | ||
59 | |||
60 | #define INTMASK_I2C1 (0x00000001) | ||
61 | #define INTMASK_I2C2 (0x00000002) | ||
62 | #define INTMASK_I2C3 (0x00000004) | ||
63 | #define INTMASK_I2C4 (0x00000008) | ||
64 | |||
65 | #define INTMASK_CIRQ1 (0x00000010) | ||
66 | #define INTMASK_CIRQ2 (0x00000020) | ||
67 | #define INTMASK_CIRQ3 (0x00000040) | ||
68 | #define INTMASK_CIRQ4 (0x00000080) | ||
69 | |||
70 | #define INTMASK_TSINPUT1 (0x00000100) | ||
71 | #define INTMASK_TSINPUT2 (0x00000200) | ||
72 | #define INTMASK_TSINPUT3 (0x00000400) | ||
73 | #define INTMASK_TSINPUT4 (0x00000800) | ||
74 | #define INTMASK_TSINPUT5 (0x00001000) | ||
75 | #define INTMASK_TSINPUT6 (0x00002000) | ||
76 | #define INTMASK_TSINPUT7 (0x00004000) | ||
77 | #define INTMASK_TSINPUT8 (0x00008000) | ||
78 | |||
79 | #define INTMASK_TSOUTPUT1 (0x00010000) | ||
80 | #define INTMASK_TSOUTPUT2 (0x00020000) | ||
81 | #define INTMASK_TSOUTPUT3 (0x00040000) | ||
82 | #define INTMASK_TSOUTPUT4 (0x00080000) | ||
83 | |||
84 | /* ------------------------------------------------------------------------- */ | ||
85 | /* I2C Master Controller */ | ||
86 | |||
87 | #define I2C_BASE (0x80) /* Byte offset */ | ||
88 | |||
89 | #define I2C_COMMAND (0x00) | ||
90 | #define I2C_TIMING (0x04) | ||
91 | #define I2C_TASKLENGTH (0x08) /* High read, low write */ | ||
92 | #define I2C_TASKADDRESS (0x0C) /* High read, low write */ | ||
93 | |||
94 | #define I2C_MONITOR (0x1C) | ||
95 | |||
96 | #define I2C_BASE_1 (I2C_BASE + 0x00) | ||
97 | #define I2C_BASE_2 (I2C_BASE + 0x20) | ||
98 | #define I2C_BASE_3 (I2C_BASE + 0x40) | ||
99 | #define I2C_BASE_4 (I2C_BASE + 0x60) | ||
100 | |||
101 | #define I2C_BASE_N(i) (I2C_BASE + (i) * 0x20) | ||
102 | |||
103 | #define I2C_TASKMEM_BASE (0x1000) /* Byte offset */ | ||
104 | #define I2C_TASKMEM_SIZE (0x1000) | ||
105 | |||
106 | #define I2C_SPEED_400 (0x04030404) | ||
107 | #define I2C_SPEED_200 (0x09080909) | ||
108 | #define I2C_SPEED_154 (0x0C0B0C0C) | ||
109 | #define I2C_SPEED_100 (0x13121313) | ||
110 | #define I2C_SPEED_77 (0x19181919) | ||
111 | #define I2C_SPEED_50 (0x27262727) | ||
112 | |||
113 | |||
114 | /* ------------------------------------------------------------------------- */ | ||
115 | /* DMA Controller */ | ||
116 | |||
117 | #define DMA_BASE_WRITE (0x100) | ||
118 | #define DMA_BASE_READ (0x140) | ||
119 | |||
120 | #define DMA_CONTROL (0x00) /* 64 */ | ||
121 | #define DMA_ERROR (0x04) /* 65 ( only read instance ) */ | ||
122 | |||
123 | #define DMA_DIAG_CONTROL (0x1C) /* 71 */ | ||
124 | #define DMA_DIAG_PACKETCOUNTER_LOW (0x20) /* 72 */ | ||
125 | #define DMA_DIAG_PACKETCOUNTER_HIGH (0x24) /* 73 */ | ||
126 | #define DMA_DIAG_TIMECOUNTER_LOW (0x28) /* 74 */ | ||
127 | #define DMA_DIAG_TIMECOUNTER_HIGH (0x2C) /* 75 */ | ||
128 | #define DMA_DIAG_RECHECKCOUNTER (0x30) /* 76 ( Split completions on read ) */ | ||
129 | #define DMA_DIAG_WAITTIMEOUTINIT (0x34) /* 77 */ | ||
130 | #define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38) /* 78 */ | ||
131 | #define DMA_DIAG_WAITCOUNTER (0x3C) /* 79 */ | ||
132 | |||
133 | /* ------------------------------------------------------------------------- */ | ||
134 | /* DMA Buffer */ | ||
135 | |||
136 | #define TS_INPUT_BASE (0x200) | ||
137 | #define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 16 + 0x00) | ||
138 | |||
139 | #define TS_OUTPUT_BASE (0x280) | ||
140 | #define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 16 + 0x00) | ||
141 | |||
142 | #define DMA_BUFFER_BASE (0x300) | ||
143 | |||
144 | #define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 16 + 0x00) | ||
145 | #define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 16 + 0x04) | ||
146 | #define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 16 + 0x08) | ||
147 | #define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 16 + 0x0c) | ||
148 | |||
149 | #define DMA_BASE_ADDRESS_TABLE (0x2000) | ||
150 | #define DMA_BASE_ADDRESS_TABLE_ENTRIES (512) | ||
151 | |||
diff --git a/drivers/media/dvb/ddbridge/ddbridge.h b/drivers/media/dvb/ddbridge/ddbridge.h deleted file mode 100644 index 8b1b41d2a52d..000000000000 --- a/drivers/media/dvb/ddbridge/ddbridge.h +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | * ddbridge.h: Digital Devices PCIe bridge driver | ||
3 | * | ||
4 | * Copyright (C) 2010-2011 Digital Devices GmbH | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 only, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
22 | */ | ||
23 | |||
24 | #ifndef _DDBRIDGE_H_ | ||
25 | #define _DDBRIDGE_H_ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <linux/mutex.h> | ||
32 | #include <asm/dma.h> | ||
33 | #include <linux/dvb/frontend.h> | ||
34 | #include <linux/dvb/ca.h> | ||
35 | #include <linux/socket.h> | ||
36 | |||
37 | #include "dmxdev.h" | ||
38 | #include "dvbdev.h" | ||
39 | #include "dvb_demux.h" | ||
40 | #include "dvb_frontend.h" | ||
41 | #include "dvb_ringbuffer.h" | ||
42 | #include "dvb_ca_en50221.h" | ||
43 | #include "dvb_net.h" | ||
44 | #include "cxd2099.h" | ||
45 | |||
46 | #define DDB_MAX_I2C 4 | ||
47 | #define DDB_MAX_PORT 4 | ||
48 | #define DDB_MAX_INPUT 8 | ||
49 | #define DDB_MAX_OUTPUT 4 | ||
50 | |||
51 | struct ddb_info { | ||
52 | int type; | ||
53 | #define DDB_NONE 0 | ||
54 | #define DDB_OCTOPUS 1 | ||
55 | char *name; | ||
56 | int port_num; | ||
57 | u32 port_type[DDB_MAX_PORT]; | ||
58 | }; | ||
59 | |||
60 | /* DMA_SIZE MUST be divisible by 188 and 128 !!! */ | ||
61 | |||
62 | #define INPUT_DMA_MAX_BUFS 32 /* hardware table limit */ | ||
63 | #define INPUT_DMA_BUFS 8 | ||
64 | #define INPUT_DMA_SIZE (128*47*21) | ||
65 | |||
66 | #define OUTPUT_DMA_MAX_BUFS 32 | ||
67 | #define OUTPUT_DMA_BUFS 8 | ||
68 | #define OUTPUT_DMA_SIZE (128*47*21) | ||
69 | |||
70 | struct ddb; | ||
71 | struct ddb_port; | ||
72 | |||
73 | struct ddb_input { | ||
74 | struct ddb_port *port; | ||
75 | u32 nr; | ||
76 | int attached; | ||
77 | |||
78 | dma_addr_t pbuf[INPUT_DMA_MAX_BUFS]; | ||
79 | u8 *vbuf[INPUT_DMA_MAX_BUFS]; | ||
80 | u32 dma_buf_num; | ||
81 | u32 dma_buf_size; | ||
82 | |||
83 | struct tasklet_struct tasklet; | ||
84 | spinlock_t lock; | ||
85 | wait_queue_head_t wq; | ||
86 | int running; | ||
87 | u32 stat; | ||
88 | u32 cbuf; | ||
89 | u32 coff; | ||
90 | |||
91 | struct dvb_adapter adap; | ||
92 | struct dvb_device *dev; | ||
93 | struct dvb_frontend *fe; | ||
94 | struct dvb_frontend *fe2; | ||
95 | struct dmxdev dmxdev; | ||
96 | struct dvb_demux demux; | ||
97 | struct dvb_net dvbnet; | ||
98 | struct dmx_frontend hw_frontend; | ||
99 | struct dmx_frontend mem_frontend; | ||
100 | int users; | ||
101 | int (*gate_ctrl)(struct dvb_frontend *, int); | ||
102 | }; | ||
103 | |||
104 | struct ddb_output { | ||
105 | struct ddb_port *port; | ||
106 | u32 nr; | ||
107 | dma_addr_t pbuf[OUTPUT_DMA_MAX_BUFS]; | ||
108 | u8 *vbuf[OUTPUT_DMA_MAX_BUFS]; | ||
109 | u32 dma_buf_num; | ||
110 | u32 dma_buf_size; | ||
111 | struct tasklet_struct tasklet; | ||
112 | spinlock_t lock; | ||
113 | wait_queue_head_t wq; | ||
114 | int running; | ||
115 | u32 stat; | ||
116 | u32 cbuf; | ||
117 | u32 coff; | ||
118 | |||
119 | struct dvb_adapter adap; | ||
120 | struct dvb_device *dev; | ||
121 | }; | ||
122 | |||
123 | struct ddb_i2c { | ||
124 | struct ddb *dev; | ||
125 | u32 nr; | ||
126 | struct i2c_adapter adap; | ||
127 | struct i2c_adapter adap2; | ||
128 | u32 regs; | ||
129 | u32 rbuf; | ||
130 | u32 wbuf; | ||
131 | int done; | ||
132 | wait_queue_head_t wq; | ||
133 | }; | ||
134 | |||
135 | struct ddb_port { | ||
136 | struct ddb *dev; | ||
137 | u32 nr; | ||
138 | struct ddb_i2c *i2c; | ||
139 | struct mutex i2c_gate_lock; | ||
140 | u32 class; | ||
141 | #define DDB_PORT_NONE 0 | ||
142 | #define DDB_PORT_CI 1 | ||
143 | #define DDB_PORT_TUNER 2 | ||
144 | u32 type; | ||
145 | #define DDB_TUNER_NONE 0 | ||
146 | #define DDB_TUNER_DVBS_ST 1 | ||
147 | #define DDB_TUNER_DVBS_ST_AA 2 | ||
148 | #define DDB_TUNER_DVBCT_TR 16 | ||
149 | #define DDB_TUNER_DVBCT_ST 17 | ||
150 | u32 adr; | ||
151 | |||
152 | struct ddb_input *input[2]; | ||
153 | struct ddb_output *output; | ||
154 | struct dvb_ca_en50221 *en; | ||
155 | }; | ||
156 | |||
157 | struct ddb { | ||
158 | struct pci_dev *pdev; | ||
159 | unsigned char *regs; | ||
160 | struct ddb_port port[DDB_MAX_PORT]; | ||
161 | struct ddb_i2c i2c[DDB_MAX_I2C]; | ||
162 | struct ddb_input input[DDB_MAX_INPUT]; | ||
163 | struct ddb_output output[DDB_MAX_OUTPUT]; | ||
164 | |||
165 | struct device *ddb_dev; | ||
166 | int nr; | ||
167 | u8 iobuf[1028]; | ||
168 | |||
169 | struct ddb_info *info; | ||
170 | int msi; | ||
171 | }; | ||
172 | |||
173 | /****************************************************************************/ | ||
174 | |||
175 | #define ddbwritel(_val, _adr) writel((_val), \ | ||
176 | (char *) (dev->regs+(_adr))) | ||
177 | #define ddbreadl(_adr) readl((char *) (dev->regs+(_adr))) | ||
178 | #define ddbcpyto(_adr, _src, _count) memcpy_toio((char *) \ | ||
179 | (dev->regs+(_adr)), (_src), (_count)) | ||
180 | #define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), (char *) \ | ||
181 | (dev->regs+(_adr)), (_count)) | ||
182 | |||
183 | /****************************************************************************/ | ||
184 | |||
185 | #endif | ||
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig deleted file mode 100644 index f3de0a4d63f2..000000000000 --- a/drivers/media/dvb/dm1105/Kconfig +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | config DVB_DM1105 | ||
2 | tristate "SDMC DM1105 based PCI cards" | ||
3 | depends on DVB_CORE && PCI && I2C | ||
4 | select DVB_PLL if !DVB_FE_CUSTOMISE | ||
5 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
6 | select DVB_STV0288 if !DVB_FE_CUSTOMISE | ||
7 | select DVB_STB6000 if !DVB_FE_CUSTOMISE | ||
8 | select DVB_CX24116 if !DVB_FE_CUSTOMISE | ||
9 | select DVB_SI21XX if !DVB_FE_CUSTOMISE | ||
10 | select DVB_DS3000 if !DVB_FE_CUSTOMISE | ||
11 | depends on RC_CORE | ||
12 | help | ||
13 | Support for cards based on the SDMC DM1105 PCI chip like | ||
14 | DvbWorld 2002 | ||
15 | |||
16 | Since these cards have no MPEG decoder onboard, they transmit | ||
17 | only compressed MPEG data over the PCI bus, so you need | ||
18 | an external software decoder to watch TV on your computer. | ||
19 | |||
20 | Say Y or M if you own such a device and want to use it. | ||
diff --git a/drivers/media/dvb/dm1105/Makefile b/drivers/media/dvb/dm1105/Makefile deleted file mode 100644 index 327585143c83..000000000000 --- a/drivers/media/dvb/dm1105/Makefile +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | obj-$(CONFIG_DVB_DM1105) += dm1105.o | ||
2 | |||
3 | ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends | ||
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c deleted file mode 100644 index a609b3a9b146..000000000000 --- a/drivers/media/dvb/dm1105/dm1105.c +++ /dev/null | |||
@@ -1,1248 +0,0 @@ | |||
1 | /* | ||
2 | * dm1105.c - driver for DVB cards based on SDMC DM1105 PCI chip | ||
3 | * | ||
4 | * Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/i2c-algo-bit.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/proc_fs.h> | ||
29 | #include <linux/pci.h> | ||
30 | #include <linux/dma-mapping.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <media/rc-core.h> | ||
33 | |||
34 | #include "demux.h" | ||
35 | #include "dmxdev.h" | ||
36 | #include "dvb_demux.h" | ||
37 | #include "dvb_frontend.h" | ||
38 | #include "dvb_net.h" | ||
39 | #include "dvbdev.h" | ||
40 | #include "dvb-pll.h" | ||
41 | |||
42 | #include "stv0299.h" | ||
43 | #include "stv0288.h" | ||
44 | #include "stb6000.h" | ||
45 | #include "si21xx.h" | ||
46 | #include "cx24116.h" | ||
47 | #include "z0194a.h" | ||
48 | #include "ds3000.h" | ||
49 | |||
50 | #define MODULE_NAME "dm1105" | ||
51 | |||
52 | #define UNSET (-1U) | ||
53 | |||
54 | #define DM1105_BOARD_NOAUTO UNSET | ||
55 | #define DM1105_BOARD_UNKNOWN 0 | ||
56 | #define DM1105_BOARD_DVBWORLD_2002 1 | ||
57 | #define DM1105_BOARD_DVBWORLD_2004 2 | ||
58 | #define DM1105_BOARD_AXESS_DM05 3 | ||
59 | #define DM1105_BOARD_UNBRANDED_I2C_ON_GPIO 4 | ||
60 | |||
61 | /* ----------------------------------------------- */ | ||
62 | /* | ||
63 | * PCI ID's | ||
64 | */ | ||
65 | #ifndef PCI_VENDOR_ID_TRIGEM | ||
66 | #define PCI_VENDOR_ID_TRIGEM 0x109f | ||
67 | #endif | ||
68 | #ifndef PCI_VENDOR_ID_AXESS | ||
69 | #define PCI_VENDOR_ID_AXESS 0x195d | ||
70 | #endif | ||
71 | #ifndef PCI_DEVICE_ID_DM1105 | ||
72 | #define PCI_DEVICE_ID_DM1105 0x036f | ||
73 | #endif | ||
74 | #ifndef PCI_DEVICE_ID_DW2002 | ||
75 | #define PCI_DEVICE_ID_DW2002 0x2002 | ||
76 | #endif | ||
77 | #ifndef PCI_DEVICE_ID_DW2004 | ||
78 | #define PCI_DEVICE_ID_DW2004 0x2004 | ||
79 | #endif | ||
80 | #ifndef PCI_DEVICE_ID_DM05 | ||
81 | #define PCI_DEVICE_ID_DM05 0x1105 | ||
82 | #endif | ||
83 | /* ----------------------------------------------- */ | ||
84 | /* sdmc dm1105 registers */ | ||
85 | |||
86 | /* TS Control */ | ||
87 | #define DM1105_TSCTR 0x00 | ||
88 | #define DM1105_DTALENTH 0x04 | ||
89 | |||
90 | /* GPIO Interface */ | ||
91 | #define DM1105_GPIOVAL 0x08 | ||
92 | #define DM1105_GPIOCTR 0x0c | ||
93 | |||
94 | /* PID serial number */ | ||
95 | #define DM1105_PIDN 0x10 | ||
96 | |||
97 | /* Odd-even secret key select */ | ||
98 | #define DM1105_CWSEL 0x14 | ||
99 | |||
100 | /* Host Command Interface */ | ||
101 | #define DM1105_HOST_CTR 0x18 | ||
102 | #define DM1105_HOST_AD 0x1c | ||
103 | |||
104 | /* PCI Interface */ | ||
105 | #define DM1105_CR 0x30 | ||
106 | #define DM1105_RST 0x34 | ||
107 | #define DM1105_STADR 0x38 | ||
108 | #define DM1105_RLEN 0x3c | ||
109 | #define DM1105_WRP 0x40 | ||
110 | #define DM1105_INTCNT 0x44 | ||
111 | #define DM1105_INTMAK 0x48 | ||
112 | #define DM1105_INTSTS 0x4c | ||
113 | |||
114 | /* CW Value */ | ||
115 | #define DM1105_ODD 0x50 | ||
116 | #define DM1105_EVEN 0x58 | ||
117 | |||
118 | /* PID Value */ | ||
119 | #define DM1105_PID 0x60 | ||
120 | |||
121 | /* IR Control */ | ||
122 | #define DM1105_IRCTR 0x64 | ||
123 | #define DM1105_IRMODE 0x68 | ||
124 | #define DM1105_SYSTEMCODE 0x6c | ||
125 | #define DM1105_IRCODE 0x70 | ||
126 | |||
127 | /* Unknown Values */ | ||
128 | #define DM1105_ENCRYPT 0x74 | ||
129 | #define DM1105_VER 0x7c | ||
130 | |||
131 | /* I2C Interface */ | ||
132 | #define DM1105_I2CCTR 0x80 | ||
133 | #define DM1105_I2CSTS 0x81 | ||
134 | #define DM1105_I2CDAT 0x82 | ||
135 | #define DM1105_I2C_RA 0x83 | ||
136 | /* ----------------------------------------------- */ | ||
137 | /* Interrupt Mask Bits */ | ||
138 | |||
139 | #define INTMAK_TSIRQM 0x01 | ||
140 | #define INTMAK_HIRQM 0x04 | ||
141 | #define INTMAK_IRM 0x08 | ||
142 | #define INTMAK_ALLMASK (INTMAK_TSIRQM | \ | ||
143 | INTMAK_HIRQM | \ | ||
144 | INTMAK_IRM) | ||
145 | #define INTMAK_NONEMASK 0x00 | ||
146 | |||
147 | /* Interrupt Status Bits */ | ||
148 | #define INTSTS_TSIRQ 0x01 | ||
149 | #define INTSTS_HIRQ 0x04 | ||
150 | #define INTSTS_IR 0x08 | ||
151 | |||
152 | /* IR Control Bits */ | ||
153 | #define DM1105_IR_EN 0x01 | ||
154 | #define DM1105_SYS_CHK 0x02 | ||
155 | #define DM1105_REP_FLG 0x08 | ||
156 | |||
157 | /* EEPROM addr */ | ||
158 | #define IIC_24C01_addr 0xa0 | ||
159 | /* Max board count */ | ||
160 | #define DM1105_MAX 0x04 | ||
161 | |||
162 | #define DRIVER_NAME "dm1105" | ||
163 | #define DM1105_I2C_GPIO_NAME "dm1105-gpio" | ||
164 | |||
165 | #define DM1105_DMA_PACKETS 47 | ||
166 | #define DM1105_DMA_PACKET_LENGTH (128*4) | ||
167 | #define DM1105_DMA_BYTES (128 * 4 * DM1105_DMA_PACKETS) | ||
168 | |||
169 | /* */ | ||
170 | #define GPIO08 (1 << 8) | ||
171 | #define GPIO13 (1 << 13) | ||
172 | #define GPIO14 (1 << 14) | ||
173 | #define GPIO15 (1 << 15) | ||
174 | #define GPIO16 (1 << 16) | ||
175 | #define GPIO17 (1 << 17) | ||
176 | #define GPIO_ALL 0x03ffff | ||
177 | |||
178 | /* GPIO's for LNB power control */ | ||
179 | #define DM1105_LNB_MASK (GPIO_ALL & ~(GPIO14 | GPIO13)) | ||
180 | #define DM1105_LNB_OFF GPIO17 | ||
181 | #define DM1105_LNB_13V (GPIO16 | GPIO08) | ||
182 | #define DM1105_LNB_18V GPIO08 | ||
183 | |||
184 | /* GPIO's for LNB power control for Axess DM05 */ | ||
185 | #define DM05_LNB_MASK (GPIO_ALL & ~(GPIO14 | GPIO13)) | ||
186 | #define DM05_LNB_OFF GPIO17/* actually 13v */ | ||
187 | #define DM05_LNB_13V GPIO17 | ||
188 | #define DM05_LNB_18V (GPIO17 | GPIO16) | ||
189 | |||
190 | /* GPIO's for LNB power control for unbranded with I2C on GPIO */ | ||
191 | #define UNBR_LNB_MASK (GPIO17 | GPIO16) | ||
192 | #define UNBR_LNB_OFF 0 | ||
193 | #define UNBR_LNB_13V GPIO17 | ||
194 | #define UNBR_LNB_18V (GPIO17 | GPIO16) | ||
195 | |||
196 | static unsigned int card[] = {[0 ... 3] = UNSET }; | ||
197 | module_param_array(card, int, NULL, 0444); | ||
198 | MODULE_PARM_DESC(card, "card type"); | ||
199 | |||
200 | static int ir_debug; | ||
201 | module_param(ir_debug, int, 0644); | ||
202 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); | ||
203 | |||
204 | static unsigned int dm1105_devcount; | ||
205 | |||
206 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
207 | |||
208 | struct dm1105_board { | ||
209 | char *name; | ||
210 | struct { | ||
211 | u32 mask, off, v13, v18; | ||
212 | } lnb; | ||
213 | u32 gpio_scl, gpio_sda; | ||
214 | }; | ||
215 | |||
216 | struct dm1105_subid { | ||
217 | u16 subvendor; | ||
218 | u16 subdevice; | ||
219 | u32 card; | ||
220 | }; | ||
221 | |||
222 | static const struct dm1105_board dm1105_boards[] = { | ||
223 | [DM1105_BOARD_UNKNOWN] = { | ||
224 | .name = "UNKNOWN/GENERIC", | ||
225 | .lnb = { | ||
226 | .mask = DM1105_LNB_MASK, | ||
227 | .off = DM1105_LNB_OFF, | ||
228 | .v13 = DM1105_LNB_13V, | ||
229 | .v18 = DM1105_LNB_18V, | ||
230 | }, | ||
231 | }, | ||
232 | [DM1105_BOARD_DVBWORLD_2002] = { | ||
233 | .name = "DVBWorld PCI 2002", | ||
234 | .lnb = { | ||
235 | .mask = DM1105_LNB_MASK, | ||
236 | .off = DM1105_LNB_OFF, | ||
237 | .v13 = DM1105_LNB_13V, | ||
238 | .v18 = DM1105_LNB_18V, | ||
239 | }, | ||
240 | }, | ||
241 | [DM1105_BOARD_DVBWORLD_2004] = { | ||
242 | .name = "DVBWorld PCI 2004", | ||
243 | .lnb = { | ||
244 | .mask = DM1105_LNB_MASK, | ||
245 | .off = DM1105_LNB_OFF, | ||
246 | .v13 = DM1105_LNB_13V, | ||
247 | .v18 = DM1105_LNB_18V, | ||
248 | }, | ||
249 | }, | ||
250 | [DM1105_BOARD_AXESS_DM05] = { | ||
251 | .name = "Axess/EasyTv DM05", | ||
252 | .lnb = { | ||
253 | .mask = DM05_LNB_MASK, | ||
254 | .off = DM05_LNB_OFF, | ||
255 | .v13 = DM05_LNB_13V, | ||
256 | .v18 = DM05_LNB_18V, | ||
257 | }, | ||
258 | }, | ||
259 | [DM1105_BOARD_UNBRANDED_I2C_ON_GPIO] = { | ||
260 | .name = "Unbranded DM1105 with i2c on GPIOs", | ||
261 | .lnb = { | ||
262 | .mask = UNBR_LNB_MASK, | ||
263 | .off = UNBR_LNB_OFF, | ||
264 | .v13 = UNBR_LNB_13V, | ||
265 | .v18 = UNBR_LNB_18V, | ||
266 | }, | ||
267 | .gpio_scl = GPIO14, | ||
268 | .gpio_sda = GPIO13, | ||
269 | }, | ||
270 | }; | ||
271 | |||
272 | static const struct dm1105_subid dm1105_subids[] = { | ||
273 | { | ||
274 | .subvendor = 0x0000, | ||
275 | .subdevice = 0x2002, | ||
276 | .card = DM1105_BOARD_DVBWORLD_2002, | ||
277 | }, { | ||
278 | .subvendor = 0x0001, | ||
279 | .subdevice = 0x2002, | ||
280 | .card = DM1105_BOARD_DVBWORLD_2002, | ||
281 | }, { | ||
282 | .subvendor = 0x0000, | ||
283 | .subdevice = 0x2004, | ||
284 | .card = DM1105_BOARD_DVBWORLD_2004, | ||
285 | }, { | ||
286 | .subvendor = 0x0001, | ||
287 | .subdevice = 0x2004, | ||
288 | .card = DM1105_BOARD_DVBWORLD_2004, | ||
289 | }, { | ||
290 | .subvendor = 0x195d, | ||
291 | .subdevice = 0x1105, | ||
292 | .card = DM1105_BOARD_AXESS_DM05, | ||
293 | }, | ||
294 | }; | ||
295 | |||
296 | static void dm1105_card_list(struct pci_dev *pci) | ||
297 | { | ||
298 | int i; | ||
299 | |||
300 | if (0 == pci->subsystem_vendor && | ||
301 | 0 == pci->subsystem_device) { | ||
302 | printk(KERN_ERR | ||
303 | "dm1105: Your board has no valid PCI Subsystem ID\n" | ||
304 | "dm1105: and thus can't be autodetected\n" | ||
305 | "dm1105: Please pass card=<n> insmod option to\n" | ||
306 | "dm1105: workaround that. Redirect complaints to\n" | ||
307 | "dm1105: the vendor of the TV card. Best regards,\n" | ||
308 | "dm1105: -- tux\n"); | ||
309 | } else { | ||
310 | printk(KERN_ERR | ||
311 | "dm1105: Your board isn't known (yet) to the driver.\n" | ||
312 | "dm1105: You can try to pick one of the existing\n" | ||
313 | "dm1105: card configs via card=<n> insmod option.\n" | ||
314 | "dm1105: Updating to the latest version might help\n" | ||
315 | "dm1105: as well.\n"); | ||
316 | } | ||
317 | printk(KERN_ERR "Here is a list of valid choices for the card=<n> " | ||
318 | "insmod option:\n"); | ||
319 | for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++) | ||
320 | printk(KERN_ERR "dm1105: card=%d -> %s\n", | ||
321 | i, dm1105_boards[i].name); | ||
322 | } | ||
323 | |||
324 | /* infrared remote control */ | ||
325 | struct infrared { | ||
326 | struct rc_dev *dev; | ||
327 | char input_phys[32]; | ||
328 | struct work_struct work; | ||
329 | u32 ir_command; | ||
330 | }; | ||
331 | |||
332 | struct dm1105_dev { | ||
333 | /* pci */ | ||
334 | struct pci_dev *pdev; | ||
335 | u8 __iomem *io_mem; | ||
336 | |||
337 | /* ir */ | ||
338 | struct infrared ir; | ||
339 | |||
340 | /* dvb */ | ||
341 | struct dmx_frontend hw_frontend; | ||
342 | struct dmx_frontend mem_frontend; | ||
343 | struct dmxdev dmxdev; | ||
344 | struct dvb_adapter dvb_adapter; | ||
345 | struct dvb_demux demux; | ||
346 | struct dvb_frontend *fe; | ||
347 | struct dvb_net dvbnet; | ||
348 | unsigned int full_ts_users; | ||
349 | unsigned int boardnr; | ||
350 | int nr; | ||
351 | |||
352 | /* i2c */ | ||
353 | struct i2c_adapter i2c_adap; | ||
354 | struct i2c_adapter i2c_bb_adap; | ||
355 | struct i2c_algo_bit_data i2c_bit; | ||
356 | |||
357 | /* irq */ | ||
358 | struct work_struct work; | ||
359 | struct workqueue_struct *wq; | ||
360 | char wqn[16]; | ||
361 | |||
362 | /* dma */ | ||
363 | dma_addr_t dma_addr; | ||
364 | unsigned char *ts_buf; | ||
365 | u32 wrp; | ||
366 | u32 nextwrp; | ||
367 | u32 buffer_size; | ||
368 | unsigned int PacketErrorCount; | ||
369 | unsigned int dmarst; | ||
370 | spinlock_t lock; | ||
371 | }; | ||
372 | |||
373 | #define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg])) | ||
374 | |||
375 | #define dm_readb(reg) inb(dm_io_mem(reg)) | ||
376 | #define dm_writeb(reg, value) outb((value), (dm_io_mem(reg))) | ||
377 | |||
378 | #define dm_readw(reg) inw(dm_io_mem(reg)) | ||
379 | #define dm_writew(reg, value) outw((value), (dm_io_mem(reg))) | ||
380 | |||
381 | #define dm_readl(reg) inl(dm_io_mem(reg)) | ||
382 | #define dm_writel(reg, value) outl((value), (dm_io_mem(reg))) | ||
383 | |||
384 | #define dm_andorl(reg, mask, value) \ | ||
385 | outl((inl(dm_io_mem(reg)) & ~(mask)) |\ | ||
386 | ((value) & (mask)), (dm_io_mem(reg))) | ||
387 | |||
388 | #define dm_setl(reg, bit) dm_andorl((reg), (bit), (bit)) | ||
389 | #define dm_clearl(reg, bit) dm_andorl((reg), (bit), 0) | ||
390 | |||
391 | /* The chip has 18 GPIOs. In HOST mode GPIO's used as 15 bit address lines, | ||
392 | so we can use only 3 GPIO's from GPIO15 to GPIO17. | ||
393 | Here I don't check whether HOST is enebled as it is not implemented yet. | ||
394 | */ | ||
395 | static void dm1105_gpio_set(struct dm1105_dev *dev, u32 mask) | ||
396 | { | ||
397 | if (mask & 0xfffc0000) | ||
398 | printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__); | ||
399 | |||
400 | if (mask & 0x0003ffff) | ||
401 | dm_setl(DM1105_GPIOVAL, mask & 0x0003ffff); | ||
402 | |||
403 | } | ||
404 | |||
405 | static void dm1105_gpio_clear(struct dm1105_dev *dev, u32 mask) | ||
406 | { | ||
407 | if (mask & 0xfffc0000) | ||
408 | printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__); | ||
409 | |||
410 | if (mask & 0x0003ffff) | ||
411 | dm_clearl(DM1105_GPIOVAL, mask & 0x0003ffff); | ||
412 | |||
413 | } | ||
414 | |||
415 | static void dm1105_gpio_andor(struct dm1105_dev *dev, u32 mask, u32 val) | ||
416 | { | ||
417 | if (mask & 0xfffc0000) | ||
418 | printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__); | ||
419 | |||
420 | if (mask & 0x0003ffff) | ||
421 | dm_andorl(DM1105_GPIOVAL, mask & 0x0003ffff, val); | ||
422 | |||
423 | } | ||
424 | |||
425 | static u32 dm1105_gpio_get(struct dm1105_dev *dev, u32 mask) | ||
426 | { | ||
427 | if (mask & 0xfffc0000) | ||
428 | printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__); | ||
429 | |||
430 | if (mask & 0x0003ffff) | ||
431 | return dm_readl(DM1105_GPIOVAL) & mask & 0x0003ffff; | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static void dm1105_gpio_enable(struct dm1105_dev *dev, u32 mask, int asoutput) | ||
437 | { | ||
438 | if (mask & 0xfffc0000) | ||
439 | printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__); | ||
440 | |||
441 | if ((mask & 0x0003ffff) && asoutput) | ||
442 | dm_clearl(DM1105_GPIOCTR, mask & 0x0003ffff); | ||
443 | else if ((mask & 0x0003ffff) && !asoutput) | ||
444 | dm_setl(DM1105_GPIOCTR, mask & 0x0003ffff); | ||
445 | |||
446 | } | ||
447 | |||
448 | static void dm1105_setline(struct dm1105_dev *dev, u32 line, int state) | ||
449 | { | ||
450 | if (state) | ||
451 | dm1105_gpio_enable(dev, line, 0); | ||
452 | else { | ||
453 | dm1105_gpio_enable(dev, line, 1); | ||
454 | dm1105_gpio_clear(dev, line); | ||
455 | } | ||
456 | } | ||
457 | |||
458 | static void dm1105_setsda(void *data, int state) | ||
459 | { | ||
460 | struct dm1105_dev *dev = data; | ||
461 | |||
462 | dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_sda, state); | ||
463 | } | ||
464 | |||
465 | static void dm1105_setscl(void *data, int state) | ||
466 | { | ||
467 | struct dm1105_dev *dev = data; | ||
468 | |||
469 | dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_scl, state); | ||
470 | } | ||
471 | |||
472 | static int dm1105_getsda(void *data) | ||
473 | { | ||
474 | struct dm1105_dev *dev = data; | ||
475 | |||
476 | return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_sda) | ||
477 | ? 1 : 0; | ||
478 | } | ||
479 | |||
480 | static int dm1105_getscl(void *data) | ||
481 | { | ||
482 | struct dm1105_dev *dev = data; | ||
483 | |||
484 | return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_scl) | ||
485 | ? 1 : 0; | ||
486 | } | ||
487 | |||
488 | static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
489 | struct i2c_msg *msgs, int num) | ||
490 | { | ||
491 | struct dm1105_dev *dev ; | ||
492 | |||
493 | int addr, rc, i, j, k, len, byte, data; | ||
494 | u8 status; | ||
495 | |||
496 | dev = i2c_adap->algo_data; | ||
497 | for (i = 0; i < num; i++) { | ||
498 | dm_writeb(DM1105_I2CCTR, 0x00); | ||
499 | if (msgs[i].flags & I2C_M_RD) { | ||
500 | /* read bytes */ | ||
501 | addr = msgs[i].addr << 1; | ||
502 | addr |= 1; | ||
503 | dm_writeb(DM1105_I2CDAT, addr); | ||
504 | for (byte = 0; byte < msgs[i].len; byte++) | ||
505 | dm_writeb(DM1105_I2CDAT + byte + 1, 0); | ||
506 | |||
507 | dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len); | ||
508 | for (j = 0; j < 55; j++) { | ||
509 | mdelay(10); | ||
510 | status = dm_readb(DM1105_I2CSTS); | ||
511 | if ((status & 0xc0) == 0x40) | ||
512 | break; | ||
513 | } | ||
514 | if (j >= 55) | ||
515 | return -1; | ||
516 | |||
517 | for (byte = 0; byte < msgs[i].len; byte++) { | ||
518 | rc = dm_readb(DM1105_I2CDAT + byte + 1); | ||
519 | if (rc < 0) | ||
520 | goto err; | ||
521 | msgs[i].buf[byte] = rc; | ||
522 | } | ||
523 | } else if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) { | ||
524 | /* prepaired for cx24116 firmware */ | ||
525 | /* Write in small blocks */ | ||
526 | len = msgs[i].len - 1; | ||
527 | k = 1; | ||
528 | do { | ||
529 | dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1); | ||
530 | dm_writeb(DM1105_I2CDAT + 1, 0xf7); | ||
531 | for (byte = 0; byte < (len > 48 ? 48 : len); byte++) { | ||
532 | data = msgs[i].buf[k + byte]; | ||
533 | dm_writeb(DM1105_I2CDAT + byte + 2, data); | ||
534 | } | ||
535 | dm_writeb(DM1105_I2CCTR, 0x82 + (len > 48 ? 48 : len)); | ||
536 | for (j = 0; j < 25; j++) { | ||
537 | mdelay(10); | ||
538 | status = dm_readb(DM1105_I2CSTS); | ||
539 | if ((status & 0xc0) == 0x40) | ||
540 | break; | ||
541 | } | ||
542 | |||
543 | if (j >= 25) | ||
544 | return -1; | ||
545 | |||
546 | k += 48; | ||
547 | len -= 48; | ||
548 | } while (len > 0); | ||
549 | } else { | ||
550 | /* write bytes */ | ||
551 | dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1); | ||
552 | for (byte = 0; byte < msgs[i].len; byte++) { | ||
553 | data = msgs[i].buf[byte]; | ||
554 | dm_writeb(DM1105_I2CDAT + byte + 1, data); | ||
555 | } | ||
556 | dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len); | ||
557 | for (j = 0; j < 25; j++) { | ||
558 | mdelay(10); | ||
559 | status = dm_readb(DM1105_I2CSTS); | ||
560 | if ((status & 0xc0) == 0x40) | ||
561 | break; | ||
562 | } | ||
563 | |||
564 | if (j >= 25) | ||
565 | return -1; | ||
566 | } | ||
567 | } | ||
568 | return num; | ||
569 | err: | ||
570 | return rc; | ||
571 | } | ||
572 | |||
573 | static u32 functionality(struct i2c_adapter *adap) | ||
574 | { | ||
575 | return I2C_FUNC_I2C; | ||
576 | } | ||
577 | |||
578 | static struct i2c_algorithm dm1105_algo = { | ||
579 | .master_xfer = dm1105_i2c_xfer, | ||
580 | .functionality = functionality, | ||
581 | }; | ||
582 | |||
583 | static inline struct dm1105_dev *feed_to_dm1105_dev(struct dvb_demux_feed *feed) | ||
584 | { | ||
585 | return container_of(feed->demux, struct dm1105_dev, demux); | ||
586 | } | ||
587 | |||
588 | static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe) | ||
589 | { | ||
590 | return container_of(fe->dvb, struct dm1105_dev, dvb_adapter); | ||
591 | } | ||
592 | |||
593 | static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
594 | { | ||
595 | struct dm1105_dev *dev = frontend_to_dm1105_dev(fe); | ||
596 | |||
597 | dm1105_gpio_enable(dev, dm1105_boards[dev->boardnr].lnb.mask, 1); | ||
598 | if (voltage == SEC_VOLTAGE_18) | ||
599 | dm1105_gpio_andor(dev, | ||
600 | dm1105_boards[dev->boardnr].lnb.mask, | ||
601 | dm1105_boards[dev->boardnr].lnb.v18); | ||
602 | else if (voltage == SEC_VOLTAGE_13) | ||
603 | dm1105_gpio_andor(dev, | ||
604 | dm1105_boards[dev->boardnr].lnb.mask, | ||
605 | dm1105_boards[dev->boardnr].lnb.v13); | ||
606 | else | ||
607 | dm1105_gpio_andor(dev, | ||
608 | dm1105_boards[dev->boardnr].lnb.mask, | ||
609 | dm1105_boards[dev->boardnr].lnb.off); | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static void dm1105_set_dma_addr(struct dm1105_dev *dev) | ||
615 | { | ||
616 | dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr)); | ||
617 | } | ||
618 | |||
619 | static int __devinit dm1105_dma_map(struct dm1105_dev *dev) | ||
620 | { | ||
621 | dev->ts_buf = pci_alloc_consistent(dev->pdev, | ||
622 | 6 * DM1105_DMA_BYTES, | ||
623 | &dev->dma_addr); | ||
624 | |||
625 | return !dev->ts_buf; | ||
626 | } | ||
627 | |||
628 | static void dm1105_dma_unmap(struct dm1105_dev *dev) | ||
629 | { | ||
630 | pci_free_consistent(dev->pdev, | ||
631 | 6 * DM1105_DMA_BYTES, | ||
632 | dev->ts_buf, | ||
633 | dev->dma_addr); | ||
634 | } | ||
635 | |||
636 | static void dm1105_enable_irqs(struct dm1105_dev *dev) | ||
637 | { | ||
638 | dm_writeb(DM1105_INTMAK, INTMAK_ALLMASK); | ||
639 | dm_writeb(DM1105_CR, 1); | ||
640 | } | ||
641 | |||
642 | static void dm1105_disable_irqs(struct dm1105_dev *dev) | ||
643 | { | ||
644 | dm_writeb(DM1105_INTMAK, INTMAK_IRM); | ||
645 | dm_writeb(DM1105_CR, 0); | ||
646 | } | ||
647 | |||
648 | static int dm1105_start_feed(struct dvb_demux_feed *f) | ||
649 | { | ||
650 | struct dm1105_dev *dev = feed_to_dm1105_dev(f); | ||
651 | |||
652 | if (dev->full_ts_users++ == 0) | ||
653 | dm1105_enable_irqs(dev); | ||
654 | |||
655 | return 0; | ||
656 | } | ||
657 | |||
658 | static int dm1105_stop_feed(struct dvb_demux_feed *f) | ||
659 | { | ||
660 | struct dm1105_dev *dev = feed_to_dm1105_dev(f); | ||
661 | |||
662 | if (--dev->full_ts_users == 0) | ||
663 | dm1105_disable_irqs(dev); | ||
664 | |||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | /* ir work handler */ | ||
669 | static void dm1105_emit_key(struct work_struct *work) | ||
670 | { | ||
671 | struct infrared *ir = container_of(work, struct infrared, work); | ||
672 | u32 ircom = ir->ir_command; | ||
673 | u8 data; | ||
674 | |||
675 | if (ir_debug) | ||
676 | printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom); | ||
677 | |||
678 | data = (ircom >> 8) & 0x7f; | ||
679 | |||
680 | rc_keydown(ir->dev, data, 0); | ||
681 | } | ||
682 | |||
683 | /* work handler */ | ||
684 | static void dm1105_dmx_buffer(struct work_struct *work) | ||
685 | { | ||
686 | struct dm1105_dev *dev = container_of(work, struct dm1105_dev, work); | ||
687 | unsigned int nbpackets; | ||
688 | u32 oldwrp = dev->wrp; | ||
689 | u32 nextwrp = dev->nextwrp; | ||
690 | |||
691 | if (!((dev->ts_buf[oldwrp] == 0x47) && | ||
692 | (dev->ts_buf[oldwrp + 188] == 0x47) && | ||
693 | (dev->ts_buf[oldwrp + 188 * 2] == 0x47))) { | ||
694 | dev->PacketErrorCount++; | ||
695 | /* bad packet found */ | ||
696 | if ((dev->PacketErrorCount >= 2) && | ||
697 | (dev->dmarst == 0)) { | ||
698 | dm_writeb(DM1105_RST, 1); | ||
699 | dev->wrp = 0; | ||
700 | dev->PacketErrorCount = 0; | ||
701 | dev->dmarst = 0; | ||
702 | return; | ||
703 | } | ||
704 | } | ||
705 | |||
706 | if (nextwrp < oldwrp) { | ||
707 | memcpy(dev->ts_buf + dev->buffer_size, dev->ts_buf, nextwrp); | ||
708 | nbpackets = ((dev->buffer_size - oldwrp) + nextwrp) / 188; | ||
709 | } else | ||
710 | nbpackets = (nextwrp - oldwrp) / 188; | ||
711 | |||
712 | dev->wrp = nextwrp; | ||
713 | dvb_dmx_swfilter_packets(&dev->demux, &dev->ts_buf[oldwrp], nbpackets); | ||
714 | } | ||
715 | |||
716 | static irqreturn_t dm1105_irq(int irq, void *dev_id) | ||
717 | { | ||
718 | struct dm1105_dev *dev = dev_id; | ||
719 | |||
720 | /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ | ||
721 | unsigned int intsts = dm_readb(DM1105_INTSTS); | ||
722 | dm_writeb(DM1105_INTSTS, intsts); | ||
723 | |||
724 | switch (intsts) { | ||
725 | case INTSTS_TSIRQ: | ||
726 | case (INTSTS_TSIRQ | INTSTS_IR): | ||
727 | dev->nextwrp = dm_readl(DM1105_WRP) - dm_readl(DM1105_STADR); | ||
728 | queue_work(dev->wq, &dev->work); | ||
729 | break; | ||
730 | case INTSTS_IR: | ||
731 | dev->ir.ir_command = dm_readl(DM1105_IRCODE); | ||
732 | schedule_work(&dev->ir.work); | ||
733 | break; | ||
734 | } | ||
735 | |||
736 | return IRQ_HANDLED; | ||
737 | } | ||
738 | |||
739 | int __devinit dm1105_ir_init(struct dm1105_dev *dm1105) | ||
740 | { | ||
741 | struct rc_dev *dev; | ||
742 | int err = -ENOMEM; | ||
743 | |||
744 | dev = rc_allocate_device(); | ||
745 | if (!dev) | ||
746 | return -ENOMEM; | ||
747 | |||
748 | snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), | ||
749 | "pci-%s/ir0", pci_name(dm1105->pdev)); | ||
750 | |||
751 | dev->driver_name = MODULE_NAME; | ||
752 | dev->map_name = RC_MAP_DM1105_NEC; | ||
753 | dev->driver_type = RC_DRIVER_SCANCODE; | ||
754 | dev->input_name = "DVB on-card IR receiver"; | ||
755 | dev->input_phys = dm1105->ir.input_phys; | ||
756 | dev->input_id.bustype = BUS_PCI; | ||
757 | dev->input_id.version = 1; | ||
758 | if (dm1105->pdev->subsystem_vendor) { | ||
759 | dev->input_id.vendor = dm1105->pdev->subsystem_vendor; | ||
760 | dev->input_id.product = dm1105->pdev->subsystem_device; | ||
761 | } else { | ||
762 | dev->input_id.vendor = dm1105->pdev->vendor; | ||
763 | dev->input_id.product = dm1105->pdev->device; | ||
764 | } | ||
765 | dev->dev.parent = &dm1105->pdev->dev; | ||
766 | |||
767 | INIT_WORK(&dm1105->ir.work, dm1105_emit_key); | ||
768 | |||
769 | err = rc_register_device(dev); | ||
770 | if (err < 0) { | ||
771 | rc_free_device(dev); | ||
772 | return err; | ||
773 | } | ||
774 | |||
775 | dm1105->ir.dev = dev; | ||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105) | ||
780 | { | ||
781 | rc_unregister_device(dm1105->ir.dev); | ||
782 | } | ||
783 | |||
784 | static int __devinit dm1105_hw_init(struct dm1105_dev *dev) | ||
785 | { | ||
786 | dm1105_disable_irqs(dev); | ||
787 | |||
788 | dm_writeb(DM1105_HOST_CTR, 0); | ||
789 | |||
790 | /*DATALEN 188,*/ | ||
791 | dm_writeb(DM1105_DTALENTH, 188); | ||
792 | /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/ | ||
793 | dm_writew(DM1105_TSCTR, 0xc10a); | ||
794 | |||
795 | /* map DMA and set address */ | ||
796 | dm1105_dma_map(dev); | ||
797 | dm1105_set_dma_addr(dev); | ||
798 | /* big buffer */ | ||
799 | dm_writel(DM1105_RLEN, 5 * DM1105_DMA_BYTES); | ||
800 | dm_writeb(DM1105_INTCNT, 47); | ||
801 | |||
802 | /* IR NEC mode enable */ | ||
803 | dm_writeb(DM1105_IRCTR, (DM1105_IR_EN | DM1105_SYS_CHK)); | ||
804 | dm_writeb(DM1105_IRMODE, 0); | ||
805 | dm_writew(DM1105_SYSTEMCODE, 0); | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | static void dm1105_hw_exit(struct dm1105_dev *dev) | ||
811 | { | ||
812 | dm1105_disable_irqs(dev); | ||
813 | |||
814 | /* IR disable */ | ||
815 | dm_writeb(DM1105_IRCTR, 0); | ||
816 | dm_writeb(DM1105_INTMAK, INTMAK_NONEMASK); | ||
817 | |||
818 | dm1105_dma_unmap(dev); | ||
819 | } | ||
820 | |||
821 | static struct stv0299_config sharp_z0194a_config = { | ||
822 | .demod_address = 0x68, | ||
823 | .inittab = sharp_z0194a_inittab, | ||
824 | .mclk = 88000000UL, | ||
825 | .invert = 1, | ||
826 | .skip_reinit = 0, | ||
827 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
828 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
829 | .min_delay_ms = 100, | ||
830 | .set_symbol_rate = sharp_z0194a_set_symbol_rate, | ||
831 | }; | ||
832 | |||
833 | static struct stv0288_config earda_config = { | ||
834 | .demod_address = 0x68, | ||
835 | .min_delay_ms = 100, | ||
836 | }; | ||
837 | |||
838 | static struct si21xx_config serit_config = { | ||
839 | .demod_address = 0x68, | ||
840 | .min_delay_ms = 100, | ||
841 | |||
842 | }; | ||
843 | |||
844 | static struct cx24116_config serit_sp2633_config = { | ||
845 | .demod_address = 0x55, | ||
846 | }; | ||
847 | |||
848 | static struct ds3000_config dvbworld_ds3000_config = { | ||
849 | .demod_address = 0x68, | ||
850 | }; | ||
851 | |||
852 | static int __devinit frontend_init(struct dm1105_dev *dev) | ||
853 | { | ||
854 | int ret; | ||
855 | |||
856 | switch (dev->boardnr) { | ||
857 | case DM1105_BOARD_UNBRANDED_I2C_ON_GPIO: | ||
858 | dm1105_gpio_enable(dev, GPIO15, 1); | ||
859 | dm1105_gpio_clear(dev, GPIO15); | ||
860 | msleep(100); | ||
861 | dm1105_gpio_set(dev, GPIO15); | ||
862 | msleep(200); | ||
863 | dev->fe = dvb_attach( | ||
864 | stv0299_attach, &sharp_z0194a_config, | ||
865 | &dev->i2c_bb_adap); | ||
866 | if (dev->fe) { | ||
867 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
868 | dvb_attach(dvb_pll_attach, dev->fe, 0x60, | ||
869 | &dev->i2c_bb_adap, DVB_PLL_OPERA1); | ||
870 | break; | ||
871 | } | ||
872 | |||
873 | dev->fe = dvb_attach( | ||
874 | stv0288_attach, &earda_config, | ||
875 | &dev->i2c_bb_adap); | ||
876 | if (dev->fe) { | ||
877 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
878 | dvb_attach(stb6000_attach, dev->fe, 0x61, | ||
879 | &dev->i2c_bb_adap); | ||
880 | break; | ||
881 | } | ||
882 | |||
883 | dev->fe = dvb_attach( | ||
884 | si21xx_attach, &serit_config, | ||
885 | &dev->i2c_bb_adap); | ||
886 | if (dev->fe) | ||
887 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
888 | break; | ||
889 | case DM1105_BOARD_DVBWORLD_2004: | ||
890 | dev->fe = dvb_attach( | ||
891 | cx24116_attach, &serit_sp2633_config, | ||
892 | &dev->i2c_adap); | ||
893 | if (dev->fe) { | ||
894 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
895 | break; | ||
896 | } | ||
897 | |||
898 | dev->fe = dvb_attach( | ||
899 | ds3000_attach, &dvbworld_ds3000_config, | ||
900 | &dev->i2c_adap); | ||
901 | if (dev->fe) | ||
902 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
903 | |||
904 | break; | ||
905 | case DM1105_BOARD_DVBWORLD_2002: | ||
906 | case DM1105_BOARD_AXESS_DM05: | ||
907 | default: | ||
908 | dev->fe = dvb_attach( | ||
909 | stv0299_attach, &sharp_z0194a_config, | ||
910 | &dev->i2c_adap); | ||
911 | if (dev->fe) { | ||
912 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
913 | dvb_attach(dvb_pll_attach, dev->fe, 0x60, | ||
914 | &dev->i2c_adap, DVB_PLL_OPERA1); | ||
915 | break; | ||
916 | } | ||
917 | |||
918 | dev->fe = dvb_attach( | ||
919 | stv0288_attach, &earda_config, | ||
920 | &dev->i2c_adap); | ||
921 | if (dev->fe) { | ||
922 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
923 | dvb_attach(stb6000_attach, dev->fe, 0x61, | ||
924 | &dev->i2c_adap); | ||
925 | break; | ||
926 | } | ||
927 | |||
928 | dev->fe = dvb_attach( | ||
929 | si21xx_attach, &serit_config, | ||
930 | &dev->i2c_adap); | ||
931 | if (dev->fe) | ||
932 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
933 | |||
934 | } | ||
935 | |||
936 | if (!dev->fe) { | ||
937 | dev_err(&dev->pdev->dev, "could not attach frontend\n"); | ||
938 | return -ENODEV; | ||
939 | } | ||
940 | |||
941 | ret = dvb_register_frontend(&dev->dvb_adapter, dev->fe); | ||
942 | if (ret < 0) { | ||
943 | if (dev->fe->ops.release) | ||
944 | dev->fe->ops.release(dev->fe); | ||
945 | dev->fe = NULL; | ||
946 | return ret; | ||
947 | } | ||
948 | |||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | static void __devinit dm1105_read_mac(struct dm1105_dev *dev, u8 *mac) | ||
953 | { | ||
954 | static u8 command[1] = { 0x28 }; | ||
955 | |||
956 | struct i2c_msg msg[] = { | ||
957 | { | ||
958 | .addr = IIC_24C01_addr >> 1, | ||
959 | .flags = 0, | ||
960 | .buf = command, | ||
961 | .len = 1 | ||
962 | }, { | ||
963 | .addr = IIC_24C01_addr >> 1, | ||
964 | .flags = I2C_M_RD, | ||
965 | .buf = mac, | ||
966 | .len = 6 | ||
967 | }, | ||
968 | }; | ||
969 | |||
970 | dm1105_i2c_xfer(&dev->i2c_adap, msg , 2); | ||
971 | dev_info(&dev->pdev->dev, "MAC %pM\n", mac); | ||
972 | } | ||
973 | |||
974 | static int __devinit dm1105_probe(struct pci_dev *pdev, | ||
975 | const struct pci_device_id *ent) | ||
976 | { | ||
977 | struct dm1105_dev *dev; | ||
978 | struct dvb_adapter *dvb_adapter; | ||
979 | struct dvb_demux *dvbdemux; | ||
980 | struct dmx_demux *dmx; | ||
981 | int ret = -ENOMEM; | ||
982 | int i; | ||
983 | |||
984 | dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL); | ||
985 | if (!dev) | ||
986 | return -ENOMEM; | ||
987 | |||
988 | /* board config */ | ||
989 | dev->nr = dm1105_devcount; | ||
990 | dev->boardnr = UNSET; | ||
991 | if (card[dev->nr] < ARRAY_SIZE(dm1105_boards)) | ||
992 | dev->boardnr = card[dev->nr]; | ||
993 | for (i = 0; UNSET == dev->boardnr && | ||
994 | i < ARRAY_SIZE(dm1105_subids); i++) | ||
995 | if (pdev->subsystem_vendor == | ||
996 | dm1105_subids[i].subvendor && | ||
997 | pdev->subsystem_device == | ||
998 | dm1105_subids[i].subdevice) | ||
999 | dev->boardnr = dm1105_subids[i].card; | ||
1000 | |||
1001 | if (UNSET == dev->boardnr) { | ||
1002 | dev->boardnr = DM1105_BOARD_UNKNOWN; | ||
1003 | dm1105_card_list(pdev); | ||
1004 | } | ||
1005 | |||
1006 | dm1105_devcount++; | ||
1007 | dev->pdev = pdev; | ||
1008 | dev->buffer_size = 5 * DM1105_DMA_BYTES; | ||
1009 | dev->PacketErrorCount = 0; | ||
1010 | dev->dmarst = 0; | ||
1011 | |||
1012 | ret = pci_enable_device(pdev); | ||
1013 | if (ret < 0) | ||
1014 | goto err_kfree; | ||
1015 | |||
1016 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
1017 | if (ret < 0) | ||
1018 | goto err_pci_disable_device; | ||
1019 | |||
1020 | pci_set_master(pdev); | ||
1021 | |||
1022 | ret = pci_request_regions(pdev, DRIVER_NAME); | ||
1023 | if (ret < 0) | ||
1024 | goto err_pci_disable_device; | ||
1025 | |||
1026 | dev->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); | ||
1027 | if (!dev->io_mem) { | ||
1028 | ret = -EIO; | ||
1029 | goto err_pci_release_regions; | ||
1030 | } | ||
1031 | |||
1032 | spin_lock_init(&dev->lock); | ||
1033 | pci_set_drvdata(pdev, dev); | ||
1034 | |||
1035 | ret = dm1105_hw_init(dev); | ||
1036 | if (ret < 0) | ||
1037 | goto err_pci_iounmap; | ||
1038 | |||
1039 | /* i2c */ | ||
1040 | i2c_set_adapdata(&dev->i2c_adap, dev); | ||
1041 | strcpy(dev->i2c_adap.name, DRIVER_NAME); | ||
1042 | dev->i2c_adap.owner = THIS_MODULE; | ||
1043 | dev->i2c_adap.dev.parent = &pdev->dev; | ||
1044 | dev->i2c_adap.algo = &dm1105_algo; | ||
1045 | dev->i2c_adap.algo_data = dev; | ||
1046 | ret = i2c_add_adapter(&dev->i2c_adap); | ||
1047 | |||
1048 | if (ret < 0) | ||
1049 | goto err_dm1105_hw_exit; | ||
1050 | |||
1051 | i2c_set_adapdata(&dev->i2c_bb_adap, dev); | ||
1052 | strcpy(dev->i2c_bb_adap.name, DM1105_I2C_GPIO_NAME); | ||
1053 | dev->i2c_bb_adap.owner = THIS_MODULE; | ||
1054 | dev->i2c_bb_adap.dev.parent = &pdev->dev; | ||
1055 | dev->i2c_bb_adap.algo_data = &dev->i2c_bit; | ||
1056 | dev->i2c_bit.data = dev; | ||
1057 | dev->i2c_bit.setsda = dm1105_setsda; | ||
1058 | dev->i2c_bit.setscl = dm1105_setscl; | ||
1059 | dev->i2c_bit.getsda = dm1105_getsda; | ||
1060 | dev->i2c_bit.getscl = dm1105_getscl; | ||
1061 | dev->i2c_bit.udelay = 10; | ||
1062 | dev->i2c_bit.timeout = 10; | ||
1063 | |||
1064 | /* Raise SCL and SDA */ | ||
1065 | dm1105_setsda(dev, 1); | ||
1066 | dm1105_setscl(dev, 1); | ||
1067 | |||
1068 | ret = i2c_bit_add_bus(&dev->i2c_bb_adap); | ||
1069 | if (ret < 0) | ||
1070 | goto err_i2c_del_adapter; | ||
1071 | |||
1072 | /* dvb */ | ||
1073 | ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME, | ||
1074 | THIS_MODULE, &pdev->dev, adapter_nr); | ||
1075 | if (ret < 0) | ||
1076 | goto err_i2c_del_adapters; | ||
1077 | |||
1078 | dvb_adapter = &dev->dvb_adapter; | ||
1079 | |||
1080 | dm1105_read_mac(dev, dvb_adapter->proposed_mac); | ||
1081 | |||
1082 | dvbdemux = &dev->demux; | ||
1083 | dvbdemux->filternum = 256; | ||
1084 | dvbdemux->feednum = 256; | ||
1085 | dvbdemux->start_feed = dm1105_start_feed; | ||
1086 | dvbdemux->stop_feed = dm1105_stop_feed; | ||
1087 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | | ||
1088 | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); | ||
1089 | ret = dvb_dmx_init(dvbdemux); | ||
1090 | if (ret < 0) | ||
1091 | goto err_dvb_unregister_adapter; | ||
1092 | |||
1093 | dmx = &dvbdemux->dmx; | ||
1094 | dev->dmxdev.filternum = 256; | ||
1095 | dev->dmxdev.demux = dmx; | ||
1096 | dev->dmxdev.capabilities = 0; | ||
1097 | |||
1098 | ret = dvb_dmxdev_init(&dev->dmxdev, dvb_adapter); | ||
1099 | if (ret < 0) | ||
1100 | goto err_dvb_dmx_release; | ||
1101 | |||
1102 | dev->hw_frontend.source = DMX_FRONTEND_0; | ||
1103 | |||
1104 | ret = dmx->add_frontend(dmx, &dev->hw_frontend); | ||
1105 | if (ret < 0) | ||
1106 | goto err_dvb_dmxdev_release; | ||
1107 | |||
1108 | dev->mem_frontend.source = DMX_MEMORY_FE; | ||
1109 | |||
1110 | ret = dmx->add_frontend(dmx, &dev->mem_frontend); | ||
1111 | if (ret < 0) | ||
1112 | goto err_remove_hw_frontend; | ||
1113 | |||
1114 | ret = dmx->connect_frontend(dmx, &dev->hw_frontend); | ||
1115 | if (ret < 0) | ||
1116 | goto err_remove_mem_frontend; | ||
1117 | |||
1118 | ret = dvb_net_init(dvb_adapter, &dev->dvbnet, dmx); | ||
1119 | if (ret < 0) | ||
1120 | goto err_disconnect_frontend; | ||
1121 | |||
1122 | ret = frontend_init(dev); | ||
1123 | if (ret < 0) | ||
1124 | goto err_dvb_net; | ||
1125 | |||
1126 | dm1105_ir_init(dev); | ||
1127 | |||
1128 | INIT_WORK(&dev->work, dm1105_dmx_buffer); | ||
1129 | sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num); | ||
1130 | dev->wq = create_singlethread_workqueue(dev->wqn); | ||
1131 | if (!dev->wq) | ||
1132 | goto err_dvb_net; | ||
1133 | |||
1134 | ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED, | ||
1135 | DRIVER_NAME, dev); | ||
1136 | if (ret < 0) | ||
1137 | goto err_workqueue; | ||
1138 | |||
1139 | return 0; | ||
1140 | |||
1141 | err_workqueue: | ||
1142 | destroy_workqueue(dev->wq); | ||
1143 | err_dvb_net: | ||
1144 | dvb_net_release(&dev->dvbnet); | ||
1145 | err_disconnect_frontend: | ||
1146 | dmx->disconnect_frontend(dmx); | ||
1147 | err_remove_mem_frontend: | ||
1148 | dmx->remove_frontend(dmx, &dev->mem_frontend); | ||
1149 | err_remove_hw_frontend: | ||
1150 | dmx->remove_frontend(dmx, &dev->hw_frontend); | ||
1151 | err_dvb_dmxdev_release: | ||
1152 | dvb_dmxdev_release(&dev->dmxdev); | ||
1153 | err_dvb_dmx_release: | ||
1154 | dvb_dmx_release(dvbdemux); | ||
1155 | err_dvb_unregister_adapter: | ||
1156 | dvb_unregister_adapter(dvb_adapter); | ||
1157 | err_i2c_del_adapters: | ||
1158 | i2c_del_adapter(&dev->i2c_bb_adap); | ||
1159 | err_i2c_del_adapter: | ||
1160 | i2c_del_adapter(&dev->i2c_adap); | ||
1161 | err_dm1105_hw_exit: | ||
1162 | dm1105_hw_exit(dev); | ||
1163 | err_pci_iounmap: | ||
1164 | pci_iounmap(pdev, dev->io_mem); | ||
1165 | err_pci_release_regions: | ||
1166 | pci_release_regions(pdev); | ||
1167 | err_pci_disable_device: | ||
1168 | pci_disable_device(pdev); | ||
1169 | err_kfree: | ||
1170 | pci_set_drvdata(pdev, NULL); | ||
1171 | kfree(dev); | ||
1172 | return ret; | ||
1173 | } | ||
1174 | |||
1175 | static void __devexit dm1105_remove(struct pci_dev *pdev) | ||
1176 | { | ||
1177 | struct dm1105_dev *dev = pci_get_drvdata(pdev); | ||
1178 | struct dvb_adapter *dvb_adapter = &dev->dvb_adapter; | ||
1179 | struct dvb_demux *dvbdemux = &dev->demux; | ||
1180 | struct dmx_demux *dmx = &dvbdemux->dmx; | ||
1181 | |||
1182 | dm1105_ir_exit(dev); | ||
1183 | dmx->close(dmx); | ||
1184 | dvb_net_release(&dev->dvbnet); | ||
1185 | if (dev->fe) | ||
1186 | dvb_unregister_frontend(dev->fe); | ||
1187 | |||
1188 | dmx->disconnect_frontend(dmx); | ||
1189 | dmx->remove_frontend(dmx, &dev->mem_frontend); | ||
1190 | dmx->remove_frontend(dmx, &dev->hw_frontend); | ||
1191 | dvb_dmxdev_release(&dev->dmxdev); | ||
1192 | dvb_dmx_release(dvbdemux); | ||
1193 | dvb_unregister_adapter(dvb_adapter); | ||
1194 | if (&dev->i2c_adap) | ||
1195 | i2c_del_adapter(&dev->i2c_adap); | ||
1196 | |||
1197 | dm1105_hw_exit(dev); | ||
1198 | synchronize_irq(pdev->irq); | ||
1199 | free_irq(pdev->irq, dev); | ||
1200 | pci_iounmap(pdev, dev->io_mem); | ||
1201 | pci_release_regions(pdev); | ||
1202 | pci_disable_device(pdev); | ||
1203 | pci_set_drvdata(pdev, NULL); | ||
1204 | dm1105_devcount--; | ||
1205 | kfree(dev); | ||
1206 | } | ||
1207 | |||
1208 | static struct pci_device_id dm1105_id_table[] __devinitdata = { | ||
1209 | { | ||
1210 | .vendor = PCI_VENDOR_ID_TRIGEM, | ||
1211 | .device = PCI_DEVICE_ID_DM1105, | ||
1212 | .subvendor = PCI_ANY_ID, | ||
1213 | .subdevice = PCI_ANY_ID, | ||
1214 | }, { | ||
1215 | .vendor = PCI_VENDOR_ID_AXESS, | ||
1216 | .device = PCI_DEVICE_ID_DM05, | ||
1217 | .subvendor = PCI_ANY_ID, | ||
1218 | .subdevice = PCI_ANY_ID, | ||
1219 | }, { | ||
1220 | /* empty */ | ||
1221 | }, | ||
1222 | }; | ||
1223 | |||
1224 | MODULE_DEVICE_TABLE(pci, dm1105_id_table); | ||
1225 | |||
1226 | static struct pci_driver dm1105_driver = { | ||
1227 | .name = DRIVER_NAME, | ||
1228 | .id_table = dm1105_id_table, | ||
1229 | .probe = dm1105_probe, | ||
1230 | .remove = __devexit_p(dm1105_remove), | ||
1231 | }; | ||
1232 | |||
1233 | static int __init dm1105_init(void) | ||
1234 | { | ||
1235 | return pci_register_driver(&dm1105_driver); | ||
1236 | } | ||
1237 | |||
1238 | static void __exit dm1105_exit(void) | ||
1239 | { | ||
1240 | pci_unregister_driver(&dm1105_driver); | ||
1241 | } | ||
1242 | |||
1243 | module_init(dm1105_init); | ||
1244 | module_exit(dm1105_exit); | ||
1245 | |||
1246 | MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>"); | ||
1247 | MODULE_DESCRIPTION("SDMC DM1105 DVB driver"); | ||
1248 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig deleted file mode 100644 index a13a50503134..000000000000 --- a/drivers/media/dvb/mantis/Kconfig +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | config MANTIS_CORE | ||
2 | tristate "Mantis/Hopper PCI bridge based devices" | ||
3 | depends on PCI && I2C && INPUT && RC_CORE | ||
4 | |||
5 | help | ||
6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. | ||
7 | |||
8 | Say Y if you own such a device and want to use it. | ||
9 | |||
10 | config DVB_MANTIS | ||
11 | tristate "MANTIS based cards" | ||
12 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
13 | select DVB_MB86A16 if !DVB_FE_CUSTOMISE | ||
14 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
15 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
16 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
17 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||
18 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
19 | select DVB_TDA665x if !DVB_FE_CUSTOMISE | ||
20 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | ||
21 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
22 | select DVB_PLL | ||
23 | help | ||
24 | Support for PCI cards based on the Mantis PCI bridge. | ||
25 | Say Y when you have a Mantis based DVB card and want to use it. | ||
26 | |||
27 | If unsure say N. | ||
28 | |||
29 | config DVB_HOPPER | ||
30 | tristate "HOPPER based cards" | ||
31 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
32 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
33 | select DVB_PLL | ||
34 | help | ||
35 | Support for PCI cards based on the Hopper PCI bridge. | ||
36 | Say Y when you have a Hopper based DVB card and want to use it. | ||
37 | |||
38 | If unsure say N | ||
diff --git a/drivers/media/dvb/mantis/Makefile b/drivers/media/dvb/mantis/Makefile deleted file mode 100644 index f715051e4453..000000000000 --- a/drivers/media/dvb/mantis/Makefile +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | mantis_core-objs := mantis_ioc.o \ | ||
2 | mantis_uart.o \ | ||
3 | mantis_dma.o \ | ||
4 | mantis_pci.o \ | ||
5 | mantis_i2c.o \ | ||
6 | mantis_dvb.o \ | ||
7 | mantis_evm.o \ | ||
8 | mantis_hif.o \ | ||
9 | mantis_ca.o \ | ||
10 | mantis_pcmcia.o \ | ||
11 | mantis_input.o | ||
12 | |||
13 | mantis-objs := mantis_cards.o \ | ||
14 | mantis_vp1033.o \ | ||
15 | mantis_vp1034.o \ | ||
16 | mantis_vp1041.o \ | ||
17 | mantis_vp2033.o \ | ||
18 | mantis_vp2040.o \ | ||
19 | mantis_vp3030.o | ||
20 | |||
21 | hopper-objs := hopper_cards.o \ | ||
22 | hopper_vp3028.o | ||
23 | |||
24 | obj-$(CONFIG_MANTIS_CORE) += mantis_core.o | ||
25 | obj-$(CONFIG_DVB_MANTIS) += mantis.o | ||
26 | obj-$(CONFIG_DVB_HOPPER) += hopper.o | ||
27 | |||
28 | ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ | ||
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c deleted file mode 100644 index cc0251e01077..000000000000 --- a/drivers/media/dvb/mantis/hopper_cards.c +++ /dev/null | |||
@@ -1,277 +0,0 @@ | |||
1 | /* | ||
2 | Hopper PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <asm/irq.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | |||
29 | #include "dmxdev.h" | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_demux.h" | ||
32 | #include "dvb_frontend.h" | ||
33 | #include "dvb_net.h" | ||
34 | |||
35 | #include "mantis_common.h" | ||
36 | #include "hopper_vp3028.h" | ||
37 | #include "mantis_dma.h" | ||
38 | #include "mantis_dvb.h" | ||
39 | #include "mantis_uart.h" | ||
40 | #include "mantis_ioc.h" | ||
41 | #include "mantis_pci.h" | ||
42 | #include "mantis_i2c.h" | ||
43 | #include "mantis_reg.h" | ||
44 | |||
45 | static unsigned int verbose; | ||
46 | module_param(verbose, int, 0644); | ||
47 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)"); | ||
48 | |||
49 | #define DRIVER_NAME "Hopper" | ||
50 | |||
51 | static char *label[10] = { | ||
52 | "DMA", | ||
53 | "IRQ-0", | ||
54 | "IRQ-1", | ||
55 | "OCERR", | ||
56 | "PABRT", | ||
57 | "RIPRR", | ||
58 | "PPERR", | ||
59 | "FTRGT", | ||
60 | "RISCI", | ||
61 | "RACK" | ||
62 | }; | ||
63 | |||
64 | static int devs; | ||
65 | |||
66 | static irqreturn_t hopper_irq_handler(int irq, void *dev_id) | ||
67 | { | ||
68 | u32 stat = 0, mask = 0; | ||
69 | u32 rst_stat = 0, rst_mask = 0; | ||
70 | |||
71 | struct mantis_pci *mantis; | ||
72 | struct mantis_ca *ca; | ||
73 | |||
74 | mantis = (struct mantis_pci *) dev_id; | ||
75 | if (unlikely(mantis == NULL)) { | ||
76 | dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); | ||
77 | return IRQ_NONE; | ||
78 | } | ||
79 | ca = mantis->mantis_ca; | ||
80 | |||
81 | stat = mmread(MANTIS_INT_STAT); | ||
82 | mask = mmread(MANTIS_INT_MASK); | ||
83 | if (!(stat & mask)) | ||
84 | return IRQ_NONE; | ||
85 | |||
86 | rst_mask = MANTIS_GPIF_WRACK | | ||
87 | MANTIS_GPIF_OTHERR | | ||
88 | MANTIS_SBUF_WSTO | | ||
89 | MANTIS_GPIF_EXTIRQ; | ||
90 | |||
91 | rst_stat = mmread(MANTIS_GPIF_STATUS); | ||
92 | rst_stat &= rst_mask; | ||
93 | mmwrite(rst_stat, MANTIS_GPIF_STATUS); | ||
94 | |||
95 | mantis->mantis_int_stat = stat; | ||
96 | mantis->mantis_int_mask = mask; | ||
97 | dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); | ||
98 | if (stat & MANTIS_INT_RISCEN) { | ||
99 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); | ||
100 | } | ||
101 | if (stat & MANTIS_INT_IRQ0) { | ||
102 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); | ||
103 | mantis->gpif_status = rst_stat; | ||
104 | wake_up(&ca->hif_write_wq); | ||
105 | schedule_work(&ca->hif_evm_work); | ||
106 | } | ||
107 | if (stat & MANTIS_INT_IRQ1) { | ||
108 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); | ||
109 | schedule_work(&mantis->uart_work); | ||
110 | } | ||
111 | if (stat & MANTIS_INT_OCERR) { | ||
112 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); | ||
113 | } | ||
114 | if (stat & MANTIS_INT_PABORT) { | ||
115 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); | ||
116 | } | ||
117 | if (stat & MANTIS_INT_RIPERR) { | ||
118 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); | ||
119 | } | ||
120 | if (stat & MANTIS_INT_PPERR) { | ||
121 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); | ||
122 | } | ||
123 | if (stat & MANTIS_INT_FTRGT) { | ||
124 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); | ||
125 | } | ||
126 | if (stat & MANTIS_INT_RISCI) { | ||
127 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); | ||
128 | mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; | ||
129 | tasklet_schedule(&mantis->tasklet); | ||
130 | } | ||
131 | if (stat & MANTIS_INT_I2CDONE) { | ||
132 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); | ||
133 | wake_up(&mantis->i2c_wq); | ||
134 | } | ||
135 | mmwrite(stat, MANTIS_INT_STAT); | ||
136 | stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | | ||
137 | MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | | ||
138 | MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | | ||
139 | MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | | ||
140 | MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | | ||
141 | MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | | ||
142 | MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | | ||
143 | MANTIS_INT_PABORT | MANTIS_INT_RIPERR | | ||
144 | MANTIS_INT_PPERR | MANTIS_INT_FTRGT | | ||
145 | MANTIS_INT_RISCI); | ||
146 | |||
147 | if (stat) | ||
148 | dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); | ||
149 | |||
150 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
151 | return IRQ_HANDLED; | ||
152 | } | ||
153 | |||
154 | static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
155 | { | ||
156 | struct mantis_pci *mantis; | ||
157 | struct mantis_hwconfig *config; | ||
158 | int err = 0; | ||
159 | |||
160 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
161 | if (mantis == NULL) { | ||
162 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
163 | err = -ENOMEM; | ||
164 | goto fail0; | ||
165 | } | ||
166 | |||
167 | mantis->num = devs; | ||
168 | mantis->verbose = verbose; | ||
169 | mantis->pdev = pdev; | ||
170 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
171 | config->irq_handler = &hopper_irq_handler; | ||
172 | mantis->hwconfig = config; | ||
173 | |||
174 | err = mantis_pci_init(mantis); | ||
175 | if (err) { | ||
176 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
177 | goto fail1; | ||
178 | } | ||
179 | |||
180 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
181 | if (err < 0) { | ||
182 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
183 | goto fail1; | ||
184 | } | ||
185 | |||
186 | err = mantis_i2c_init(mantis); | ||
187 | if (err < 0) { | ||
188 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
189 | goto fail2; | ||
190 | } | ||
191 | |||
192 | err = mantis_get_mac(mantis); | ||
193 | if (err < 0) { | ||
194 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
195 | goto fail2; | ||
196 | } | ||
197 | |||
198 | err = mantis_dma_init(mantis); | ||
199 | if (err < 0) { | ||
200 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
201 | goto fail3; | ||
202 | } | ||
203 | |||
204 | err = mantis_dvb_init(mantis); | ||
205 | if (err < 0) { | ||
206 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
207 | goto fail4; | ||
208 | } | ||
209 | devs++; | ||
210 | |||
211 | return err; | ||
212 | |||
213 | fail4: | ||
214 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
215 | mantis_dma_exit(mantis); | ||
216 | |||
217 | fail3: | ||
218 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
219 | mantis_i2c_exit(mantis); | ||
220 | |||
221 | fail2: | ||
222 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
223 | mantis_pci_exit(mantis); | ||
224 | |||
225 | fail1: | ||
226 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
227 | kfree(mantis); | ||
228 | |||
229 | fail0: | ||
230 | return err; | ||
231 | } | ||
232 | |||
233 | static void __devexit hopper_pci_remove(struct pci_dev *pdev) | ||
234 | { | ||
235 | struct mantis_pci *mantis = pci_get_drvdata(pdev); | ||
236 | |||
237 | if (mantis) { | ||
238 | mantis_dvb_exit(mantis); | ||
239 | mantis_dma_exit(mantis); | ||
240 | mantis_i2c_exit(mantis); | ||
241 | mantis_pci_exit(mantis); | ||
242 | kfree(mantis); | ||
243 | } | ||
244 | return; | ||
245 | |||
246 | } | ||
247 | |||
248 | static struct pci_device_id hopper_pci_table[] = { | ||
249 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config), | ||
250 | { } | ||
251 | }; | ||
252 | |||
253 | MODULE_DEVICE_TABLE(pci, hopper_pci_table); | ||
254 | |||
255 | static struct pci_driver hopper_pci_driver = { | ||
256 | .name = DRIVER_NAME, | ||
257 | .id_table = hopper_pci_table, | ||
258 | .probe = hopper_pci_probe, | ||
259 | .remove = hopper_pci_remove, | ||
260 | }; | ||
261 | |||
262 | static int __devinit hopper_init(void) | ||
263 | { | ||
264 | return pci_register_driver(&hopper_pci_driver); | ||
265 | } | ||
266 | |||
267 | static void __devexit hopper_exit(void) | ||
268 | { | ||
269 | return pci_unregister_driver(&hopper_pci_driver); | ||
270 | } | ||
271 | |||
272 | module_init(hopper_init); | ||
273 | module_exit(hopper_exit); | ||
274 | |||
275 | MODULE_DESCRIPTION("HOPPER driver"); | ||
276 | MODULE_AUTHOR("Manu Abraham"); | ||
277 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.c b/drivers/media/dvb/mantis/hopper_vp3028.c deleted file mode 100644 index 68a29f8bdf73..000000000000 --- a/drivers/media/dvb/mantis/hopper_vp3028.c +++ /dev/null | |||
@@ -1,88 +0,0 @@ | |||
1 | /* | ||
2 | Hopper VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "zl10353.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "hopper_vp3028.h" | ||
36 | |||
37 | struct zl10353_config hopper_vp3028_config = { | ||
38 | .demod_address = 0x0f, | ||
39 | }; | ||
40 | |||
41 | #define MANTIS_MODEL_NAME "VP-3028" | ||
42 | #define MANTIS_DEV_TYPE "DVB-T" | ||
43 | |||
44 | static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
45 | { | ||
46 | struct i2c_adapter *adapter = &mantis->adapter; | ||
47 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
48 | int err = 0; | ||
49 | |||
50 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
51 | msleep(100); | ||
52 | err = mantis_frontend_power(mantis, POWER_ON); | ||
53 | msleep(100); | ||
54 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
55 | |||
56 | err = mantis_frontend_power(mantis, POWER_ON); | ||
57 | if (err == 0) { | ||
58 | msleep(250); | ||
59 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
60 | fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter); | ||
61 | |||
62 | if (!fe) | ||
63 | return -1; | ||
64 | } else { | ||
65 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
66 | adapter->name, | ||
67 | err); | ||
68 | |||
69 | return -EIO; | ||
70 | } | ||
71 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | struct mantis_hwconfig vp3028_config = { | ||
77 | .model_name = MANTIS_MODEL_NAME, | ||
78 | .dev_type = MANTIS_DEV_TYPE, | ||
79 | .ts_size = MANTIS_TS_188, | ||
80 | |||
81 | .baud_rate = MANTIS_BAUD_9600, | ||
82 | .parity = MANTIS_PARITY_NONE, | ||
83 | .bytes = 0, | ||
84 | |||
85 | .frontend_init = vp3028_frontend_init, | ||
86 | .power = GPIF_A00, | ||
87 | .reset = GPIF_A03, | ||
88 | }; | ||
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.h b/drivers/media/dvb/mantis/hopper_vp3028.h deleted file mode 100644 index 57239498bc87..000000000000 --- a/drivers/media/dvb/mantis/hopper_vp3028.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | Hopper VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP3028_H | ||
22 | #define __MANTIS_VP3028_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
27 | |||
28 | extern struct mantis_hwconfig vp3028_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c deleted file mode 100644 index 3d7046909009..000000000000 --- a/drivers/media/dvb/mantis/mantis_ca.c +++ /dev/null | |||
@@ -1,209 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #include "dmxdev.h" | ||
28 | #include "dvbdev.h" | ||
29 | #include "dvb_demux.h" | ||
30 | #include "dvb_frontend.h" | ||
31 | #include "dvb_net.h" | ||
32 | |||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_link.h" | ||
35 | #include "mantis_hif.h" | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | #include "mantis_ca.h" | ||
39 | |||
40 | static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr) | ||
41 | { | ||
42 | struct mantis_ca *ca = en50221->data; | ||
43 | struct mantis_pci *mantis = ca->ca_priv; | ||
44 | |||
45 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot); | ||
46 | |||
47 | if (slot != 0) | ||
48 | return -EINVAL; | ||
49 | |||
50 | return mantis_hif_read_mem(ca, addr); | ||
51 | } | ||
52 | |||
53 | static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data) | ||
54 | { | ||
55 | struct mantis_ca *ca = en50221->data; | ||
56 | struct mantis_pci *mantis = ca->ca_priv; | ||
57 | |||
58 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot); | ||
59 | |||
60 | if (slot != 0) | ||
61 | return -EINVAL; | ||
62 | |||
63 | return mantis_hif_write_mem(ca, addr, data); | ||
64 | } | ||
65 | |||
66 | static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) | ||
67 | { | ||
68 | struct mantis_ca *ca = en50221->data; | ||
69 | struct mantis_pci *mantis = ca->ca_priv; | ||
70 | |||
71 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot); | ||
72 | |||
73 | if (slot != 0) | ||
74 | return -EINVAL; | ||
75 | |||
76 | return mantis_hif_read_iom(ca, addr); | ||
77 | } | ||
78 | |||
79 | static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data) | ||
80 | { | ||
81 | struct mantis_ca *ca = en50221->data; | ||
82 | struct mantis_pci *mantis = ca->ca_priv; | ||
83 | |||
84 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot); | ||
85 | |||
86 | if (slot != 0) | ||
87 | return -EINVAL; | ||
88 | |||
89 | return mantis_hif_write_iom(ca, addr, data); | ||
90 | } | ||
91 | |||
92 | static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot) | ||
93 | { | ||
94 | struct mantis_ca *ca = en50221->data; | ||
95 | struct mantis_pci *mantis = ca->ca_priv; | ||
96 | |||
97 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot); | ||
98 | udelay(500); /* Wait.. */ | ||
99 | mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */ | ||
100 | udelay(500); | ||
101 | mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */ | ||
102 | msleep(1000); | ||
103 | dvb_ca_en50221_camready_irq(&ca->en50221, 0); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) | ||
109 | { | ||
110 | struct mantis_ca *ca = en50221->data; | ||
111 | struct mantis_pci *mantis = ca->ca_priv; | ||
112 | |||
113 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot) | ||
119 | { | ||
120 | struct mantis_ca *ca = en50221->data; | ||
121 | struct mantis_pci *mantis = ca->ca_priv; | ||
122 | |||
123 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot); | ||
124 | /* mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */ | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open) | ||
130 | { | ||
131 | struct mantis_ca *ca = en50221->data; | ||
132 | struct mantis_pci *mantis = ca->ca_priv; | ||
133 | |||
134 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot); | ||
135 | |||
136 | if (ca->slot_state == MODULE_INSERTED) { | ||
137 | dprintk(MANTIS_DEBUG, 1, "CA Module present and ready"); | ||
138 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
139 | } else { | ||
140 | dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready"); | ||
141 | } | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | int mantis_ca_init(struct mantis_pci *mantis) | ||
147 | { | ||
148 | struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter; | ||
149 | struct mantis_ca *ca; | ||
150 | int ca_flags = 0, result; | ||
151 | |||
152 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA"); | ||
153 | ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL); | ||
154 | if (!ca) { | ||
155 | dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting .."); | ||
156 | result = -ENOMEM; | ||
157 | goto err; | ||
158 | } | ||
159 | |||
160 | ca->ca_priv = mantis; | ||
161 | mantis->mantis_ca = ca; | ||
162 | ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE; | ||
163 | /* register CA interface */ | ||
164 | ca->en50221.owner = THIS_MODULE; | ||
165 | ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem; | ||
166 | ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem; | ||
167 | ca->en50221.read_cam_control = mantis_ca_read_cam_ctl; | ||
168 | ca->en50221.write_cam_control = mantis_ca_write_cam_ctl; | ||
169 | ca->en50221.slot_reset = mantis_ca_slot_reset; | ||
170 | ca->en50221.slot_shutdown = mantis_ca_slot_shutdown; | ||
171 | ca->en50221.slot_ts_enable = mantis_ts_control; | ||
172 | ca->en50221.poll_slot_status = mantis_slot_status; | ||
173 | ca->en50221.data = ca; | ||
174 | |||
175 | mutex_init(&ca->ca_lock); | ||
176 | |||
177 | init_waitqueue_head(&ca->hif_data_wq); | ||
178 | init_waitqueue_head(&ca->hif_opdone_wq); | ||
179 | init_waitqueue_head(&ca->hif_write_wq); | ||
180 | |||
181 | dprintk(MANTIS_ERROR, 1, "Registering EN50221 device"); | ||
182 | result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1); | ||
183 | if (result != 0) { | ||
184 | dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result); | ||
185 | goto err; | ||
186 | } | ||
187 | dprintk(MANTIS_ERROR, 1, "Registered EN50221 device"); | ||
188 | mantis_evmgr_init(ca); | ||
189 | return 0; | ||
190 | err: | ||
191 | kfree(ca); | ||
192 | return result; | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(mantis_ca_init); | ||
195 | |||
196 | void mantis_ca_exit(struct mantis_pci *mantis) | ||
197 | { | ||
198 | struct mantis_ca *ca = mantis->mantis_ca; | ||
199 | |||
200 | dprintk(MANTIS_DEBUG, 1, "Mantis CA exit"); | ||
201 | |||
202 | mantis_evmgr_exit(ca); | ||
203 | dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device"); | ||
204 | if (ca) | ||
205 | dvb_ca_en50221_release(&ca->en50221); | ||
206 | |||
207 | kfree(ca); | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(mantis_ca_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_ca.h b/drivers/media/dvb/mantis/mantis_ca.h deleted file mode 100644 index dc63e55f7eca..000000000000 --- a/drivers/media/dvb/mantis/mantis_ca.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_CA_H | ||
22 | #define __MANTIS_CA_H | ||
23 | |||
24 | extern int mantis_ca_init(struct mantis_pci *mantis); | ||
25 | extern void mantis_ca_exit(struct mantis_pci *mantis); | ||
26 | |||
27 | #endif /* __MANTIS_CA_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c deleted file mode 100644 index 0207d1f064e0..000000000000 --- a/drivers/media/dvb/mantis/mantis_cards.c +++ /dev/null | |||
@@ -1,307 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <asm/irq.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | |||
29 | #include "dmxdev.h" | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_demux.h" | ||
32 | #include "dvb_frontend.h" | ||
33 | #include "dvb_net.h" | ||
34 | |||
35 | #include "mantis_common.h" | ||
36 | |||
37 | #include "mantis_vp1033.h" | ||
38 | #include "mantis_vp1034.h" | ||
39 | #include "mantis_vp1041.h" | ||
40 | #include "mantis_vp2033.h" | ||
41 | #include "mantis_vp2040.h" | ||
42 | #include "mantis_vp3030.h" | ||
43 | |||
44 | #include "mantis_dma.h" | ||
45 | #include "mantis_ca.h" | ||
46 | #include "mantis_dvb.h" | ||
47 | #include "mantis_uart.h" | ||
48 | #include "mantis_ioc.h" | ||
49 | #include "mantis_pci.h" | ||
50 | #include "mantis_i2c.h" | ||
51 | #include "mantis_reg.h" | ||
52 | |||
53 | static unsigned int verbose; | ||
54 | module_param(verbose, int, 0644); | ||
55 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)"); | ||
56 | |||
57 | static int devs; | ||
58 | |||
59 | #define DRIVER_NAME "Mantis" | ||
60 | |||
61 | static char *label[10] = { | ||
62 | "DMA", | ||
63 | "IRQ-0", | ||
64 | "IRQ-1", | ||
65 | "OCERR", | ||
66 | "PABRT", | ||
67 | "RIPRR", | ||
68 | "PPERR", | ||
69 | "FTRGT", | ||
70 | "RISCI", | ||
71 | "RACK" | ||
72 | }; | ||
73 | |||
74 | static irqreturn_t mantis_irq_handler(int irq, void *dev_id) | ||
75 | { | ||
76 | u32 stat = 0, mask = 0; | ||
77 | u32 rst_stat = 0, rst_mask = 0; | ||
78 | |||
79 | struct mantis_pci *mantis; | ||
80 | struct mantis_ca *ca; | ||
81 | |||
82 | mantis = (struct mantis_pci *) dev_id; | ||
83 | if (unlikely(mantis == NULL)) { | ||
84 | dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); | ||
85 | return IRQ_NONE; | ||
86 | } | ||
87 | ca = mantis->mantis_ca; | ||
88 | |||
89 | stat = mmread(MANTIS_INT_STAT); | ||
90 | mask = mmread(MANTIS_INT_MASK); | ||
91 | if (!(stat & mask)) | ||
92 | return IRQ_NONE; | ||
93 | |||
94 | rst_mask = MANTIS_GPIF_WRACK | | ||
95 | MANTIS_GPIF_OTHERR | | ||
96 | MANTIS_SBUF_WSTO | | ||
97 | MANTIS_GPIF_EXTIRQ; | ||
98 | |||
99 | rst_stat = mmread(MANTIS_GPIF_STATUS); | ||
100 | rst_stat &= rst_mask; | ||
101 | mmwrite(rst_stat, MANTIS_GPIF_STATUS); | ||
102 | |||
103 | mantis->mantis_int_stat = stat; | ||
104 | mantis->mantis_int_mask = mask; | ||
105 | dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); | ||
106 | if (stat & MANTIS_INT_RISCEN) { | ||
107 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); | ||
108 | } | ||
109 | if (stat & MANTIS_INT_IRQ0) { | ||
110 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); | ||
111 | mantis->gpif_status = rst_stat; | ||
112 | wake_up(&ca->hif_write_wq); | ||
113 | schedule_work(&ca->hif_evm_work); | ||
114 | } | ||
115 | if (stat & MANTIS_INT_IRQ1) { | ||
116 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); | ||
117 | schedule_work(&mantis->uart_work); | ||
118 | } | ||
119 | if (stat & MANTIS_INT_OCERR) { | ||
120 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); | ||
121 | } | ||
122 | if (stat & MANTIS_INT_PABORT) { | ||
123 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); | ||
124 | } | ||
125 | if (stat & MANTIS_INT_RIPERR) { | ||
126 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); | ||
127 | } | ||
128 | if (stat & MANTIS_INT_PPERR) { | ||
129 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); | ||
130 | } | ||
131 | if (stat & MANTIS_INT_FTRGT) { | ||
132 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); | ||
133 | } | ||
134 | if (stat & MANTIS_INT_RISCI) { | ||
135 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); | ||
136 | mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; | ||
137 | tasklet_schedule(&mantis->tasklet); | ||
138 | } | ||
139 | if (stat & MANTIS_INT_I2CDONE) { | ||
140 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); | ||
141 | wake_up(&mantis->i2c_wq); | ||
142 | } | ||
143 | mmwrite(stat, MANTIS_INT_STAT); | ||
144 | stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | | ||
145 | MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | | ||
146 | MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | | ||
147 | MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | | ||
148 | MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | | ||
149 | MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | | ||
150 | MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | | ||
151 | MANTIS_INT_PABORT | MANTIS_INT_RIPERR | | ||
152 | MANTIS_INT_PPERR | MANTIS_INT_FTRGT | | ||
153 | MANTIS_INT_RISCI); | ||
154 | |||
155 | if (stat) | ||
156 | dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); | ||
157 | |||
158 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
159 | return IRQ_HANDLED; | ||
160 | } | ||
161 | |||
162 | static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
163 | { | ||
164 | struct mantis_pci *mantis; | ||
165 | struct mantis_hwconfig *config; | ||
166 | int err = 0; | ||
167 | |||
168 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
169 | if (mantis == NULL) { | ||
170 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
171 | err = -ENOMEM; | ||
172 | goto fail0; | ||
173 | } | ||
174 | |||
175 | mantis->num = devs; | ||
176 | mantis->verbose = verbose; | ||
177 | mantis->pdev = pdev; | ||
178 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
179 | config->irq_handler = &mantis_irq_handler; | ||
180 | mantis->hwconfig = config; | ||
181 | |||
182 | err = mantis_pci_init(mantis); | ||
183 | if (err) { | ||
184 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
185 | goto fail1; | ||
186 | } | ||
187 | |||
188 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
189 | if (err < 0) { | ||
190 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
191 | goto fail1; | ||
192 | } | ||
193 | |||
194 | err = mantis_i2c_init(mantis); | ||
195 | if (err < 0) { | ||
196 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
197 | goto fail2; | ||
198 | } | ||
199 | |||
200 | err = mantis_get_mac(mantis); | ||
201 | if (err < 0) { | ||
202 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
203 | goto fail2; | ||
204 | } | ||
205 | |||
206 | err = mantis_dma_init(mantis); | ||
207 | if (err < 0) { | ||
208 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
209 | goto fail3; | ||
210 | } | ||
211 | |||
212 | err = mantis_dvb_init(mantis); | ||
213 | if (err < 0) { | ||
214 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
215 | goto fail4; | ||
216 | } | ||
217 | err = mantis_uart_init(mantis); | ||
218 | if (err < 0) { | ||
219 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); | ||
220 | goto fail6; | ||
221 | } | ||
222 | |||
223 | devs++; | ||
224 | |||
225 | return err; | ||
226 | |||
227 | |||
228 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err); | ||
229 | mantis_uart_exit(mantis); | ||
230 | |||
231 | fail6: | ||
232 | fail4: | ||
233 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
234 | mantis_dma_exit(mantis); | ||
235 | |||
236 | fail3: | ||
237 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
238 | mantis_i2c_exit(mantis); | ||
239 | |||
240 | fail2: | ||
241 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
242 | mantis_pci_exit(mantis); | ||
243 | |||
244 | fail1: | ||
245 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
246 | kfree(mantis); | ||
247 | |||
248 | fail0: | ||
249 | return err; | ||
250 | } | ||
251 | |||
252 | static void __devexit mantis_pci_remove(struct pci_dev *pdev) | ||
253 | { | ||
254 | struct mantis_pci *mantis = pci_get_drvdata(pdev); | ||
255 | |||
256 | if (mantis) { | ||
257 | |||
258 | mantis_uart_exit(mantis); | ||
259 | mantis_dvb_exit(mantis); | ||
260 | mantis_dma_exit(mantis); | ||
261 | mantis_i2c_exit(mantis); | ||
262 | mantis_pci_exit(mantis); | ||
263 | kfree(mantis); | ||
264 | } | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | static struct pci_device_id mantis_pci_table[] = { | ||
269 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config), | ||
270 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config), | ||
271 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config), | ||
272 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config), | ||
273 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config), | ||
274 | MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config), | ||
275 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config), | ||
276 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config), | ||
277 | MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config), | ||
278 | MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config), | ||
279 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config), | ||
280 | { } | ||
281 | }; | ||
282 | |||
283 | MODULE_DEVICE_TABLE(pci, mantis_pci_table); | ||
284 | |||
285 | static struct pci_driver mantis_pci_driver = { | ||
286 | .name = DRIVER_NAME, | ||
287 | .id_table = mantis_pci_table, | ||
288 | .probe = mantis_pci_probe, | ||
289 | .remove = mantis_pci_remove, | ||
290 | }; | ||
291 | |||
292 | static int __devinit mantis_init(void) | ||
293 | { | ||
294 | return pci_register_driver(&mantis_pci_driver); | ||
295 | } | ||
296 | |||
297 | static void __devexit mantis_exit(void) | ||
298 | { | ||
299 | return pci_unregister_driver(&mantis_pci_driver); | ||
300 | } | ||
301 | |||
302 | module_init(mantis_init); | ||
303 | module_exit(mantis_exit); | ||
304 | |||
305 | MODULE_DESCRIPTION("MANTIS driver"); | ||
306 | MODULE_AUTHOR("Manu Abraham"); | ||
307 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h deleted file mode 100644 index f2410cf0a6bf..000000000000 --- a/drivers/media/dvb/mantis/mantis_common.h +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_COMMON_H | ||
22 | #define __MANTIS_COMMON_H | ||
23 | |||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/workqueue.h> | ||
27 | |||
28 | #include "mantis_uart.h" | ||
29 | |||
30 | #include "mantis_link.h" | ||
31 | |||
32 | #define MANTIS_ERROR 0 | ||
33 | #define MANTIS_NOTICE 1 | ||
34 | #define MANTIS_INFO 2 | ||
35 | #define MANTIS_DEBUG 3 | ||
36 | #define MANTIS_TMG 9 | ||
37 | |||
38 | #define dprintk(y, z, format, arg...) do { \ | ||
39 | if (z) { \ | ||
40 | if ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y)) \ | ||
41 | printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
42 | else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y)) \ | ||
43 | printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
44 | else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y)) \ | ||
45 | printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
46 | else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y)) \ | ||
47 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
48 | else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y)) \ | ||
49 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
50 | } else { \ | ||
51 | if (mantis->verbose > y) \ | ||
52 | printk(format , ##arg); \ | ||
53 | } \ | ||
54 | } while(0) | ||
55 | |||
56 | #define mwrite(dat, addr) writel((dat), addr) | ||
57 | #define mread(addr) readl(addr) | ||
58 | |||
59 | #define mmwrite(dat, addr) mwrite((dat), (mantis->mmio + (addr))) | ||
60 | #define mmread(addr) mread(mantis->mmio + (addr)) | ||
61 | |||
62 | #define MANTIS_TS_188 0 | ||
63 | #define MANTIS_TS_204 1 | ||
64 | |||
65 | #define TWINHAN_TECHNOLOGIES 0x1822 | ||
66 | #define MANTIS 0x4e35 | ||
67 | |||
68 | #define TECHNISAT 0x1ae4 | ||
69 | #define TERRATEC 0x153b | ||
70 | |||
71 | #define MAKE_ENTRY(__subven, __subdev, __configptr) { \ | ||
72 | .vendor = TWINHAN_TECHNOLOGIES, \ | ||
73 | .device = MANTIS, \ | ||
74 | .subvendor = (__subven), \ | ||
75 | .subdevice = (__subdev), \ | ||
76 | .driver_data = (unsigned long) (__configptr) \ | ||
77 | } | ||
78 | |||
79 | enum mantis_i2c_mode { | ||
80 | MANTIS_PAGE_MODE = 0, | ||
81 | MANTIS_BYTE_MODE, | ||
82 | }; | ||
83 | |||
84 | struct mantis_pci; | ||
85 | |||
86 | struct mantis_hwconfig { | ||
87 | char *model_name; | ||
88 | char *dev_type; | ||
89 | u32 ts_size; | ||
90 | |||
91 | enum mantis_baud baud_rate; | ||
92 | enum mantis_parity parity; | ||
93 | u32 bytes; | ||
94 | |||
95 | irqreturn_t (*irq_handler)(int irq, void *dev_id); | ||
96 | int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe); | ||
97 | |||
98 | u8 power; | ||
99 | u8 reset; | ||
100 | |||
101 | enum mantis_i2c_mode i2c_mode; | ||
102 | }; | ||
103 | |||
104 | struct mantis_pci { | ||
105 | unsigned int verbose; | ||
106 | |||
107 | /* PCI stuff */ | ||
108 | u16 vendor_id; | ||
109 | u16 device_id; | ||
110 | u16 subsystem_vendor; | ||
111 | u16 subsystem_device; | ||
112 | |||
113 | u8 latency; | ||
114 | |||
115 | struct pci_dev *pdev; | ||
116 | |||
117 | unsigned long mantis_addr; | ||
118 | void __iomem *mmio; | ||
119 | |||
120 | u8 irq; | ||
121 | u8 revision; | ||
122 | |||
123 | unsigned int num; | ||
124 | |||
125 | /* RISC Core */ | ||
126 | u32 busy_block; | ||
127 | u32 last_block; | ||
128 | u8 *buf_cpu; | ||
129 | dma_addr_t buf_dma; | ||
130 | u32 *risc_cpu; | ||
131 | dma_addr_t risc_dma; | ||
132 | |||
133 | struct tasklet_struct tasklet; | ||
134 | |||
135 | struct i2c_adapter adapter; | ||
136 | int i2c_rc; | ||
137 | wait_queue_head_t i2c_wq; | ||
138 | struct mutex i2c_lock; | ||
139 | |||
140 | /* DVB stuff */ | ||
141 | struct dvb_adapter dvb_adapter; | ||
142 | struct dvb_frontend *fe; | ||
143 | struct dvb_demux demux; | ||
144 | struct dmxdev dmxdev; | ||
145 | struct dmx_frontend fe_hw; | ||
146 | struct dmx_frontend fe_mem; | ||
147 | struct dvb_net dvbnet; | ||
148 | |||
149 | u8 feeds; | ||
150 | |||
151 | struct mantis_hwconfig *hwconfig; | ||
152 | |||
153 | u32 mantis_int_stat; | ||
154 | u32 mantis_int_mask; | ||
155 | |||
156 | /* board specific */ | ||
157 | u8 mac_address[8]; | ||
158 | u32 sub_vendor_id; | ||
159 | u32 sub_device_id; | ||
160 | |||
161 | /* A12 A13 A14 */ | ||
162 | u32 gpio_status; | ||
163 | |||
164 | u32 gpif_status; | ||
165 | |||
166 | struct mantis_ca *mantis_ca; | ||
167 | |||
168 | wait_queue_head_t uart_wq; | ||
169 | struct work_struct uart_work; | ||
170 | spinlock_t uart_lock; | ||
171 | |||
172 | struct rc_dev *rc; | ||
173 | char input_name[80]; | ||
174 | char input_phys[80]; | ||
175 | }; | ||
176 | |||
177 | #define MANTIS_HIF_STATUS (mantis->gpio_status) | ||
178 | |||
179 | #endif /* __MANTIS_COMMON_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/dvb/mantis/mantis_core.c deleted file mode 100644 index 684d9061fe2a..000000000000 --- a/drivers/media/dvb/mantis/mantis_core.c +++ /dev/null | |||
@@ -1,235 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include "mantis_common.h" | ||
22 | #include "mantis_core.h" | ||
23 | #include "mantis_vp1033.h" | ||
24 | #include "mantis_vp1034.h" | ||
25 | #include "mantis_vp1041.h" | ||
26 | #include "mantis_vp2033.h" | ||
27 | #include "mantis_vp2040.h" | ||
28 | #include "mantis_vp3030.h" | ||
29 | |||
30 | static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
31 | { | ||
32 | int err; | ||
33 | struct i2c_msg msg[] = { | ||
34 | { | ||
35 | .addr = 0x50, | ||
36 | .flags = 0, | ||
37 | .buf = data, | ||
38 | .len = 1 | ||
39 | }, { | ||
40 | .addr = 0x50, | ||
41 | .flags = I2C_M_RD, | ||
42 | .buf = data, | ||
43 | .len = length | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | err = i2c_transfer(&mantis->adapter, msg, 2); | ||
48 | if (err < 0) { | ||
49 | dprintk(verbose, MANTIS_ERROR, 1, | ||
50 | "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
51 | err, data[0], data[1]); | ||
52 | |||
53 | return err; | ||
54 | } | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
60 | { | ||
61 | int err; | ||
62 | |||
63 | struct i2c_msg msg = { | ||
64 | .addr = 0x50, | ||
65 | .flags = 0, | ||
66 | .buf = data, | ||
67 | .len = length | ||
68 | }; | ||
69 | |||
70 | err = i2c_transfer(&mantis->adapter, &msg, 1); | ||
71 | if (err < 0) { | ||
72 | dprintk(verbose, MANTIS_ERROR, 1, | ||
73 | "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >", | ||
74 | err, length, data[0], data[1]); | ||
75 | |||
76 | return err; | ||
77 | } | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int get_mac_address(struct mantis_pci *mantis) | ||
83 | { | ||
84 | int err; | ||
85 | |||
86 | mantis->mac_address[0] = 0x08; | ||
87 | err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6); | ||
88 | if (err < 0) { | ||
89 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error"); | ||
90 | |||
91 | return err; | ||
92 | } | ||
93 | dprintk(verbose, MANTIS_ERROR, 0, | ||
94 | " MAC Address=[%pM]\n", mantis->mac_address); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | #define MANTIS_MODEL_UNKNOWN "UNKNOWN" | ||
100 | #define MANTIS_DEV_UNKNOWN "UNKNOWN" | ||
101 | |||
102 | struct mantis_hwconfig unknown_device = { | ||
103 | .model_name = MANTIS_MODEL_UNKNOWN, | ||
104 | .dev_type = MANTIS_DEV_UNKNOWN, | ||
105 | }; | ||
106 | |||
107 | static void mantis_load_config(struct mantis_pci *mantis) | ||
108 | { | ||
109 | switch (mantis->subsystem_device) { | ||
110 | case MANTIS_VP_1033_DVB_S: /* VP-1033 */ | ||
111 | mantis->hwconfig = &vp1033_mantis_config; | ||
112 | break; | ||
113 | case MANTIS_VP_1034_DVB_S: /* VP-1034 */ | ||
114 | mantis->hwconfig = &vp1034_mantis_config; | ||
115 | break; | ||
116 | case MANTIS_VP_1041_DVB_S2: /* VP-1041 */ | ||
117 | case TECHNISAT_SKYSTAR_HD2: | ||
118 | mantis->hwconfig = &vp1041_mantis_config; | ||
119 | break; | ||
120 | case MANTIS_VP_2033_DVB_C: /* VP-2033 */ | ||
121 | mantis->hwconfig = &vp2033_mantis_config; | ||
122 | break; | ||
123 | case MANTIS_VP_2040_DVB_C: /* VP-2040 */ | ||
124 | case CINERGY_C: /* VP-2040 clone */ | ||
125 | case TECHNISAT_CABLESTAR_HD2: | ||
126 | mantis->hwconfig = &vp2040_mantis_config; | ||
127 | break; | ||
128 | case MANTIS_VP_3030_DVB_T: /* VP-3030 */ | ||
129 | mantis->hwconfig = &vp3030_mantis_config; | ||
130 | break; | ||
131 | default: | ||
132 | mantis->hwconfig = &unknown_device; | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | int mantis_core_init(struct mantis_pci *mantis) | ||
138 | { | ||
139 | int err = 0; | ||
140 | |||
141 | mantis_load_config(mantis); | ||
142 | dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
143 | mantis->hwconfig->model_name, mantis->hwconfig->dev_type, | ||
144 | mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn)); | ||
145 | dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
146 | mantis->revision, | ||
147 | mantis->subsystem_vendor, mantis->subsystem_device); | ||
148 | dprintk(verbose, MANTIS_ERROR, 0, | ||
149 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
150 | mantis->pdev->irq, mantis->latency, | ||
151 | mantis->mantis_addr, mantis->mantis_mmio); | ||
152 | |||
153 | err = mantis_i2c_init(mantis); | ||
154 | if (err < 0) { | ||
155 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed"); | ||
156 | return err; | ||
157 | } | ||
158 | err = get_mac_address(mantis); | ||
159 | if (err < 0) { | ||
160 | dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed"); | ||
161 | return err; | ||
162 | } | ||
163 | err = mantis_dma_init(mantis); | ||
164 | if (err < 0) { | ||
165 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed"); | ||
166 | return err; | ||
167 | } | ||
168 | err = mantis_dvb_init(mantis); | ||
169 | if (err < 0) { | ||
170 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed"); | ||
171 | return err; | ||
172 | } | ||
173 | err = mantis_uart_init(mantis); | ||
174 | if (err < 0) { | ||
175 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed"); | ||
176 | return err; | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | int mantis_core_exit(struct mantis_pci *mantis) | ||
183 | { | ||
184 | mantis_dma_stop(mantis); | ||
185 | dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping"); | ||
186 | |||
187 | mantis_uart_exit(mantis); | ||
188 | dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed"); | ||
189 | |||
190 | if (mantis_dma_exit(mantis) < 0) | ||
191 | dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); | ||
192 | if (mantis_dvb_exit(mantis) < 0) | ||
193 | dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed"); | ||
194 | if (mantis_i2c_exit(mantis) < 0) | ||
195 | dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed"); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | /* Turn the given bit on or off. */ | ||
201 | void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
202 | { | ||
203 | u32 cur; | ||
204 | |||
205 | cur = mmread(MANTIS_GPIF_ADDR); | ||
206 | if (value) | ||
207 | mantis->gpio_status = cur | (1 << bitpos); | ||
208 | else | ||
209 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
210 | |||
211 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
212 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
213 | udelay(100); | ||
214 | } | ||
215 | |||
216 | /* direction = 0 , no CI passthrough ; 1 , CI passthrough */ | ||
217 | void mantis_set_direction(struct mantis_pci *mantis, int direction) | ||
218 | { | ||
219 | u32 reg; | ||
220 | |||
221 | reg = mmread(0x28); | ||
222 | dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup"); | ||
223 | if (direction == 0x01) { | ||
224 | /* to CI */ | ||
225 | reg |= 0x04; | ||
226 | mmwrite(reg, 0x28); | ||
227 | reg &= 0xff - 0x04; | ||
228 | mmwrite(reg, 0x28); | ||
229 | } else { | ||
230 | reg &= 0xff - 0x04; | ||
231 | mmwrite(reg, 0x28); | ||
232 | reg |= 0x04; | ||
233 | mmwrite(reg, 0x28); | ||
234 | } | ||
235 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_core.h b/drivers/media/dvb/mantis/mantis_core.h deleted file mode 100644 index 833ee42e694e..000000000000 --- a/drivers/media/dvb/mantis/mantis_core.h +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_CORE_H | ||
22 | #define __MANTIS_CORE_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | |||
27 | #define FE_TYPE_SAT 0 | ||
28 | #define FE_TYPE_CAB 1 | ||
29 | #define FE_TYPE_TER 2 | ||
30 | |||
31 | #define FE_TYPE_TS204 0 | ||
32 | #define FE_TYPE_TS188 1 | ||
33 | |||
34 | |||
35 | struct vendorname { | ||
36 | u8 *sub_vendor_name; | ||
37 | u32 sub_vendor_id; | ||
38 | }; | ||
39 | |||
40 | struct devicetype { | ||
41 | u8 *sub_device_name; | ||
42 | u32 sub_device_id; | ||
43 | u8 device_type; | ||
44 | u32 type_flags; | ||
45 | }; | ||
46 | |||
47 | |||
48 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
49 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
50 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
51 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
52 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
53 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
54 | extern int mantis_core_init(struct mantis_pci *mantis); | ||
55 | extern int mantis_core_exit(struct mantis_pci *mantis); | ||
56 | |||
57 | #endif /* __MANTIS_CORE_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c deleted file mode 100644 index 566c407175a4..000000000000 --- a/drivers/media/dvb/mantis/mantis_dma.c +++ /dev/null | |||
@@ -1,230 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <asm/page.h> | ||
23 | #include <linux/vmalloc.h> | ||
24 | #include <linux/pci.h> | ||
25 | |||
26 | #include <asm/irq.h> | ||
27 | #include <linux/signal.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | |||
31 | #include "dmxdev.h" | ||
32 | #include "dvbdev.h" | ||
33 | #include "dvb_demux.h" | ||
34 | #include "dvb_frontend.h" | ||
35 | #include "dvb_net.h" | ||
36 | |||
37 | #include "mantis_common.h" | ||
38 | #include "mantis_reg.h" | ||
39 | #include "mantis_dma.h" | ||
40 | |||
41 | #define RISC_WRITE (0x01 << 28) | ||
42 | #define RISC_JUMP (0x07 << 28) | ||
43 | #define RISC_IRQ (0x01 << 24) | ||
44 | |||
45 | #define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) | ||
46 | #define RISC_FLUSH(risc_pos) (risc_pos = 0) | ||
47 | #define RISC_INSTR(risc_pos, opcode) (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode)) | ||
48 | |||
49 | #define MANTIS_BUF_SIZE (64 * 1024) | ||
50 | #define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE / 4) | ||
51 | #define MANTIS_DMA_TR_BYTES (2 * 1024) /* upper limit: 4095 bytes. */ | ||
52 | #define MANTIS_BLOCK_COUNT (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES) | ||
53 | |||
54 | #define MANTIS_DMA_TR_UNITS (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES) | ||
55 | /* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */ | ||
56 | #define MANTIS_RISC_SIZE PAGE_SIZE /* RISC program must fit here. */ | ||
57 | |||
58 | int mantis_dma_exit(struct mantis_pci *mantis) | ||
59 | { | ||
60 | if (mantis->buf_cpu) { | ||
61 | dprintk(MANTIS_ERROR, 1, | ||
62 | "DMA=0x%lx cpu=0x%p size=%d", | ||
63 | (unsigned long) mantis->buf_dma, | ||
64 | mantis->buf_cpu, | ||
65 | MANTIS_BUF_SIZE); | ||
66 | |||
67 | pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE, | ||
68 | mantis->buf_cpu, mantis->buf_dma); | ||
69 | |||
70 | mantis->buf_cpu = NULL; | ||
71 | } | ||
72 | if (mantis->risc_cpu) { | ||
73 | dprintk(MANTIS_ERROR, 1, | ||
74 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
75 | (unsigned long) mantis->risc_dma, | ||
76 | mantis->risc_cpu, | ||
77 | MANTIS_RISC_SIZE); | ||
78 | |||
79 | pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE, | ||
80 | mantis->risc_cpu, mantis->risc_dma); | ||
81 | |||
82 | mantis->risc_cpu = NULL; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(mantis_dma_exit); | ||
88 | |||
89 | static inline int mantis_alloc_buffers(struct mantis_pci *mantis) | ||
90 | { | ||
91 | if (!mantis->buf_cpu) { | ||
92 | mantis->buf_cpu = pci_alloc_consistent(mantis->pdev, | ||
93 | MANTIS_BUF_SIZE, | ||
94 | &mantis->buf_dma); | ||
95 | if (!mantis->buf_cpu) { | ||
96 | dprintk(MANTIS_ERROR, 1, | ||
97 | "DMA buffer allocation failed"); | ||
98 | |||
99 | goto err; | ||
100 | } | ||
101 | dprintk(MANTIS_ERROR, 1, | ||
102 | "DMA=0x%lx cpu=0x%p size=%d", | ||
103 | (unsigned long) mantis->buf_dma, | ||
104 | mantis->buf_cpu, MANTIS_BUF_SIZE); | ||
105 | } | ||
106 | if (!mantis->risc_cpu) { | ||
107 | mantis->risc_cpu = pci_alloc_consistent(mantis->pdev, | ||
108 | MANTIS_RISC_SIZE, | ||
109 | &mantis->risc_dma); | ||
110 | |||
111 | if (!mantis->risc_cpu) { | ||
112 | dprintk(MANTIS_ERROR, 1, | ||
113 | "RISC program allocation failed"); | ||
114 | |||
115 | mantis_dma_exit(mantis); | ||
116 | |||
117 | goto err; | ||
118 | } | ||
119 | dprintk(MANTIS_ERROR, 1, | ||
120 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
121 | (unsigned long) mantis->risc_dma, | ||
122 | mantis->risc_cpu, MANTIS_RISC_SIZE); | ||
123 | } | ||
124 | |||
125 | return 0; | ||
126 | err: | ||
127 | dprintk(MANTIS_ERROR, 1, "Out of memory (?) ....."); | ||
128 | return -ENOMEM; | ||
129 | } | ||
130 | |||
131 | int mantis_dma_init(struct mantis_pci *mantis) | ||
132 | { | ||
133 | int err = 0; | ||
134 | |||
135 | dprintk(MANTIS_DEBUG, 1, "Mantis DMA init"); | ||
136 | if (mantis_alloc_buffers(mantis) < 0) { | ||
137 | dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer"); | ||
138 | |||
139 | /* Stop RISC Engine */ | ||
140 | mmwrite(0, MANTIS_DMA_CTL); | ||
141 | |||
142 | goto err; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | err: | ||
147 | return err; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(mantis_dma_init); | ||
150 | |||
151 | static inline void mantis_risc_program(struct mantis_pci *mantis) | ||
152 | { | ||
153 | u32 buf_pos = 0; | ||
154 | u32 line, step; | ||
155 | u32 risc_pos; | ||
156 | |||
157 | dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); | ||
158 | RISC_FLUSH(risc_pos); | ||
159 | |||
160 | dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u", | ||
161 | MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES); | ||
162 | |||
163 | for (line = 0; line < MANTIS_BLOCK_COUNT; line++) { | ||
164 | for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) { | ||
165 | dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step); | ||
166 | if (step == 0) { | ||
167 | RISC_INSTR(risc_pos, RISC_WRITE | | ||
168 | RISC_IRQ | | ||
169 | RISC_STATUS(line) | | ||
170 | MANTIS_DMA_TR_BYTES); | ||
171 | } else { | ||
172 | RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES); | ||
173 | } | ||
174 | RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos); | ||
175 | buf_pos += MANTIS_DMA_TR_BYTES; | ||
176 | } | ||
177 | } | ||
178 | RISC_INSTR(risc_pos, RISC_JUMP); | ||
179 | RISC_INSTR(risc_pos, mantis->risc_dma); | ||
180 | } | ||
181 | |||
182 | void mantis_dma_start(struct mantis_pci *mantis) | ||
183 | { | ||
184 | dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine"); | ||
185 | |||
186 | mantis_risc_program(mantis); | ||
187 | mmwrite(mantis->risc_dma, MANTIS_RISC_START); | ||
188 | mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
189 | |||
190 | mmwrite(0, MANTIS_DMA_CTL); | ||
191 | mantis->last_block = mantis->busy_block = 0; | ||
192 | |||
193 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); | ||
194 | |||
195 | mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN | ||
196 | | MANTIS_RISC_EN, MANTIS_DMA_CTL); | ||
197 | |||
198 | } | ||
199 | |||
200 | void mantis_dma_stop(struct mantis_pci *mantis) | ||
201 | { | ||
202 | dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine"); | ||
203 | |||
204 | mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR); | ||
205 | |||
206 | mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN | | ||
207 | MANTIS_DCAP_EN | | ||
208 | MANTIS_RISC_EN)), MANTIS_DMA_CTL); | ||
209 | |||
210 | mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); | ||
211 | |||
212 | mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | | ||
213 | MANTIS_INT_RISCEN), MANTIS_INT_MASK); | ||
214 | } | ||
215 | |||
216 | |||
217 | void mantis_dma_xfer(unsigned long data) | ||
218 | { | ||
219 | struct mantis_pci *mantis = (struct mantis_pci *) data; | ||
220 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
221 | |||
222 | while (mantis->last_block != mantis->busy_block) { | ||
223 | dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", | ||
224 | mantis->last_block, mantis->busy_block); | ||
225 | |||
226 | (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) | ||
227 | (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); | ||
228 | mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT; | ||
229 | } | ||
230 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_dma.h b/drivers/media/dvb/mantis/mantis_dma.h deleted file mode 100644 index 6be00fa82094..000000000000 --- a/drivers/media/dvb/mantis/mantis_dma.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_DMA_H | ||
22 | #define __MANTIS_DMA_H | ||
23 | |||
24 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
25 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
26 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
27 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
28 | extern void mantis_dma_xfer(unsigned long data); | ||
29 | |||
30 | #endif /* __MANTIS_DMA_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c deleted file mode 100644 index 5d15c6b74d9b..000000000000 --- a/drivers/media/dvb/mantis/mantis_dvb.c +++ /dev/null | |||
@@ -1,301 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/bitops.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/pci.h> | ||
27 | #include <linux/i2c.h> | ||
28 | |||
29 | #include "dmxdev.h" | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_demux.h" | ||
32 | #include "dvb_frontend.h" | ||
33 | #include "dvb_net.h" | ||
34 | |||
35 | #include "mantis_common.h" | ||
36 | #include "mantis_dma.h" | ||
37 | #include "mantis_ca.h" | ||
38 | #include "mantis_ioc.h" | ||
39 | #include "mantis_dvb.h" | ||
40 | |||
41 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
42 | |||
43 | int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power) | ||
44 | { | ||
45 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
46 | |||
47 | switch (power) { | ||
48 | case POWER_ON: | ||
49 | dprintk(MANTIS_DEBUG, 1, "Power ON"); | ||
50 | mantis_gpio_set_bits(mantis, config->power, POWER_ON); | ||
51 | msleep(100); | ||
52 | mantis_gpio_set_bits(mantis, config->power, POWER_ON); | ||
53 | msleep(100); | ||
54 | break; | ||
55 | |||
56 | case POWER_OFF: | ||
57 | dprintk(MANTIS_DEBUG, 1, "Power OFF"); | ||
58 | mantis_gpio_set_bits(mantis, config->power, POWER_OFF); | ||
59 | msleep(100); | ||
60 | break; | ||
61 | |||
62 | default: | ||
63 | dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power); | ||
64 | return -1; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(mantis_frontend_power); | ||
70 | |||
71 | void mantis_frontend_soft_reset(struct mantis_pci *mantis) | ||
72 | { | ||
73 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
74 | |||
75 | dprintk(MANTIS_DEBUG, 1, "Frontend RESET"); | ||
76 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
77 | msleep(100); | ||
78 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
79 | msleep(100); | ||
80 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
81 | msleep(100); | ||
82 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
83 | msleep(100); | ||
84 | |||
85 | return; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset); | ||
88 | |||
89 | static int mantis_frontend_shutdown(struct mantis_pci *mantis) | ||
90 | { | ||
91 | int err; | ||
92 | |||
93 | mantis_frontend_soft_reset(mantis); | ||
94 | err = mantis_frontend_power(mantis, POWER_OFF); | ||
95 | if (err != 0) { | ||
96 | dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err); | ||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
104 | { | ||
105 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
106 | struct mantis_pci *mantis = dvbdmx->priv; | ||
107 | |||
108 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed"); | ||
109 | if (!dvbdmx->dmx.frontend) { | ||
110 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | mantis->feeds++; | ||
115 | dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds); | ||
116 | |||
117 | if (mantis->feeds == 1) { | ||
118 | dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); | ||
119 | mantis_dma_start(mantis); | ||
120 | tasklet_enable(&mantis->tasklet); | ||
121 | } | ||
122 | |||
123 | return mantis->feeds; | ||
124 | } | ||
125 | |||
126 | static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
127 | { | ||
128 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
129 | struct mantis_pci *mantis = dvbdmx->priv; | ||
130 | |||
131 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed"); | ||
132 | if (!dvbdmx->dmx.frontend) { | ||
133 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | mantis->feeds--; | ||
138 | if (mantis->feeds == 0) { | ||
139 | dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); | ||
140 | tasklet_disable(&mantis->tasklet); | ||
141 | mantis_dma_stop(mantis); | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | int __devinit mantis_dvb_init(struct mantis_pci *mantis) | ||
148 | { | ||
149 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
150 | int result = -1; | ||
151 | |||
152 | dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter"); | ||
153 | |||
154 | result = dvb_register_adapter(&mantis->dvb_adapter, | ||
155 | "Mantis DVB adapter", | ||
156 | THIS_MODULE, | ||
157 | &mantis->pdev->dev, | ||
158 | adapter_nr); | ||
159 | |||
160 | if (result < 0) { | ||
161 | |||
162 | dprintk(MANTIS_ERROR, 1, "Error registering adapter"); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | mantis->dvb_adapter.priv = mantis; | ||
167 | mantis->demux.dmx.capabilities = DMX_TS_FILTERING | | ||
168 | DMX_SECTION_FILTERING | | ||
169 | DMX_MEMORY_BASED_FILTERING; | ||
170 | |||
171 | mantis->demux.priv = mantis; | ||
172 | mantis->demux.filternum = 256; | ||
173 | mantis->demux.feednum = 256; | ||
174 | mantis->demux.start_feed = mantis_dvb_start_feed; | ||
175 | mantis->demux.stop_feed = mantis_dvb_stop_feed; | ||
176 | mantis->demux.write_to_decoder = NULL; | ||
177 | |||
178 | dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init"); | ||
179 | result = dvb_dmx_init(&mantis->demux); | ||
180 | if (result < 0) { | ||
181 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
182 | |||
183 | goto err0; | ||
184 | } | ||
185 | |||
186 | mantis->dmxdev.filternum = 256; | ||
187 | mantis->dmxdev.demux = &mantis->demux.dmx; | ||
188 | mantis->dmxdev.capabilities = 0; | ||
189 | dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init"); | ||
190 | |||
191 | result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter); | ||
192 | if (result < 0) { | ||
193 | |||
194 | dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); | ||
195 | goto err1; | ||
196 | } | ||
197 | |||
198 | mantis->fe_hw.source = DMX_FRONTEND_0; | ||
199 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
200 | if (result < 0) { | ||
201 | |||
202 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
203 | goto err2; | ||
204 | } | ||
205 | |||
206 | mantis->fe_mem.source = DMX_MEMORY_FE; | ||
207 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
208 | if (result < 0) { | ||
209 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
210 | goto err3; | ||
211 | } | ||
212 | |||
213 | result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
214 | if (result < 0) { | ||
215 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
216 | goto err4; | ||
217 | } | ||
218 | |||
219 | dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); | ||
220 | tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); | ||
221 | tasklet_disable(&mantis->tasklet); | ||
222 | if (mantis->hwconfig) { | ||
223 | result = config->frontend_init(mantis, mantis->fe); | ||
224 | if (result < 0) { | ||
225 | dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!"); | ||
226 | goto err5; | ||
227 | } else { | ||
228 | if (mantis->fe == NULL) { | ||
229 | dprintk(MANTIS_ERROR, 1, "FE <NULL>"); | ||
230 | goto err5; | ||
231 | } | ||
232 | |||
233 | if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) { | ||
234 | dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed"); | ||
235 | |||
236 | if (mantis->fe->ops.release) | ||
237 | mantis->fe->ops.release(mantis->fe); | ||
238 | |||
239 | mantis->fe = NULL; | ||
240 | goto err5; | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | |||
245 | return 0; | ||
246 | |||
247 | /* Error conditions .. */ | ||
248 | err5: | ||
249 | tasklet_kill(&mantis->tasklet); | ||
250 | dvb_net_release(&mantis->dvbnet); | ||
251 | if (mantis->fe) { | ||
252 | dvb_unregister_frontend(mantis->fe); | ||
253 | dvb_frontend_detach(mantis->fe); | ||
254 | } | ||
255 | err4: | ||
256 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
257 | |||
258 | err3: | ||
259 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
260 | |||
261 | err2: | ||
262 | dvb_dmxdev_release(&mantis->dmxdev); | ||
263 | |||
264 | err1: | ||
265 | dvb_dmx_release(&mantis->demux); | ||
266 | |||
267 | err0: | ||
268 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
269 | |||
270 | return result; | ||
271 | } | ||
272 | EXPORT_SYMBOL_GPL(mantis_dvb_init); | ||
273 | |||
274 | int __devexit mantis_dvb_exit(struct mantis_pci *mantis) | ||
275 | { | ||
276 | int err; | ||
277 | |||
278 | if (mantis->fe) { | ||
279 | /* mantis_ca_exit(mantis); */ | ||
280 | err = mantis_frontend_shutdown(mantis); | ||
281 | if (err != 0) | ||
282 | dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err); | ||
283 | dvb_unregister_frontend(mantis->fe); | ||
284 | dvb_frontend_detach(mantis->fe); | ||
285 | } | ||
286 | |||
287 | tasklet_kill(&mantis->tasklet); | ||
288 | dvb_net_release(&mantis->dvbnet); | ||
289 | |||
290 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
291 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
292 | |||
293 | dvb_dmxdev_release(&mantis->dmxdev); | ||
294 | dvb_dmx_release(&mantis->demux); | ||
295 | |||
296 | dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter"); | ||
297 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | EXPORT_SYMBOL_GPL(mantis_dvb_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_dvb.h b/drivers/media/dvb/mantis/mantis_dvb.h deleted file mode 100644 index 464199db304e..000000000000 --- a/drivers/media/dvb/mantis/mantis_dvb.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_DVB_H | ||
22 | #define __MANTIS_DVB_H | ||
23 | |||
24 | enum mantis_power { | ||
25 | POWER_OFF = 0, | ||
26 | POWER_ON = 1 | ||
27 | }; | ||
28 | |||
29 | extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power); | ||
30 | extern void mantis_frontend_soft_reset(struct mantis_pci *mantis); | ||
31 | |||
32 | extern int mantis_dvb_init(struct mantis_pci *mantis); | ||
33 | extern int mantis_dvb_exit(struct mantis_pci *mantis); | ||
34 | |||
35 | #endif /* __MANTIS_DVB_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c deleted file mode 100644 index 71ce52875c38..000000000000 --- a/drivers/media/dvb/mantis/mantis_evm.c +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | #include "mantis_link.h" | ||
36 | #include "mantis_hif.h" | ||
37 | #include "mantis_reg.h" | ||
38 | |||
39 | static void mantis_hifevm_work(struct work_struct *work) | ||
40 | { | ||
41 | struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work); | ||
42 | struct mantis_pci *mantis = ca->ca_priv; | ||
43 | |||
44 | u32 gpif_stat; | ||
45 | |||
46 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
47 | |||
48 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
49 | if (gpif_stat & MANTIS_CARD_PLUGIN) { | ||
50 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num); | ||
51 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
52 | mantis_event_cam_plugin(ca); | ||
53 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
54 | 0, | ||
55 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
56 | } | ||
57 | } else { | ||
58 | if (gpif_stat & MANTIS_CARD_PLUGOUT) { | ||
59 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num); | ||
60 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
61 | mantis_event_cam_unplug(ca); | ||
62 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
63 | 0, | ||
64 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ) | ||
69 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num); | ||
70 | |||
71 | if (mantis->gpif_status & MANTIS_SBUF_WSTO) | ||
72 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num); | ||
73 | |||
74 | if (mantis->gpif_status & MANTIS_GPIF_OTHERR) | ||
75 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num); | ||
76 | |||
77 | if (gpif_stat & MANTIS_SBUF_OVFLW) | ||
78 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num); | ||
79 | |||
80 | if (gpif_stat & MANTIS_GPIF_BRRDY) | ||
81 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num); | ||
82 | |||
83 | if (gpif_stat & MANTIS_GPIF_INTSTAT) | ||
84 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num); | ||
85 | |||
86 | if (gpif_stat & MANTIS_SBUF_EMPTY) | ||
87 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num); | ||
88 | |||
89 | if (gpif_stat & MANTIS_SBUF_OPDONE) { | ||
90 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num); | ||
91 | ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL; | ||
92 | ca->hif_event = MANTIS_SBUF_OPDONE; | ||
93 | wake_up(&ca->hif_opdone_wq); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | int mantis_evmgr_init(struct mantis_ca *ca) | ||
98 | { | ||
99 | struct mantis_pci *mantis = ca->ca_priv; | ||
100 | |||
101 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager"); | ||
102 | INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work); | ||
103 | mantis_pcmcia_init(ca); | ||
104 | schedule_work(&ca->hif_evm_work); | ||
105 | mantis_hif_init(ca); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void mantis_evmgr_exit(struct mantis_ca *ca) | ||
110 | { | ||
111 | struct mantis_pci *mantis = ca->ca_priv; | ||
112 | |||
113 | dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); | ||
114 | flush_work_sync(&ca->hif_evm_work); | ||
115 | mantis_hif_exit(ca); | ||
116 | mantis_pcmcia_exit(ca); | ||
117 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c deleted file mode 100644 index 10c68df7e16f..000000000000 --- a/drivers/media/dvb/mantis/mantis_hif.c +++ /dev/null | |||
@@ -1,239 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/signal.h> | ||
23 | #include <linux/sched.h> | ||
24 | |||
25 | #include <linux/interrupt.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | |||
36 | #include "mantis_hif.h" | ||
37 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
38 | |||
39 | #include "mantis_reg.h" | ||
40 | |||
41 | |||
42 | static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca) | ||
43 | { | ||
44 | struct mantis_pci *mantis = ca->ca_priv; | ||
45 | int rc = 0; | ||
46 | |||
47 | if (wait_event_timeout(ca->hif_opdone_wq, | ||
48 | ca->hif_event & MANTIS_SBUF_OPDONE, | ||
49 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
50 | |||
51 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num); | ||
52 | rc = -EREMOTEIO; | ||
53 | } | ||
54 | dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete"); | ||
55 | ca->hif_event &= ~MANTIS_SBUF_OPDONE; | ||
56 | return rc; | ||
57 | } | ||
58 | |||
59 | static int mantis_hif_write_wait(struct mantis_ca *ca) | ||
60 | { | ||
61 | struct mantis_pci *mantis = ca->ca_priv; | ||
62 | u32 opdone = 0, timeout = 0; | ||
63 | int rc = 0; | ||
64 | |||
65 | if (wait_event_timeout(ca->hif_write_wq, | ||
66 | mantis->gpif_status & MANTIS_GPIF_WRACK, | ||
67 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
68 | |||
69 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num); | ||
70 | rc = -EREMOTEIO; | ||
71 | } | ||
72 | dprintk(MANTIS_DEBUG, 1, "Write Acknowledged"); | ||
73 | mantis->gpif_status &= ~MANTIS_GPIF_WRACK; | ||
74 | while (!opdone) { | ||
75 | opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE); | ||
76 | udelay(500); | ||
77 | timeout++; | ||
78 | if (timeout > 100) { | ||
79 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timed out!", mantis->num); | ||
80 | rc = -ETIMEDOUT; | ||
81 | break; | ||
82 | } | ||
83 | } | ||
84 | dprintk(MANTIS_DEBUG, 1, "HIF Write success"); | ||
85 | return rc; | ||
86 | } | ||
87 | |||
88 | |||
89 | int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr) | ||
90 | { | ||
91 | struct mantis_pci *mantis = ca->ca_priv; | ||
92 | u32 hif_addr = 0, data, count = 4; | ||
93 | |||
94 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num); | ||
95 | mutex_lock(&ca->ca_lock); | ||
96 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
97 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
98 | hif_addr |= MANTIS_HIF_STATUS; | ||
99 | hif_addr |= addr; | ||
100 | |||
101 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
102 | mmwrite(count, MANTIS_GPIF_BRBYTES); | ||
103 | udelay(20); | ||
104 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
105 | |||
106 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
107 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num); | ||
108 | mutex_unlock(&ca->ca_lock); | ||
109 | return -EREMOTEIO; | ||
110 | } | ||
111 | data = mmread(MANTIS_GPIF_DIN); | ||
112 | mutex_unlock(&ca->ca_lock); | ||
113 | dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data); | ||
114 | return (data >> 24) & 0xff; | ||
115 | } | ||
116 | |||
117 | int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data) | ||
118 | { | ||
119 | struct mantis_slot *slot = ca->slot; | ||
120 | struct mantis_pci *mantis = ca->ca_priv; | ||
121 | u32 hif_addr = 0; | ||
122 | |||
123 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num); | ||
124 | mutex_lock(&ca->ca_lock); | ||
125 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
126 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
127 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
128 | hif_addr |= MANTIS_HIF_STATUS; | ||
129 | hif_addr |= addr; | ||
130 | |||
131 | mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */ | ||
132 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
133 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
134 | |||
135 | if (mantis_hif_write_wait(ca) != 0) { | ||
136 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
137 | mutex_unlock(&ca->ca_lock); | ||
138 | return -EREMOTEIO; | ||
139 | } | ||
140 | dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr); | ||
141 | mutex_unlock(&ca->ca_lock); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr) | ||
147 | { | ||
148 | struct mantis_pci *mantis = ca->ca_priv; | ||
149 | u32 data, hif_addr = 0; | ||
150 | |||
151 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num); | ||
152 | mutex_lock(&ca->ca_lock); | ||
153 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
154 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
155 | hif_addr |= MANTIS_HIF_STATUS; | ||
156 | hif_addr |= addr; | ||
157 | |||
158 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
159 | mmwrite(1, MANTIS_GPIF_BRBYTES); | ||
160 | udelay(20); | ||
161 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
162 | |||
163 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
164 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
165 | mutex_unlock(&ca->ca_lock); | ||
166 | return -EREMOTEIO; | ||
167 | } | ||
168 | data = mmread(MANTIS_GPIF_DIN); | ||
169 | dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data); | ||
170 | udelay(50); | ||
171 | mutex_unlock(&ca->ca_lock); | ||
172 | |||
173 | return (u8) data; | ||
174 | } | ||
175 | |||
176 | int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data) | ||
177 | { | ||
178 | struct mantis_pci *mantis = ca->ca_priv; | ||
179 | u32 hif_addr = 0; | ||
180 | |||
181 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num); | ||
182 | mutex_lock(&ca->ca_lock); | ||
183 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
184 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
185 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
186 | hif_addr |= MANTIS_HIF_STATUS; | ||
187 | hif_addr |= addr; | ||
188 | |||
189 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
190 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
191 | |||
192 | if (mantis_hif_write_wait(ca) != 0) { | ||
193 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
194 | mutex_unlock(&ca->ca_lock); | ||
195 | return -EREMOTEIO; | ||
196 | } | ||
197 | dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr); | ||
198 | mutex_unlock(&ca->ca_lock); | ||
199 | udelay(50); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | int mantis_hif_init(struct mantis_ca *ca) | ||
205 | { | ||
206 | struct mantis_slot *slot = ca->slot; | ||
207 | struct mantis_pci *mantis = ca->ca_priv; | ||
208 | u32 irqcfg; | ||
209 | |||
210 | slot[0].slave_cfg = 0x70773028; | ||
211 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num); | ||
212 | |||
213 | mutex_lock(&ca->ca_lock); | ||
214 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
215 | irqcfg = MANTIS_MASK_BRRDY | | ||
216 | MANTIS_MASK_WRACK | | ||
217 | MANTIS_MASK_EXTIRQ | | ||
218 | MANTIS_MASK_WSTO | | ||
219 | MANTIS_MASK_OTHERR | | ||
220 | MANTIS_MASK_OVFLW; | ||
221 | |||
222 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
223 | mutex_unlock(&ca->ca_lock); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | void mantis_hif_exit(struct mantis_ca *ca) | ||
229 | { | ||
230 | struct mantis_pci *mantis = ca->ca_priv; | ||
231 | u32 irqcfg; | ||
232 | |||
233 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num); | ||
234 | mutex_lock(&ca->ca_lock); | ||
235 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
236 | irqcfg &= ~MANTIS_MASK_BRRDY; | ||
237 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
238 | mutex_unlock(&ca->ca_lock); | ||
239 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_hif.h b/drivers/media/dvb/mantis/mantis_hif.h deleted file mode 100644 index 9094f9ed2362..000000000000 --- a/drivers/media/dvb/mantis/mantis_hif.h +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_HIF_H | ||
22 | #define __MANTIS_HIF_H | ||
23 | |||
24 | #define MANTIS_HIF_MEMRD 1 | ||
25 | #define MANTIS_HIF_MEMWR 2 | ||
26 | #define MANTIS_HIF_IOMRD 3 | ||
27 | #define MANTIS_HIF_IOMWR 4 | ||
28 | |||
29 | #endif /* __MANTIS_HIF_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c deleted file mode 100644 index e7794517fe26..000000000000 --- a/drivers/media/dvb/mantis/mantis_i2c.c +++ /dev/null | |||
@@ -1,266 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <asm/io.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | #include "dmxdev.h" | ||
27 | #include "dvbdev.h" | ||
28 | #include "dvb_demux.h" | ||
29 | #include "dvb_frontend.h" | ||
30 | #include "dvb_net.h" | ||
31 | |||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_reg.h" | ||
34 | #include "mantis_i2c.h" | ||
35 | |||
36 | #define TRIALS 10000 | ||
37 | |||
38 | static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
39 | { | ||
40 | u32 rxd, i, stat, trials; | ||
41 | |||
42 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ", | ||
43 | __func__, msg->addr); | ||
44 | |||
45 | for (i = 0; i < msg->len; i++) { | ||
46 | rxd = (msg->addr << 25) | (1 << 24) | ||
47 | | MANTIS_I2C_RATE_3 | ||
48 | | MANTIS_I2C_STOP | ||
49 | | MANTIS_I2C_PGMODE; | ||
50 | |||
51 | if (i == (msg->len - 1)) | ||
52 | rxd &= ~MANTIS_I2C_STOP; | ||
53 | |||
54 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
55 | mmwrite(rxd, MANTIS_I2CDATA_CTL); | ||
56 | |||
57 | /* wait for xfer completion */ | ||
58 | for (trials = 0; trials < TRIALS; trials++) { | ||
59 | stat = mmread(MANTIS_INT_STAT); | ||
60 | if (stat & MANTIS_INT_I2CDONE) | ||
61 | break; | ||
62 | } | ||
63 | |||
64 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
65 | |||
66 | /* wait for xfer completion */ | ||
67 | for (trials = 0; trials < TRIALS; trials++) { | ||
68 | stat = mmread(MANTIS_INT_STAT); | ||
69 | if (stat & MANTIS_INT_I2CRACK) | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
74 | |||
75 | rxd = mmread(MANTIS_I2CDATA_CTL); | ||
76 | msg->buf[i] = (u8)((rxd >> 8) & 0xFF); | ||
77 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
78 | } | ||
79 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
85 | { | ||
86 | int i; | ||
87 | u32 txd = 0, stat, trials; | ||
88 | |||
89 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ", | ||
90 | __func__, msg->addr); | ||
91 | |||
92 | for (i = 0; i < msg->len; i++) { | ||
93 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
94 | txd = (msg->addr << 25) | (msg->buf[i] << 8) | ||
95 | | MANTIS_I2C_RATE_3 | ||
96 | | MANTIS_I2C_STOP | ||
97 | | MANTIS_I2C_PGMODE; | ||
98 | |||
99 | if (i == (msg->len - 1)) | ||
100 | txd &= ~MANTIS_I2C_STOP; | ||
101 | |||
102 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
103 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
104 | |||
105 | /* wait for xfer completion */ | ||
106 | for (trials = 0; trials < TRIALS; trials++) { | ||
107 | stat = mmread(MANTIS_INT_STAT); | ||
108 | if (stat & MANTIS_INT_I2CDONE) | ||
109 | break; | ||
110 | } | ||
111 | |||
112 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
113 | |||
114 | /* wait for xfer completion */ | ||
115 | for (trials = 0; trials < TRIALS; trials++) { | ||
116 | stat = mmread(MANTIS_INT_STAT); | ||
117 | if (stat & MANTIS_INT_I2CRACK) | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
122 | } | ||
123 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | ||
129 | { | ||
130 | int ret = 0, i = 0, trials; | ||
131 | u32 stat, data, txd; | ||
132 | struct mantis_pci *mantis; | ||
133 | struct mantis_hwconfig *config; | ||
134 | |||
135 | mantis = i2c_get_adapdata(adapter); | ||
136 | BUG_ON(!mantis); | ||
137 | config = mantis->hwconfig; | ||
138 | BUG_ON(!config); | ||
139 | |||
140 | dprintk(MANTIS_DEBUG, 1, "Messages:%d", num); | ||
141 | mutex_lock(&mantis->i2c_lock); | ||
142 | |||
143 | while (i < num) { | ||
144 | /* Byte MODE */ | ||
145 | if ((config->i2c_mode & MANTIS_BYTE_MODE) && | ||
146 | ((i + 1) < num) && | ||
147 | (msgs[i].len < 2) && | ||
148 | (msgs[i + 1].len < 2) && | ||
149 | (msgs[i + 1].flags & I2C_M_RD)) { | ||
150 | |||
151 | dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n"); | ||
152 | |||
153 | /* Read operation */ | ||
154 | txd = msgs[i].addr << 25 | (0x1 << 24) | ||
155 | | (msgs[i].buf[0] << 16) | ||
156 | | MANTIS_I2C_RATE_3; | ||
157 | |||
158 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
159 | /* wait for xfer completion */ | ||
160 | for (trials = 0; trials < TRIALS; trials++) { | ||
161 | stat = mmread(MANTIS_INT_STAT); | ||
162 | if (stat & MANTIS_INT_I2CDONE) | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | /* check for xfer completion */ | ||
167 | if (stat & MANTIS_INT_I2CDONE) { | ||
168 | /* check xfer was acknowledged */ | ||
169 | if (stat & MANTIS_INT_I2CRACK) { | ||
170 | data = mmread(MANTIS_I2CDATA_CTL); | ||
171 | msgs[i + 1].buf[0] = (data >> 8) & 0xff; | ||
172 | dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]); | ||
173 | } else { | ||
174 | /* I/O error */ | ||
175 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
176 | ret = -EIO; | ||
177 | break; | ||
178 | } | ||
179 | } else { | ||
180 | /* I/O error */ | ||
181 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
182 | ret = -EIO; | ||
183 | break; | ||
184 | } | ||
185 | i += 2; /* Write/Read operation in one go */ | ||
186 | } | ||
187 | |||
188 | if (i < num) { | ||
189 | if (msgs[i].flags & I2C_M_RD) | ||
190 | ret = mantis_i2c_read(mantis, &msgs[i]); | ||
191 | else | ||
192 | ret = mantis_i2c_write(mantis, &msgs[i]); | ||
193 | |||
194 | i++; | ||
195 | if (ret < 0) | ||
196 | goto bail_out; | ||
197 | } | ||
198 | |||
199 | } | ||
200 | |||
201 | mutex_unlock(&mantis->i2c_lock); | ||
202 | |||
203 | return num; | ||
204 | |||
205 | bail_out: | ||
206 | mutex_unlock(&mantis->i2c_lock); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | static u32 mantis_i2c_func(struct i2c_adapter *adapter) | ||
211 | { | ||
212 | return I2C_FUNC_SMBUS_EMUL; | ||
213 | } | ||
214 | |||
215 | static struct i2c_algorithm mantis_algo = { | ||
216 | .master_xfer = mantis_i2c_xfer, | ||
217 | .functionality = mantis_i2c_func, | ||
218 | }; | ||
219 | |||
220 | int __devinit mantis_i2c_init(struct mantis_pci *mantis) | ||
221 | { | ||
222 | u32 intstat, intmask; | ||
223 | struct i2c_adapter *i2c_adapter = &mantis->adapter; | ||
224 | struct pci_dev *pdev = mantis->pdev; | ||
225 | |||
226 | init_waitqueue_head(&mantis->i2c_wq); | ||
227 | mutex_init(&mantis->i2c_lock); | ||
228 | strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name)); | ||
229 | i2c_set_adapdata(i2c_adapter, mantis); | ||
230 | |||
231 | i2c_adapter->owner = THIS_MODULE; | ||
232 | i2c_adapter->algo = &mantis_algo; | ||
233 | i2c_adapter->algo_data = NULL; | ||
234 | i2c_adapter->timeout = 500; | ||
235 | i2c_adapter->retries = 3; | ||
236 | i2c_adapter->dev.parent = &pdev->dev; | ||
237 | |||
238 | mantis->i2c_rc = i2c_add_adapter(i2c_adapter); | ||
239 | if (mantis->i2c_rc < 0) | ||
240 | return mantis->i2c_rc; | ||
241 | |||
242 | dprintk(MANTIS_DEBUG, 1, "Initializing I2C .."); | ||
243 | |||
244 | intstat = mmread(MANTIS_INT_STAT); | ||
245 | intmask = mmread(MANTIS_INT_MASK); | ||
246 | mmwrite(intstat, MANTIS_INT_STAT); | ||
247 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
248 | intmask = mmread(MANTIS_INT_MASK); | ||
249 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | EXPORT_SYMBOL_GPL(mantis_i2c_init); | ||
254 | |||
255 | int mantis_i2c_exit(struct mantis_pci *mantis) | ||
256 | { | ||
257 | u32 intmask; | ||
258 | |||
259 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
260 | intmask = mmread(MANTIS_INT_MASK); | ||
261 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
262 | |||
263 | dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); | ||
264 | return i2c_del_adapter(&mantis->adapter); | ||
265 | } | ||
266 | EXPORT_SYMBOL_GPL(mantis_i2c_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_i2c.h b/drivers/media/dvb/mantis/mantis_i2c.h deleted file mode 100644 index 1342df2faed8..000000000000 --- a/drivers/media/dvb/mantis/mantis_i2c.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_I2C_H | ||
22 | #define __MANTIS_I2C_H | ||
23 | |||
24 | #define I2C_STOP (1 << 0) | ||
25 | #define I2C_READ (1 << 1) | ||
26 | |||
27 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
28 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
29 | |||
30 | #endif /* __MANTIS_I2C_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c deleted file mode 100644 index db6d54d3fec0..000000000000 --- a/drivers/media/dvb/mantis/mantis_input.c +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <media/rc-core.h> | ||
22 | #include <linux/pci.h> | ||
23 | |||
24 | #include "dmxdev.h" | ||
25 | #include "dvbdev.h" | ||
26 | #include "dvb_demux.h" | ||
27 | #include "dvb_frontend.h" | ||
28 | #include "dvb_net.h" | ||
29 | |||
30 | #include "mantis_common.h" | ||
31 | #include "mantis_reg.h" | ||
32 | #include "mantis_uart.h" | ||
33 | |||
34 | #define MODULE_NAME "mantis_core" | ||
35 | #define RC_MAP_MANTIS "rc-mantis" | ||
36 | |||
37 | static struct rc_map_table mantis_ir_table[] = { | ||
38 | { 0x29, KEY_POWER }, | ||
39 | { 0x28, KEY_FAVORITES }, | ||
40 | { 0x30, KEY_TEXT }, | ||
41 | { 0x17, KEY_INFO }, /* Preview */ | ||
42 | { 0x23, KEY_EPG }, | ||
43 | { 0x3b, KEY_F22 }, /* Record List */ | ||
44 | { 0x3c, KEY_1 }, | ||
45 | { 0x3e, KEY_2 }, | ||
46 | { 0x39, KEY_3 }, | ||
47 | { 0x36, KEY_4 }, | ||
48 | { 0x22, KEY_5 }, | ||
49 | { 0x20, KEY_6 }, | ||
50 | { 0x32, KEY_7 }, | ||
51 | { 0x26, KEY_8 }, | ||
52 | { 0x24, KEY_9 }, | ||
53 | { 0x2a, KEY_0 }, | ||
54 | |||
55 | { 0x33, KEY_CANCEL }, | ||
56 | { 0x2c, KEY_BACK }, | ||
57 | { 0x15, KEY_CLEAR }, | ||
58 | { 0x3f, KEY_TAB }, | ||
59 | { 0x10, KEY_ENTER }, | ||
60 | { 0x14, KEY_UP }, | ||
61 | { 0x0d, KEY_RIGHT }, | ||
62 | { 0x0e, KEY_DOWN }, | ||
63 | { 0x11, KEY_LEFT }, | ||
64 | |||
65 | { 0x21, KEY_VOLUMEUP }, | ||
66 | { 0x35, KEY_VOLUMEDOWN }, | ||
67 | { 0x3d, KEY_CHANNELDOWN }, | ||
68 | { 0x3a, KEY_CHANNELUP }, | ||
69 | { 0x2e, KEY_RECORD }, | ||
70 | { 0x2b, KEY_PLAY }, | ||
71 | { 0x13, KEY_PAUSE }, | ||
72 | { 0x25, KEY_STOP }, | ||
73 | |||
74 | { 0x1f, KEY_REWIND }, | ||
75 | { 0x2d, KEY_FASTFORWARD }, | ||
76 | { 0x1e, KEY_PREVIOUS }, /* Replay |< */ | ||
77 | { 0x1d, KEY_NEXT }, /* Skip >| */ | ||
78 | |||
79 | { 0x0b, KEY_CAMERA }, /* Capture */ | ||
80 | { 0x0f, KEY_LANGUAGE }, /* SAP */ | ||
81 | { 0x18, KEY_MODE }, /* PIP */ | ||
82 | { 0x12, KEY_ZOOM }, /* Full screen */ | ||
83 | { 0x1c, KEY_SUBTITLE }, | ||
84 | { 0x2f, KEY_MUTE }, | ||
85 | { 0x16, KEY_F20 }, /* L/R */ | ||
86 | { 0x38, KEY_F21 }, /* Hibernate */ | ||
87 | |||
88 | { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */ | ||
89 | { 0x31, KEY_AGAIN }, /* Recall */ | ||
90 | { 0x1a, KEY_KPPLUS }, /* Zoom+ */ | ||
91 | { 0x19, KEY_KPMINUS }, /* Zoom- */ | ||
92 | { 0x27, KEY_RED }, | ||
93 | { 0x0C, KEY_GREEN }, | ||
94 | { 0x01, KEY_YELLOW }, | ||
95 | { 0x00, KEY_BLUE }, | ||
96 | }; | ||
97 | |||
98 | static struct rc_map_list ir_mantis_map = { | ||
99 | .map = { | ||
100 | .scan = mantis_ir_table, | ||
101 | .size = ARRAY_SIZE(mantis_ir_table), | ||
102 | .rc_type = RC_TYPE_UNKNOWN, | ||
103 | .name = RC_MAP_MANTIS, | ||
104 | } | ||
105 | }; | ||
106 | |||
107 | int mantis_input_init(struct mantis_pci *mantis) | ||
108 | { | ||
109 | struct rc_dev *dev; | ||
110 | int err; | ||
111 | |||
112 | err = rc_map_register(&ir_mantis_map); | ||
113 | if (err) | ||
114 | goto out; | ||
115 | |||
116 | dev = rc_allocate_device(); | ||
117 | if (!dev) { | ||
118 | dprintk(MANTIS_ERROR, 1, "Remote device allocation failed"); | ||
119 | err = -ENOMEM; | ||
120 | goto out_map; | ||
121 | } | ||
122 | |||
123 | sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name); | ||
124 | sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev)); | ||
125 | |||
126 | dev->input_name = mantis->input_name; | ||
127 | dev->input_phys = mantis->input_phys; | ||
128 | dev->input_id.bustype = BUS_PCI; | ||
129 | dev->input_id.vendor = mantis->vendor_id; | ||
130 | dev->input_id.product = mantis->device_id; | ||
131 | dev->input_id.version = 1; | ||
132 | dev->driver_name = MODULE_NAME; | ||
133 | dev->map_name = RC_MAP_MANTIS; | ||
134 | dev->dev.parent = &mantis->pdev->dev; | ||
135 | |||
136 | err = rc_register_device(dev); | ||
137 | if (err) { | ||
138 | dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); | ||
139 | goto out_dev; | ||
140 | } | ||
141 | |||
142 | mantis->rc = dev; | ||
143 | return 0; | ||
144 | |||
145 | out_dev: | ||
146 | rc_free_device(dev); | ||
147 | out_map: | ||
148 | rc_map_unregister(&ir_mantis_map); | ||
149 | out: | ||
150 | return err; | ||
151 | } | ||
152 | |||
153 | int mantis_exit(struct mantis_pci *mantis) | ||
154 | { | ||
155 | rc_unregister_device(mantis->rc); | ||
156 | rc_map_unregister(&ir_mantis_map); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c deleted file mode 100644 index 24fcdc63d6d5..000000000000 --- a/drivers/media/dvb/mantis/mantis_ioc.c +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/i2c.h> | ||
23 | |||
24 | #include <linux/signal.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <asm/io.h> | ||
28 | |||
29 | #include "dmxdev.h" | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_demux.h" | ||
32 | #include "dvb_frontend.h" | ||
33 | #include "dvb_net.h" | ||
34 | |||
35 | #include "mantis_common.h" | ||
36 | #include "mantis_reg.h" | ||
37 | #include "mantis_ioc.h" | ||
38 | |||
39 | static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length) | ||
40 | { | ||
41 | struct i2c_adapter *adapter = &mantis->adapter; | ||
42 | int err; | ||
43 | u8 buf = reg; | ||
44 | |||
45 | struct i2c_msg msg[] = { | ||
46 | { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 }, | ||
47 | { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length }, | ||
48 | }; | ||
49 | |||
50 | err = i2c_transfer(adapter, msg, 2); | ||
51 | if (err < 0) { | ||
52 | dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
53 | err, data[0], data[1]); | ||
54 | |||
55 | return err; | ||
56 | } | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | int mantis_get_mac(struct mantis_pci *mantis) | ||
61 | { | ||
62 | int err; | ||
63 | u8 mac_addr[6] = {0}; | ||
64 | |||
65 | err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6); | ||
66 | if (err < 0) { | ||
67 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err); | ||
68 | |||
69 | return err; | ||
70 | } | ||
71 | |||
72 | dprintk(MANTIS_ERROR, 0, " MAC Address=[%pM]\n", mac_addr); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | EXPORT_SYMBOL_GPL(mantis_get_mac); | ||
77 | |||
78 | /* Turn the given bit on or off. */ | ||
79 | void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
80 | { | ||
81 | u32 cur; | ||
82 | |||
83 | dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value); | ||
84 | cur = mmread(MANTIS_GPIF_ADDR); | ||
85 | if (value) | ||
86 | mantis->gpio_status = cur | (1 << bitpos); | ||
87 | else | ||
88 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
89 | |||
90 | dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status); | ||
91 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
92 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(mantis_gpio_set_bits); | ||
95 | |||
96 | int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl) | ||
97 | { | ||
98 | u32 reg; | ||
99 | |||
100 | reg = mmread(MANTIS_CONTROL); | ||
101 | switch (stream_ctl) { | ||
102 | case STREAM_TO_HIF: | ||
103 | dprintk(MANTIS_DEBUG, 1, "Set stream to HIF"); | ||
104 | reg &= 0xff - MANTIS_BYPASS; | ||
105 | mmwrite(reg, MANTIS_CONTROL); | ||
106 | reg |= MANTIS_BYPASS; | ||
107 | mmwrite(reg, MANTIS_CONTROL); | ||
108 | break; | ||
109 | |||
110 | case STREAM_TO_CAM: | ||
111 | dprintk(MANTIS_DEBUG, 1, "Set stream to CAM"); | ||
112 | reg |= MANTIS_BYPASS; | ||
113 | mmwrite(reg, MANTIS_CONTROL); | ||
114 | reg &= 0xff - MANTIS_BYPASS; | ||
115 | mmwrite(reg, MANTIS_CONTROL); | ||
116 | break; | ||
117 | default: | ||
118 | dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl); | ||
119 | return -1; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(mantis_stream_control); | ||
diff --git a/drivers/media/dvb/mantis/mantis_ioc.h b/drivers/media/dvb/mantis/mantis_ioc.h deleted file mode 100644 index d56e002b2955..000000000000 --- a/drivers/media/dvb/mantis/mantis_ioc.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_IOC_H | ||
22 | #define __MANTIS_IOC_H | ||
23 | |||
24 | #define GPIF_A00 0x00 | ||
25 | #define GPIF_A01 0x01 | ||
26 | #define GPIF_A02 0x02 | ||
27 | #define GPIF_A03 0x03 | ||
28 | #define GPIF_A04 0x04 | ||
29 | #define GPIF_A05 0x05 | ||
30 | #define GPIF_A06 0x06 | ||
31 | #define GPIF_A07 0x07 | ||
32 | #define GPIF_A08 0x08 | ||
33 | #define GPIF_A09 0x09 | ||
34 | #define GPIF_A10 0x0a | ||
35 | #define GPIF_A11 0x0b | ||
36 | |||
37 | #define GPIF_A12 0x0c | ||
38 | #define GPIF_A13 0x0d | ||
39 | #define GPIF_A14 0x0e | ||
40 | |||
41 | enum mantis_stream_control { | ||
42 | STREAM_TO_HIF = 0, | ||
43 | STREAM_TO_CAM | ||
44 | }; | ||
45 | |||
46 | extern int mantis_get_mac(struct mantis_pci *mantis); | ||
47 | extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value); | ||
48 | |||
49 | extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl); | ||
50 | |||
51 | #endif /* __MANTIS_IOC_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_link.h b/drivers/media/dvb/mantis/mantis_link.h deleted file mode 100644 index 2a814774a001..000000000000 --- a/drivers/media/dvb/mantis/mantis_link.h +++ /dev/null | |||
@@ -1,83 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_LINK_H | ||
22 | #define __MANTIS_LINK_H | ||
23 | |||
24 | #include <linux/mutex.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | #include "dvb_ca_en50221.h" | ||
27 | |||
28 | enum mantis_sbuf_status { | ||
29 | MANTIS_SBUF_DATA_AVAIL = 1, | ||
30 | MANTIS_SBUF_DATA_EMPTY = 2, | ||
31 | MANTIS_SBUF_DATA_OVFLW = 3 | ||
32 | }; | ||
33 | |||
34 | struct mantis_slot { | ||
35 | u32 timeout; | ||
36 | u32 slave_cfg; | ||
37 | u32 bar; | ||
38 | }; | ||
39 | |||
40 | /* Physical layer */ | ||
41 | enum mantis_slot_state { | ||
42 | MODULE_INSERTED = 3, | ||
43 | MODULE_XTRACTED = 4 | ||
44 | }; | ||
45 | |||
46 | struct mantis_ca { | ||
47 | struct mantis_slot slot[4]; | ||
48 | |||
49 | struct work_struct hif_evm_work; | ||
50 | |||
51 | u32 hif_event; | ||
52 | wait_queue_head_t hif_opdone_wq; | ||
53 | wait_queue_head_t hif_brrdyw_wq; | ||
54 | wait_queue_head_t hif_data_wq; | ||
55 | wait_queue_head_t hif_write_wq; /* HIF Write op */ | ||
56 | |||
57 | enum mantis_sbuf_status sbuf_status; | ||
58 | |||
59 | enum mantis_slot_state slot_state; | ||
60 | |||
61 | void *ca_priv; | ||
62 | |||
63 | struct dvb_ca_en50221 en50221; | ||
64 | struct mutex ca_lock; | ||
65 | }; | ||
66 | |||
67 | /* CA */ | ||
68 | extern void mantis_event_cam_plugin(struct mantis_ca *ca); | ||
69 | extern void mantis_event_cam_unplug(struct mantis_ca *ca); | ||
70 | extern int mantis_pcmcia_init(struct mantis_ca *ca); | ||
71 | extern void mantis_pcmcia_exit(struct mantis_ca *ca); | ||
72 | extern int mantis_evmgr_init(struct mantis_ca *ca); | ||
73 | extern void mantis_evmgr_exit(struct mantis_ca *ca); | ||
74 | |||
75 | /* HIF */ | ||
76 | extern int mantis_hif_init(struct mantis_ca *ca); | ||
77 | extern void mantis_hif_exit(struct mantis_ca *ca); | ||
78 | extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr); | ||
79 | extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data); | ||
80 | extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr); | ||
81 | extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data); | ||
82 | |||
83 | #endif /* __MANTIS_LINK_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c deleted file mode 100644 index 371558af2d96..000000000000 --- a/drivers/media/dvb/mantis/mantis_pci.c +++ /dev/null | |||
@@ -1,170 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/page.h> | ||
26 | #include <linux/kmod.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/pci.h> | ||
31 | |||
32 | #include <asm/irq.h> | ||
33 | #include <linux/signal.h> | ||
34 | #include <linux/sched.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | |||
37 | #include "dmxdev.h" | ||
38 | #include "dvbdev.h" | ||
39 | #include "dvb_demux.h" | ||
40 | #include "dvb_frontend.h" | ||
41 | #include "dvb_net.h" | ||
42 | |||
43 | #include "mantis_common.h" | ||
44 | #include "mantis_reg.h" | ||
45 | #include "mantis_pci.h" | ||
46 | |||
47 | #define DRIVER_NAME "Mantis Core" | ||
48 | |||
49 | int __devinit mantis_pci_init(struct mantis_pci *mantis) | ||
50 | { | ||
51 | u8 latency; | ||
52 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
53 | struct pci_dev *pdev = mantis->pdev; | ||
54 | int err, ret = 0; | ||
55 | |||
56 | dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
57 | config->model_name, | ||
58 | config->dev_type, | ||
59 | mantis->pdev->bus->number, | ||
60 | PCI_SLOT(mantis->pdev->devfn), | ||
61 | PCI_FUNC(mantis->pdev->devfn)); | ||
62 | |||
63 | err = pci_enable_device(pdev); | ||
64 | if (err != 0) { | ||
65 | ret = -ENODEV; | ||
66 | dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err); | ||
67 | goto fail0; | ||
68 | } | ||
69 | |||
70 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
71 | if (err != 0) { | ||
72 | dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err); | ||
73 | ret = -ENOMEM; | ||
74 | goto fail1; | ||
75 | } | ||
76 | |||
77 | pci_set_master(pdev); | ||
78 | |||
79 | if (!request_mem_region(pci_resource_start(pdev, 0), | ||
80 | pci_resource_len(pdev, 0), | ||
81 | DRIVER_NAME)) { | ||
82 | |||
83 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !"); | ||
84 | ret = -ENODEV; | ||
85 | goto fail1; | ||
86 | } | ||
87 | |||
88 | mantis->mmio = ioremap(pci_resource_start(pdev, 0), | ||
89 | pci_resource_len(pdev, 0)); | ||
90 | |||
91 | if (!mantis->mmio) { | ||
92 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !"); | ||
93 | ret = -ENODEV; | ||
94 | goto fail2; | ||
95 | } | ||
96 | |||
97 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); | ||
98 | mantis->latency = latency; | ||
99 | mantis->revision = pdev->revision; | ||
100 | |||
101 | dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
102 | mantis->revision, | ||
103 | mantis->pdev->subsystem_vendor, | ||
104 | mantis->pdev->subsystem_device); | ||
105 | |||
106 | dprintk(MANTIS_ERROR, 0, | ||
107 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
108 | mantis->pdev->irq, | ||
109 | mantis->latency, | ||
110 | mantis->mantis_addr, | ||
111 | mantis->mmio); | ||
112 | |||
113 | err = request_irq(pdev->irq, | ||
114 | config->irq_handler, | ||
115 | IRQF_SHARED, | ||
116 | DRIVER_NAME, | ||
117 | mantis); | ||
118 | |||
119 | if (err != 0) { | ||
120 | |||
121 | dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err); | ||
122 | ret = -ENODEV; | ||
123 | goto fail3; | ||
124 | } | ||
125 | |||
126 | pci_set_drvdata(pdev, mantis); | ||
127 | return ret; | ||
128 | |||
129 | /* Error conditions */ | ||
130 | fail3: | ||
131 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret); | ||
132 | if (mantis->mmio) | ||
133 | iounmap(mantis->mmio); | ||
134 | |||
135 | fail2: | ||
136 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret); | ||
137 | release_mem_region(pci_resource_start(pdev, 0), | ||
138 | pci_resource_len(pdev, 0)); | ||
139 | |||
140 | fail1: | ||
141 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret); | ||
142 | pci_disable_device(pdev); | ||
143 | |||
144 | fail0: | ||
145 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); | ||
146 | pci_set_drvdata(pdev, NULL); | ||
147 | return ret; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(mantis_pci_init); | ||
150 | |||
151 | void mantis_pci_exit(struct mantis_pci *mantis) | ||
152 | { | ||
153 | struct pci_dev *pdev = mantis->pdev; | ||
154 | |||
155 | dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio); | ||
156 | free_irq(pdev->irq, mantis); | ||
157 | if (mantis->mmio) { | ||
158 | iounmap(mantis->mmio); | ||
159 | release_mem_region(pci_resource_start(pdev, 0), | ||
160 | pci_resource_len(pdev, 0)); | ||
161 | } | ||
162 | |||
163 | pci_disable_device(pdev); | ||
164 | pci_set_drvdata(pdev, NULL); | ||
165 | } | ||
166 | EXPORT_SYMBOL_GPL(mantis_pci_exit); | ||
167 | |||
168 | MODULE_DESCRIPTION("Mantis PCI DTV bridge driver"); | ||
169 | MODULE_AUTHOR("Manu Abraham"); | ||
170 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/mantis_pci.h b/drivers/media/dvb/mantis/mantis_pci.h deleted file mode 100644 index 65f004519086..000000000000 --- a/drivers/media/dvb/mantis/mantis_pci.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_PCI_H | ||
22 | #define __MANTIS_PCI_H | ||
23 | |||
24 | extern int mantis_pci_init(struct mantis_pci *mantis); | ||
25 | extern void mantis_pci_exit(struct mantis_pci *mantis); | ||
26 | |||
27 | #endif /* __MANTIS_PCI_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/dvb/mantis/mantis_pcmcia.c deleted file mode 100644 index 2f188c089666..000000000000 --- a/drivers/media/dvb/mantis/mantis_pcmcia.c +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | /* | ||
39 | * If Slot state is already PLUG_IN event and we are called | ||
40 | * again, definitely it is jitter alone | ||
41 | */ | ||
42 | void mantis_event_cam_plugin(struct mantis_ca *ca) | ||
43 | { | ||
44 | struct mantis_pci *mantis = ca->ca_priv; | ||
45 | |||
46 | u32 gpif_irqcfg; | ||
47 | |||
48 | if (ca->slot_state == MODULE_XTRACTED) { | ||
49 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num); | ||
50 | udelay(50); | ||
51 | mmwrite(0xda000000, MANTIS_CARD_RESET); | ||
52 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
53 | gpif_irqcfg |= MANTIS_MASK_PLUGOUT; | ||
54 | gpif_irqcfg &= ~MANTIS_MASK_PLUGIN; | ||
55 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
56 | udelay(500); | ||
57 | ca->slot_state = MODULE_INSERTED; | ||
58 | } | ||
59 | udelay(100); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * If Slot state is already UN_PLUG event and we are called | ||
64 | * again, definitely it is jitter alone | ||
65 | */ | ||
66 | void mantis_event_cam_unplug(struct mantis_ca *ca) | ||
67 | { | ||
68 | struct mantis_pci *mantis = ca->ca_priv; | ||
69 | |||
70 | u32 gpif_irqcfg; | ||
71 | |||
72 | if (ca->slot_state == MODULE_INSERTED) { | ||
73 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num); | ||
74 | udelay(50); | ||
75 | mmwrite(0x00da0000, MANTIS_CARD_RESET); | ||
76 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
77 | gpif_irqcfg |= MANTIS_MASK_PLUGIN; | ||
78 | gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT; | ||
79 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
80 | udelay(500); | ||
81 | ca->slot_state = MODULE_XTRACTED; | ||
82 | } | ||
83 | udelay(100); | ||
84 | } | ||
85 | |||
86 | int mantis_pcmcia_init(struct mantis_ca *ca) | ||
87 | { | ||
88 | struct mantis_pci *mantis = ca->ca_priv; | ||
89 | |||
90 | u32 gpif_stat, card_stat; | ||
91 | |||
92 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
93 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
94 | card_stat = mmread(MANTIS_GPIF_IRQCFG); | ||
95 | |||
96 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
97 | dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num); | ||
98 | mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG); | ||
99 | ca->slot_state = MODULE_INSERTED; | ||
100 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
101 | 0, | ||
102 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
103 | } else { | ||
104 | dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num); | ||
105 | mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG); | ||
106 | ca->slot_state = MODULE_XTRACTED; | ||
107 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
108 | 0, | ||
109 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
110 | } | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | void mantis_pcmcia_exit(struct mantis_ca *ca) | ||
116 | { | ||
117 | struct mantis_pci *mantis = ca->ca_priv; | ||
118 | |||
119 | mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS); | ||
120 | mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
121 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_reg.h b/drivers/media/dvb/mantis/mantis_reg.h deleted file mode 100644 index 7761f9dc7fe0..000000000000 --- a/drivers/media/dvb/mantis/mantis_reg.h +++ /dev/null | |||
@@ -1,197 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_REG_H | ||
22 | #define __MANTIS_REG_H | ||
23 | |||
24 | /* Interrupts */ | ||
25 | #define MANTIS_INT_STAT 0x00 | ||
26 | #define MANTIS_INT_MASK 0x04 | ||
27 | |||
28 | #define MANTIS_INT_RISCSTAT (0x0f << 28) | ||
29 | #define MANTIS_INT_RISCEN (0x01 << 27) | ||
30 | #define MANTIS_INT_I2CRACK (0x01 << 26) | ||
31 | |||
32 | /* #define MANTIS_INT_GPIF (0xff << 12) */ | ||
33 | |||
34 | #define MANTIS_INT_PCMCIA7 (0x01 << 19) | ||
35 | #define MANTIS_INT_PCMCIA6 (0x01 << 18) | ||
36 | #define MANTIS_INT_PCMCIA5 (0x01 << 17) | ||
37 | #define MANTIS_INT_PCMCIA4 (0x01 << 16) | ||
38 | #define MANTIS_INT_PCMCIA3 (0x01 << 15) | ||
39 | #define MANTIS_INT_PCMCIA2 (0x01 << 14) | ||
40 | #define MANTIS_INT_PCMCIA1 (0x01 << 13) | ||
41 | #define MANTIS_INT_PCMCIA0 (0x01 << 12) | ||
42 | #define MANTIS_INT_IRQ1 (0x01 << 11) | ||
43 | #define MANTIS_INT_IRQ0 (0x01 << 10) | ||
44 | #define MANTIS_INT_OCERR (0x01 << 8) | ||
45 | #define MANTIS_INT_PABORT (0x01 << 7) | ||
46 | #define MANTIS_INT_RIPERR (0x01 << 6) | ||
47 | #define MANTIS_INT_PPERR (0x01 << 5) | ||
48 | #define MANTIS_INT_FTRGT (0x01 << 3) | ||
49 | #define MANTIS_INT_RISCI (0x01 << 1) | ||
50 | #define MANTIS_INT_I2CDONE (0x01 << 0) | ||
51 | |||
52 | /* DMA */ | ||
53 | #define MANTIS_DMA_CTL 0x08 | ||
54 | #define MANTIS_GPIF_RD (0xff << 24) | ||
55 | #define MANTIS_GPIF_WR (0xff << 16) | ||
56 | #define MANTIS_CPU_DO (0x01 << 10) | ||
57 | #define MANTIS_DRV_DO (0x01 << 9) | ||
58 | #define MANTIS_I2C_RD (0x01 << 7) | ||
59 | #define MANTIS_I2C_WR (0x01 << 6) | ||
60 | #define MANTIS_DCAP_MODE (0x01 << 5) | ||
61 | #define MANTIS_FIFO_TP_4 (0x00 << 3) | ||
62 | #define MANTIS_FIFO_TP_8 (0x01 << 3) | ||
63 | #define MANTIS_FIFO_TP_16 (0x02 << 3) | ||
64 | #define MANTIS_FIFO_EN (0x01 << 2) | ||
65 | #define MANTIS_DCAP_EN (0x01 << 1) | ||
66 | #define MANTIS_RISC_EN (0x01 << 0) | ||
67 | |||
68 | /* DEBUG */ | ||
69 | #define MANTIS_DEBUGREG 0x0c | ||
70 | #define MANTIS_DATINV (0x0e << 7) | ||
71 | #define MANTIS_TOP_DEBUGSEL (0x07 << 4) | ||
72 | #define MANTIS_PCMCIA_DEBUGSEL (0x0f << 0) | ||
73 | |||
74 | #define MANTIS_RISC_START 0x10 | ||
75 | #define MANTIS_RISC_PC 0x14 | ||
76 | |||
77 | /* I2C */ | ||
78 | #define MANTIS_I2CDATA_CTL 0x18 | ||
79 | #define MANTIS_I2C_RATE_1 (0x00 << 6) | ||
80 | #define MANTIS_I2C_RATE_2 (0x01 << 6) | ||
81 | #define MANTIS_I2C_RATE_3 (0x02 << 6) | ||
82 | #define MANTIS_I2C_RATE_4 (0x03 << 6) | ||
83 | #define MANTIS_I2C_STOP (0x01 << 5) | ||
84 | #define MANTIS_I2C_PGMODE (0x01 << 3) | ||
85 | |||
86 | /* DATA */ | ||
87 | #define MANTIS_CMD_DATA_R1 0x20 | ||
88 | #define MANTIS_CMD_DATA_3 (0xff << 24) | ||
89 | #define MANTIS_CMD_DATA_2 (0xff << 16) | ||
90 | #define MANTIS_CMD_DATA_1 (0xff << 8) | ||
91 | #define MANTIS_CMD_DATA_0 (0xff << 0) | ||
92 | |||
93 | #define MANTIS_CMD_DATA_R2 0x24 | ||
94 | #define MANTIS_CMD_DATA_7 (0xff << 24) | ||
95 | #define MANTIS_CMD_DATA_6 (0xff << 16) | ||
96 | #define MANTIS_CMD_DATA_5 (0xff << 8) | ||
97 | #define MANTIS_CMD_DATA_4 (0xff << 0) | ||
98 | |||
99 | #define MANTIS_CONTROL 0x28 | ||
100 | #define MANTIS_DET (0x01 << 7) | ||
101 | #define MANTIS_DAT_CF_EN (0x01 << 6) | ||
102 | #define MANTIS_ACS (0x03 << 4) | ||
103 | #define MANTIS_VCCEN (0x01 << 3) | ||
104 | #define MANTIS_BYPASS (0x01 << 2) | ||
105 | #define MANTIS_MRST (0x01 << 1) | ||
106 | #define MANTIS_CRST_INT (0x01 << 0) | ||
107 | |||
108 | #define MANTIS_GPIF_CFGSLA 0x84 | ||
109 | #define MANTIS_GPIF_WAITSMPL (0x07 << 28) | ||
110 | #define MANTIS_GPIF_BYTEADDRSUB (0x01 << 25) | ||
111 | #define MANTIS_GPIF_WAITPOL (0x01 << 24) | ||
112 | #define MANTIS_GPIF_NCDELAY (0x07 << 20) | ||
113 | #define MANTIS_GPIF_RW2CSDELAY (0x07 << 16) | ||
114 | #define MANTIS_GPIF_SLFTIMEDMODE (0x01 << 15) | ||
115 | #define MANTIS_GPIF_SLFTIMEDDELY (0x7f << 8) | ||
116 | #define MANTIS_GPIF_DEVTYPE (0x07 << 4) | ||
117 | #define MANTIS_GPIF_BIGENDIAN (0x01 << 3) | ||
118 | #define MANTIS_GPIF_FETCHCMD (0x03 << 1) | ||
119 | #define MANTIS_GPIF_HWORDDEV (0x01 << 0) | ||
120 | |||
121 | #define MANTIS_GPIF_WSTOPER 0x90 | ||
122 | #define MANTIS_GPIF_WSTOPERWREN3 (0x01 << 31) | ||
123 | #define MANTIS_GPIF_PARBOOTN (0x01 << 29) | ||
124 | #define MANTIS_GPIF_WSTOPERSLID3 (0x1f << 24) | ||
125 | #define MANTIS_GPIF_WSTOPERWREN2 (0x01 << 23) | ||
126 | #define MANTIS_GPIF_WSTOPERSLID2 (0x1f << 16) | ||
127 | #define MANTIS_GPIF_WSTOPERWREN1 (0x01 << 15) | ||
128 | #define MANTIS_GPIF_WSTOPERSLID1 (0x1f << 8) | ||
129 | #define MANTIS_GPIF_WSTOPERWREN0 (0x01 << 7) | ||
130 | #define MANTIS_GPIF_WSTOPERSLID0 (0x1f << 0) | ||
131 | |||
132 | #define MANTIS_GPIF_CS2RW 0x94 | ||
133 | #define MANTIS_GPIF_CS2RWWREN3 (0x01 << 31) | ||
134 | #define MANTIS_GPIF_CS2RWDELY3 (0x3f << 24) | ||
135 | #define MANTIS_GPIF_CS2RWWREN2 (0x01 << 23) | ||
136 | #define MANTIS_GPIF_CS2RWDELY2 (0x3f << 16) | ||
137 | #define MANTIS_GPIF_CS2RWWREN1 (0x01 << 15) | ||
138 | #define MANTIS_GPIF_CS2RWDELY1 (0x3f << 8) | ||
139 | #define MANTIS_GPIF_CS2RWWREN0 (0x01 << 7) | ||
140 | #define MANTIS_GPIF_CS2RWDELY0 (0x3f << 0) | ||
141 | |||
142 | #define MANTIS_GPIF_IRQCFG 0x98 | ||
143 | #define MANTIS_GPIF_IRQPOL (0x01 << 8) | ||
144 | #define MANTIS_MASK_WRACK (0x01 << 7) | ||
145 | #define MANTIS_MASK_BRRDY (0x01 << 6) | ||
146 | #define MANTIS_MASK_OVFLW (0x01 << 5) | ||
147 | #define MANTIS_MASK_OTHERR (0x01 << 4) | ||
148 | #define MANTIS_MASK_WSTO (0x01 << 3) | ||
149 | #define MANTIS_MASK_EXTIRQ (0x01 << 2) | ||
150 | #define MANTIS_MASK_PLUGIN (0x01 << 1) | ||
151 | #define MANTIS_MASK_PLUGOUT (0x01 << 0) | ||
152 | |||
153 | #define MANTIS_GPIF_STATUS 0x9c | ||
154 | #define MANTIS_SBUF_KILLOP (0x01 << 15) | ||
155 | #define MANTIS_SBUF_OPDONE (0x01 << 14) | ||
156 | #define MANTIS_SBUF_EMPTY (0x01 << 13) | ||
157 | #define MANTIS_GPIF_DETSTAT (0x01 << 9) | ||
158 | #define MANTIS_GPIF_INTSTAT (0x01 << 8) | ||
159 | #define MANTIS_GPIF_WRACK (0x01 << 7) | ||
160 | #define MANTIS_GPIF_BRRDY (0x01 << 6) | ||
161 | #define MANTIS_SBUF_OVFLW (0x01 << 5) | ||
162 | #define MANTIS_GPIF_OTHERR (0x01 << 4) | ||
163 | #define MANTIS_SBUF_WSTO (0x01 << 3) | ||
164 | #define MANTIS_GPIF_EXTIRQ (0x01 << 2) | ||
165 | #define MANTIS_CARD_PLUGIN (0x01 << 1) | ||
166 | #define MANTIS_CARD_PLUGOUT (0x01 << 0) | ||
167 | |||
168 | #define MANTIS_GPIF_BRADDR 0xa0 | ||
169 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
170 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
171 | #define MANTIS_GPIF_BR_ADDR (0xfffffff << 0) | ||
172 | |||
173 | #define MANTIS_GPIF_BRBYTES 0xa4 | ||
174 | #define MANTIS_GPIF_BRCNT (0xfff << 0) | ||
175 | |||
176 | #define MANTIS_PCMCIA_RESET 0xa8 | ||
177 | #define MANTIS_PCMCIA_RSTVAL (0xff << 0) | ||
178 | |||
179 | #define MANTIS_CARD_RESET 0xac | ||
180 | |||
181 | #define MANTIS_GPIF_ADDR 0xb0 | ||
182 | #define MANTIS_GPIF_HIFRDWRN (0x01 << 31) | ||
183 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
184 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
185 | #define MANTIS_GPIF_HIFADDR (0xfffffff << 0) | ||
186 | |||
187 | #define MANTIS_GPIF_DOUT 0xb4 | ||
188 | #define MANTIS_GPIF_HIFDOUT (0xfffffff << 0) | ||
189 | |||
190 | #define MANTIS_GPIF_DIN 0xb8 | ||
191 | #define MANTIS_GPIF_HIFDIN (0xfffffff << 0) | ||
192 | |||
193 | #define MANTIS_GPIF_SPARE 0xbc | ||
194 | #define MANTIS_GPIF_LOGICRD (0xffff << 16) | ||
195 | #define MANTIS_GPIF_LOGICRW (0xffff << 0) | ||
196 | |||
197 | #endif /* __MANTIS_REG_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c deleted file mode 100644 index 18340dafa426..000000000000 --- a/drivers/media/dvb/mantis/mantis_uart.c +++ /dev/null | |||
@@ -1,188 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | #include <linux/signal.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | |||
29 | #include "dmxdev.h" | ||
30 | #include "dvbdev.h" | ||
31 | #include "dvb_demux.h" | ||
32 | #include "dvb_frontend.h" | ||
33 | #include "dvb_net.h" | ||
34 | |||
35 | #include "mantis_common.h" | ||
36 | #include "mantis_reg.h" | ||
37 | #include "mantis_uart.h" | ||
38 | |||
39 | struct mantis_uart_params { | ||
40 | enum mantis_baud baud_rate; | ||
41 | enum mantis_parity parity; | ||
42 | }; | ||
43 | |||
44 | static struct { | ||
45 | char string[7]; | ||
46 | } rates[5] = { | ||
47 | { "9600" }, | ||
48 | { "19200" }, | ||
49 | { "38400" }, | ||
50 | { "57600" }, | ||
51 | { "115200" } | ||
52 | }; | ||
53 | |||
54 | static struct { | ||
55 | char string[5]; | ||
56 | } parity[3] = { | ||
57 | { "NONE" }, | ||
58 | { "ODD" }, | ||
59 | { "EVEN" } | ||
60 | }; | ||
61 | |||
62 | #define UART_MAX_BUF 16 | ||
63 | |||
64 | int mantis_uart_read(struct mantis_pci *mantis, u8 *data) | ||
65 | { | ||
66 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
67 | u32 stat = 0, i; | ||
68 | |||
69 | /* get data */ | ||
70 | for (i = 0; i < (config->bytes + 1); i++) { | ||
71 | |||
72 | stat = mmread(MANTIS_UART_STAT); | ||
73 | |||
74 | if (stat & MANTIS_UART_RXFIFO_FULL) { | ||
75 | dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); | ||
76 | } | ||
77 | data[i] = mmread(MANTIS_UART_RXD) & 0x3f; | ||
78 | |||
79 | dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f); | ||
80 | |||
81 | if (data[i] & (1 << 7)) { | ||
82 | dprintk(MANTIS_ERROR, 1, "UART framing error"); | ||
83 | return -EINVAL; | ||
84 | } | ||
85 | if (data[i] & (1 << 6)) { | ||
86 | dprintk(MANTIS_ERROR, 1, "UART parity error"); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static void mantis_uart_work(struct work_struct *work) | ||
95 | { | ||
96 | struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); | ||
97 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
98 | u8 buf[16]; | ||
99 | int i; | ||
100 | |||
101 | mantis_uart_read(mantis, buf); | ||
102 | |||
103 | for (i = 0; i < (config->bytes + 1); i++) | ||
104 | dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); | ||
105 | |||
106 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
107 | } | ||
108 | |||
109 | static int mantis_uart_setup(struct mantis_pci *mantis, | ||
110 | struct mantis_uart_params *params) | ||
111 | { | ||
112 | u32 reg; | ||
113 | |||
114 | mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL); | ||
115 | |||
116 | reg = mmread(MANTIS_UART_BAUD); | ||
117 | |||
118 | switch (params->baud_rate) { | ||
119 | case MANTIS_BAUD_9600: | ||
120 | reg |= 0xd8; | ||
121 | break; | ||
122 | case MANTIS_BAUD_19200: | ||
123 | reg |= 0x6c; | ||
124 | break; | ||
125 | case MANTIS_BAUD_38400: | ||
126 | reg |= 0x36; | ||
127 | break; | ||
128 | case MANTIS_BAUD_57600: | ||
129 | reg |= 0x23; | ||
130 | break; | ||
131 | case MANTIS_BAUD_115200: | ||
132 | reg |= 0x11; | ||
133 | break; | ||
134 | default: | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | |||
138 | mmwrite(reg, MANTIS_UART_BAUD); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | int mantis_uart_init(struct mantis_pci *mantis) | ||
144 | { | ||
145 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
146 | struct mantis_uart_params params; | ||
147 | |||
148 | /* default parity: */ | ||
149 | params.baud_rate = config->baud_rate; | ||
150 | params.parity = config->parity; | ||
151 | dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s", | ||
152 | rates[params.baud_rate].string, | ||
153 | parity[params.parity].string); | ||
154 | |||
155 | init_waitqueue_head(&mantis->uart_wq); | ||
156 | spin_lock_init(&mantis->uart_lock); | ||
157 | |||
158 | INIT_WORK(&mantis->uart_work, mantis_uart_work); | ||
159 | |||
160 | /* disable interrupt */ | ||
161 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
162 | |||
163 | mantis_uart_setup(mantis, ¶ms); | ||
164 | |||
165 | /* default 1 byte */ | ||
166 | mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD); | ||
167 | |||
168 | /* flush buffer */ | ||
169 | mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); | ||
170 | |||
171 | /* enable interrupt */ | ||
172 | mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK); | ||
173 | mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); | ||
174 | |||
175 | schedule_work(&mantis->uart_work); | ||
176 | dprintk(MANTIS_DEBUG, 1, "UART successfully initialized"); | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(mantis_uart_init); | ||
181 | |||
182 | void mantis_uart_exit(struct mantis_pci *mantis) | ||
183 | { | ||
184 | /* disable interrupt */ | ||
185 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
186 | flush_work_sync(&mantis->uart_work); | ||
187 | } | ||
188 | EXPORT_SYMBOL_GPL(mantis_uart_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_uart.h b/drivers/media/dvb/mantis/mantis_uart.h deleted file mode 100644 index ffb62a0a5a13..000000000000 --- a/drivers/media/dvb/mantis/mantis_uart.h +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_UART_H | ||
22 | #define __MANTIS_UART_H | ||
23 | |||
24 | #define MANTIS_UART_CTL 0xe0 | ||
25 | #define MANTIS_UART_RXINT (1 << 4) | ||
26 | #define MANTIS_UART_RXFLUSH (1 << 2) | ||
27 | |||
28 | #define MANTIS_UART_RXD 0xe8 | ||
29 | #define MANTIS_UART_BAUD 0xec | ||
30 | |||
31 | #define MANTIS_UART_STAT 0xf0 | ||
32 | #define MANTIS_UART_RXFIFO_DATA (1 << 7) | ||
33 | #define MANTIS_UART_RXFIFO_EMPTY (1 << 6) | ||
34 | #define MANTIS_UART_RXFIFO_FULL (1 << 3) | ||
35 | #define MANTIS_UART_FRAME_ERR (1 << 2) | ||
36 | #define MANTIS_UART_PARITY_ERR (1 << 1) | ||
37 | #define MANTIS_UART_RXTHRESH_INT (1 << 0) | ||
38 | |||
39 | enum mantis_baud { | ||
40 | MANTIS_BAUD_9600 = 0, | ||
41 | MANTIS_BAUD_19200, | ||
42 | MANTIS_BAUD_38400, | ||
43 | MANTIS_BAUD_57600, | ||
44 | MANTIS_BAUD_115200 | ||
45 | }; | ||
46 | |||
47 | enum mantis_parity { | ||
48 | MANTIS_PARITY_NONE = 0, | ||
49 | MANTIS_PARITY_EVEN, | ||
50 | MANTIS_PARITY_ODD, | ||
51 | }; | ||
52 | |||
53 | struct mantis_pci; | ||
54 | |||
55 | extern int mantis_uart_init(struct mantis_pci *mantis); | ||
56 | extern void mantis_uart_exit(struct mantis_pci *mantis); | ||
57 | |||
58 | #endif /* __MANTIS_UART_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c deleted file mode 100644 index ad013e93ed11..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp1033.c +++ /dev/null | |||
@@ -1,212 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-1033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "stv0299.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp1033.h" | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | u8 lgtdqcs001f_inittab[] = { | ||
39 | 0x01, 0x15, | ||
40 | 0x02, 0x30, | ||
41 | 0x03, 0x00, | ||
42 | 0x04, 0x2a, | ||
43 | 0x05, 0x85, | ||
44 | 0x06, 0x02, | ||
45 | 0x07, 0x00, | ||
46 | 0x08, 0x00, | ||
47 | 0x0c, 0x01, | ||
48 | 0x0d, 0x81, | ||
49 | 0x0e, 0x44, | ||
50 | 0x0f, 0x94, | ||
51 | 0x10, 0x3c, | ||
52 | 0x11, 0x84, | ||
53 | 0x12, 0xb9, | ||
54 | 0x13, 0xb5, | ||
55 | 0x14, 0x4f, | ||
56 | 0x15, 0xc9, | ||
57 | 0x16, 0x80, | ||
58 | 0x17, 0x36, | ||
59 | 0x18, 0xfb, | ||
60 | 0x19, 0xcf, | ||
61 | 0x1a, 0xbc, | ||
62 | 0x1c, 0x2b, | ||
63 | 0x1d, 0x27, | ||
64 | 0x1e, 0x00, | ||
65 | 0x1f, 0x0b, | ||
66 | 0x20, 0xa1, | ||
67 | 0x21, 0x60, | ||
68 | 0x22, 0x00, | ||
69 | 0x23, 0x00, | ||
70 | 0x28, 0x00, | ||
71 | 0x29, 0x28, | ||
72 | 0x2a, 0x14, | ||
73 | 0x2b, 0x0f, | ||
74 | 0x2c, 0x09, | ||
75 | 0x2d, 0x05, | ||
76 | 0x31, 0x1f, | ||
77 | 0x32, 0x19, | ||
78 | 0x33, 0xfc, | ||
79 | 0x34, 0x13, | ||
80 | 0xff, 0xff, | ||
81 | }; | ||
82 | |||
83 | #define MANTIS_MODEL_NAME "VP-1033" | ||
84 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
85 | |||
86 | int lgtdqcs001f_tuner_set(struct dvb_frontend *fe) | ||
87 | { | ||
88 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
89 | struct mantis_pci *mantis = fe->dvb->priv; | ||
90 | struct i2c_adapter *adapter = &mantis->adapter; | ||
91 | |||
92 | u8 buf[4]; | ||
93 | u32 div; | ||
94 | |||
95 | |||
96 | struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
97 | |||
98 | div = p->frequency / 250; | ||
99 | |||
100 | buf[0] = (div >> 8) & 0x7f; | ||
101 | buf[1] = div & 0xff; | ||
102 | buf[2] = 0x83; | ||
103 | buf[3] = 0xc0; | ||
104 | |||
105 | if (p->frequency < 1531000) | ||
106 | buf[3] |= 0x04; | ||
107 | else | ||
108 | buf[3] &= ~0x04; | ||
109 | if (i2c_transfer(adapter, &msg, 1) < 0) { | ||
110 | dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed"); | ||
111 | return -EIO; | ||
112 | } | ||
113 | msleep_interruptible(100); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe, | ||
119 | u32 srate, u32 ratio) | ||
120 | { | ||
121 | u8 aclk = 0; | ||
122 | u8 bclk = 0; | ||
123 | |||
124 | if (srate < 1500000) { | ||
125 | aclk = 0xb7; | ||
126 | bclk = 0x47; | ||
127 | } else if (srate < 3000000) { | ||
128 | aclk = 0xb7; | ||
129 | bclk = 0x4b; | ||
130 | } else if (srate < 7000000) { | ||
131 | aclk = 0xb7; | ||
132 | bclk = 0x4f; | ||
133 | } else if (srate < 14000000) { | ||
134 | aclk = 0xb7; | ||
135 | bclk = 0x53; | ||
136 | } else if (srate < 30000000) { | ||
137 | aclk = 0xb6; | ||
138 | bclk = 0x53; | ||
139 | } else if (srate < 45000000) { | ||
140 | aclk = 0xb4; | ||
141 | bclk = 0x51; | ||
142 | } | ||
143 | stv0299_writereg(fe, 0x13, aclk); | ||
144 | stv0299_writereg(fe, 0x14, bclk); | ||
145 | |||
146 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
147 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
148 | stv0299_writereg(fe, 0x21, ratio & 0xf0); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | struct stv0299_config lgtdqcs001f_config = { | ||
154 | .demod_address = 0x68, | ||
155 | .inittab = lgtdqcs001f_inittab, | ||
156 | .mclk = 88000000UL, | ||
157 | .invert = 0, | ||
158 | .skip_reinit = 0, | ||
159 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
160 | .min_delay_ms = 100, | ||
161 | .set_symbol_rate = lgtdqcs001f_set_symbol_rate, | ||
162 | }; | ||
163 | |||
164 | static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
165 | { | ||
166 | struct i2c_adapter *adapter = &mantis->adapter; | ||
167 | |||
168 | int err = 0; | ||
169 | |||
170 | err = mantis_frontend_power(mantis, POWER_ON); | ||
171 | if (err == 0) { | ||
172 | mantis_frontend_soft_reset(mantis); | ||
173 | msleep(250); | ||
174 | |||
175 | dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)"); | ||
176 | fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter); | ||
177 | |||
178 | if (fe) { | ||
179 | fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set; | ||
180 | dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x", | ||
181 | lgtdqcs001f_config.demod_address); | ||
182 | |||
183 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success"); | ||
184 | } else { | ||
185 | return -1; | ||
186 | } | ||
187 | } else { | ||
188 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
189 | adapter->name, | ||
190 | err); | ||
191 | |||
192 | return -EIO; | ||
193 | } | ||
194 | mantis->fe = fe; | ||
195 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | struct mantis_hwconfig vp1033_config = { | ||
201 | .model_name = MANTIS_MODEL_NAME, | ||
202 | .dev_type = MANTIS_DEV_TYPE, | ||
203 | .ts_size = MANTIS_TS_204, | ||
204 | |||
205 | .baud_rate = MANTIS_BAUD_9600, | ||
206 | .parity = MANTIS_PARITY_NONE, | ||
207 | .bytes = 0, | ||
208 | |||
209 | .frontend_init = vp1033_frontend_init, | ||
210 | .power = GPIF_A12, | ||
211 | .reset = GPIF_A13, | ||
212 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.h b/drivers/media/dvb/mantis/mantis_vp1033.h deleted file mode 100644 index 7daaa1bf127d..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp1033.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-1033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP1033_H | ||
22 | #define __MANTIS_VP1033_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_1033_DVB_S 0x0016 | ||
27 | |||
28 | extern struct mantis_hwconfig vp1033_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP1033_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c deleted file mode 100644 index 430ae84ce528..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp1034.c +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-1034 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <asm/io.h> | ||
25 | |||
26 | #include "dmxdev.h" | ||
27 | #include "dvbdev.h" | ||
28 | #include "dvb_demux.h" | ||
29 | #include "dvb_frontend.h" | ||
30 | #include "dvb_net.h" | ||
31 | |||
32 | #include "mb86a16.h" | ||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_ioc.h" | ||
35 | #include "mantis_dvb.h" | ||
36 | #include "mantis_vp1034.h" | ||
37 | #include "mantis_reg.h" | ||
38 | |||
39 | struct mb86a16_config vp1034_mb86a16_config = { | ||
40 | .demod_address = 0x08, | ||
41 | .set_voltage = vp1034_set_voltage, | ||
42 | }; | ||
43 | |||
44 | #define MANTIS_MODEL_NAME "VP-1034" | ||
45 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
46 | |||
47 | int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
48 | { | ||
49 | struct mantis_pci *mantis = fe->dvb->priv; | ||
50 | |||
51 | switch (voltage) { | ||
52 | case SEC_VOLTAGE_13: | ||
53 | dprintk(MANTIS_ERROR, 1, "Polarization=[13V]"); | ||
54 | mantis_gpio_set_bits(mantis, 13, 1); | ||
55 | mantis_gpio_set_bits(mantis, 14, 0); | ||
56 | break; | ||
57 | case SEC_VOLTAGE_18: | ||
58 | dprintk(MANTIS_ERROR, 1, "Polarization=[18V]"); | ||
59 | mantis_gpio_set_bits(mantis, 13, 1); | ||
60 | mantis_gpio_set_bits(mantis, 14, 1); | ||
61 | break; | ||
62 | case SEC_VOLTAGE_OFF: | ||
63 | dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN"); | ||
64 | break; | ||
65 | default: | ||
66 | dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
75 | { | ||
76 | struct i2c_adapter *adapter = &mantis->adapter; | ||
77 | |||
78 | int err = 0; | ||
79 | |||
80 | err = mantis_frontend_power(mantis, POWER_ON); | ||
81 | if (err == 0) { | ||
82 | mantis_frontend_soft_reset(mantis); | ||
83 | msleep(250); | ||
84 | |||
85 | dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); | ||
86 | fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter); | ||
87 | if (fe) { | ||
88 | dprintk(MANTIS_ERROR, 1, | ||
89 | "found MB86A16 DVB-S/DSS frontend @0x%02x", | ||
90 | vp1034_mb86a16_config.demod_address); | ||
91 | |||
92 | } else { | ||
93 | return -1; | ||
94 | } | ||
95 | } else { | ||
96 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
97 | adapter->name, | ||
98 | err); | ||
99 | |||
100 | return -EIO; | ||
101 | } | ||
102 | mantis->fe = fe; | ||
103 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | struct mantis_hwconfig vp1034_config = { | ||
109 | .model_name = MANTIS_MODEL_NAME, | ||
110 | .dev_type = MANTIS_DEV_TYPE, | ||
111 | .ts_size = MANTIS_TS_204, | ||
112 | |||
113 | .baud_rate = MANTIS_BAUD_9600, | ||
114 | .parity = MANTIS_PARITY_NONE, | ||
115 | .bytes = 0, | ||
116 | |||
117 | .frontend_init = vp1034_frontend_init, | ||
118 | .power = GPIF_A12, | ||
119 | .reset = GPIF_A13, | ||
120 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.h b/drivers/media/dvb/mantis/mantis_vp1034.h deleted file mode 100644 index 323f38ef8e3d..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp1034.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-1034 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP1034_H | ||
22 | #define __MANTIS_VP1034_H | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | #include "mantis_common.h" | ||
26 | |||
27 | |||
28 | #define MANTIS_VP_1034_DVB_S 0x0014 | ||
29 | |||
30 | extern struct mantis_hwconfig vp1034_config; | ||
31 | extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||
32 | |||
33 | #endif /* __MANTIS_VP1034_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c deleted file mode 100644 index 07aa887a4b4a..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp1041.c +++ /dev/null | |||
@@ -1,357 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-1041 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "mantis_common.h" | ||
32 | #include "mantis_ioc.h" | ||
33 | #include "mantis_dvb.h" | ||
34 | #include "mantis_vp1041.h" | ||
35 | #include "stb0899_reg.h" | ||
36 | #include "stb0899_drv.h" | ||
37 | #include "stb0899_cfg.h" | ||
38 | #include "stb6100_cfg.h" | ||
39 | #include "stb6100.h" | ||
40 | #include "lnbp21.h" | ||
41 | |||
42 | #define MANTIS_MODEL_NAME "VP-1041" | ||
43 | #define MANTIS_DEV_TYPE "DSS/DVB-S/DVB-S2" | ||
44 | |||
45 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { | ||
46 | |||
47 | /* 0x0000000b, *//* SYSREG */ | ||
48 | { STB0899_DEV_ID , 0x30 }, | ||
49 | { STB0899_DISCNTRL1 , 0x32 }, | ||
50 | { STB0899_DISCNTRL2 , 0x80 }, | ||
51 | { STB0899_DISRX_ST0 , 0x04 }, | ||
52 | { STB0899_DISRX_ST1 , 0x00 }, | ||
53 | { STB0899_DISPARITY , 0x00 }, | ||
54 | { STB0899_DISSTATUS , 0x20 }, | ||
55 | { STB0899_DISF22 , 0x99 }, | ||
56 | { STB0899_DISF22RX , 0xa8 }, | ||
57 | /* SYSREG ? */ | ||
58 | { STB0899_ACRPRESC , 0x11 }, | ||
59 | { STB0899_ACRDIV1 , 0x0a }, | ||
60 | { STB0899_ACRDIV2 , 0x05 }, | ||
61 | { STB0899_DACR1 , 0x00 }, | ||
62 | { STB0899_DACR2 , 0x00 }, | ||
63 | { STB0899_OUTCFG , 0x00 }, | ||
64 | { STB0899_MODECFG , 0x00 }, | ||
65 | { STB0899_IRQSTATUS_3 , 0xfe }, | ||
66 | { STB0899_IRQSTATUS_2 , 0x03 }, | ||
67 | { STB0899_IRQSTATUS_1 , 0x7c }, | ||
68 | { STB0899_IRQSTATUS_0 , 0xf4 }, | ||
69 | { STB0899_IRQMSK_3 , 0xf3 }, | ||
70 | { STB0899_IRQMSK_2 , 0xfc }, | ||
71 | { STB0899_IRQMSK_1 , 0xff }, | ||
72 | { STB0899_IRQMSK_0 , 0xff }, | ||
73 | { STB0899_IRQCFG , 0x00 }, | ||
74 | { STB0899_I2CCFG , 0x88 }, | ||
75 | { STB0899_I2CRPT , 0x58 }, | ||
76 | { STB0899_IOPVALUE5 , 0x00 }, | ||
77 | { STB0899_IOPVALUE4 , 0x33 }, | ||
78 | { STB0899_IOPVALUE3 , 0x6d }, | ||
79 | { STB0899_IOPVALUE2 , 0x90 }, | ||
80 | { STB0899_IOPVALUE1 , 0x60 }, | ||
81 | { STB0899_IOPVALUE0 , 0x00 }, | ||
82 | { STB0899_GPIO00CFG , 0x82 }, | ||
83 | { STB0899_GPIO01CFG , 0x82 }, | ||
84 | { STB0899_GPIO02CFG , 0x82 }, | ||
85 | { STB0899_GPIO03CFG , 0x82 }, | ||
86 | { STB0899_GPIO04CFG , 0x82 }, | ||
87 | { STB0899_GPIO05CFG , 0x82 }, | ||
88 | { STB0899_GPIO06CFG , 0x82 }, | ||
89 | { STB0899_GPIO07CFG , 0x82 }, | ||
90 | { STB0899_GPIO08CFG , 0x82 }, | ||
91 | { STB0899_GPIO09CFG , 0x82 }, | ||
92 | { STB0899_GPIO10CFG , 0x82 }, | ||
93 | { STB0899_GPIO11CFG , 0x82 }, | ||
94 | { STB0899_GPIO12CFG , 0x82 }, | ||
95 | { STB0899_GPIO13CFG , 0x82 }, | ||
96 | { STB0899_GPIO14CFG , 0x82 }, | ||
97 | { STB0899_GPIO15CFG , 0x82 }, | ||
98 | { STB0899_GPIO16CFG , 0x82 }, | ||
99 | { STB0899_GPIO17CFG , 0x82 }, | ||
100 | { STB0899_GPIO18CFG , 0x82 }, | ||
101 | { STB0899_GPIO19CFG , 0x82 }, | ||
102 | { STB0899_GPIO20CFG , 0x82 }, | ||
103 | { STB0899_SDATCFG , 0xb8 }, | ||
104 | { STB0899_SCLTCFG , 0xba }, | ||
105 | { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ | ||
106 | { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ | ||
107 | { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ | ||
108 | { STB0899_DIRCLKCFG , 0x82 }, | ||
109 | { STB0899_CLKOUT27CFG , 0x7e }, | ||
110 | { STB0899_STDBYCFG , 0x82 }, | ||
111 | { STB0899_CS0CFG , 0x82 }, | ||
112 | { STB0899_CS1CFG , 0x82 }, | ||
113 | { STB0899_DISEQCOCFG , 0x20 }, | ||
114 | { STB0899_GPIO32CFG , 0x82 }, | ||
115 | { STB0899_GPIO33CFG , 0x82 }, | ||
116 | { STB0899_GPIO34CFG , 0x82 }, | ||
117 | { STB0899_GPIO35CFG , 0x82 }, | ||
118 | { STB0899_GPIO36CFG , 0x82 }, | ||
119 | { STB0899_GPIO37CFG , 0x82 }, | ||
120 | { STB0899_GPIO38CFG , 0x82 }, | ||
121 | { STB0899_GPIO39CFG , 0x82 }, | ||
122 | { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | ||
123 | { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | ||
124 | { STB0899_FILTCTRL , 0x00 }, | ||
125 | { STB0899_SYSCTRL , 0x01 }, | ||
126 | { STB0899_STOPCLK1 , 0x20 }, | ||
127 | { STB0899_STOPCLK2 , 0x00 }, | ||
128 | { STB0899_INTBUFSTATUS , 0x00 }, | ||
129 | { STB0899_INTBUFCTRL , 0x0a }, | ||
130 | { 0xffff , 0xff }, | ||
131 | }; | ||
132 | |||
133 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { | ||
134 | { STB0899_DEMOD , 0x00 }, | ||
135 | { STB0899_RCOMPC , 0xc9 }, | ||
136 | { STB0899_AGC1CN , 0x01 }, | ||
137 | { STB0899_AGC1REF , 0x10 }, | ||
138 | { STB0899_RTC , 0x23 }, | ||
139 | { STB0899_TMGCFG , 0x4e }, | ||
140 | { STB0899_AGC2REF , 0x34 }, | ||
141 | { STB0899_TLSR , 0x84 }, | ||
142 | { STB0899_CFD , 0xf7 }, | ||
143 | { STB0899_ACLC , 0x87 }, | ||
144 | { STB0899_BCLC , 0x94 }, | ||
145 | { STB0899_EQON , 0x41 }, | ||
146 | { STB0899_LDT , 0xf1 }, | ||
147 | { STB0899_LDT2 , 0xe3 }, | ||
148 | { STB0899_EQUALREF , 0xb4 }, | ||
149 | { STB0899_TMGRAMP , 0x10 }, | ||
150 | { STB0899_TMGTHD , 0x30 }, | ||
151 | { STB0899_IDCCOMP , 0xfd }, | ||
152 | { STB0899_QDCCOMP , 0xff }, | ||
153 | { STB0899_POWERI , 0x0c }, | ||
154 | { STB0899_POWERQ , 0x0f }, | ||
155 | { STB0899_RCOMP , 0x6c }, | ||
156 | { STB0899_AGCIQIN , 0x80 }, | ||
157 | { STB0899_AGC2I1 , 0x06 }, | ||
158 | { STB0899_AGC2I2 , 0x00 }, | ||
159 | { STB0899_TLIR , 0x30 }, | ||
160 | { STB0899_RTF , 0x7f }, | ||
161 | { STB0899_DSTATUS , 0x00 }, | ||
162 | { STB0899_LDI , 0xbc }, | ||
163 | { STB0899_CFRM , 0xea }, | ||
164 | { STB0899_CFRL , 0x31 }, | ||
165 | { STB0899_NIRM , 0x2b }, | ||
166 | { STB0899_NIRL , 0x80 }, | ||
167 | { STB0899_ISYMB , 0x1d }, | ||
168 | { STB0899_QSYMB , 0xa6 }, | ||
169 | { STB0899_SFRH , 0x2f }, | ||
170 | { STB0899_SFRM , 0x68 }, | ||
171 | { STB0899_SFRL , 0x40 }, | ||
172 | { STB0899_SFRUPH , 0x2f }, | ||
173 | { STB0899_SFRUPM , 0x68 }, | ||
174 | { STB0899_SFRUPL , 0x40 }, | ||
175 | { STB0899_EQUAI1 , 0x02 }, | ||
176 | { STB0899_EQUAQ1 , 0xff }, | ||
177 | { STB0899_EQUAI2 , 0x04 }, | ||
178 | { STB0899_EQUAQ2 , 0x05 }, | ||
179 | { STB0899_EQUAI3 , 0x02 }, | ||
180 | { STB0899_EQUAQ3 , 0xfd }, | ||
181 | { STB0899_EQUAI4 , 0x03 }, | ||
182 | { STB0899_EQUAQ4 , 0x07 }, | ||
183 | { STB0899_EQUAI5 , 0x08 }, | ||
184 | { STB0899_EQUAQ5 , 0xf5 }, | ||
185 | { STB0899_DSTATUS2 , 0x00 }, | ||
186 | { STB0899_VSTATUS , 0x00 }, | ||
187 | { STB0899_VERROR , 0x86 }, | ||
188 | { STB0899_IQSWAP , 0x2a }, | ||
189 | { STB0899_ECNT1M , 0x00 }, | ||
190 | { STB0899_ECNT1L , 0x00 }, | ||
191 | { STB0899_ECNT2M , 0x00 }, | ||
192 | { STB0899_ECNT2L , 0x00 }, | ||
193 | { STB0899_ECNT3M , 0x0a }, | ||
194 | { STB0899_ECNT3L , 0xad }, | ||
195 | { STB0899_FECAUTO1 , 0x06 }, | ||
196 | { STB0899_FECM , 0x01 }, | ||
197 | { STB0899_VTH12 , 0xb0 }, | ||
198 | { STB0899_VTH23 , 0x7a }, | ||
199 | { STB0899_VTH34 , 0x58 }, | ||
200 | { STB0899_VTH56 , 0x38 }, | ||
201 | { STB0899_VTH67 , 0x34 }, | ||
202 | { STB0899_VTH78 , 0x24 }, | ||
203 | { STB0899_PRVIT , 0xff }, | ||
204 | { STB0899_VITSYNC , 0x19 }, | ||
205 | { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | ||
206 | { STB0899_TSULC , 0x42 }, | ||
207 | { STB0899_RSLLC , 0x41 }, | ||
208 | { STB0899_TSLPL , 0x12 }, | ||
209 | { STB0899_TSCFGH , 0x0c }, | ||
210 | { STB0899_TSCFGM , 0x00 }, | ||
211 | { STB0899_TSCFGL , 0x00 }, | ||
212 | { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ | ||
213 | { STB0899_RSSYNCDEL , 0x00 }, | ||
214 | { STB0899_TSINHDELH , 0x02 }, | ||
215 | { STB0899_TSINHDELM , 0x00 }, | ||
216 | { STB0899_TSINHDELL , 0x00 }, | ||
217 | { STB0899_TSLLSTKM , 0x1b }, | ||
218 | { STB0899_TSLLSTKL , 0xb3 }, | ||
219 | { STB0899_TSULSTKM , 0x00 }, | ||
220 | { STB0899_TSULSTKL , 0x00 }, | ||
221 | { STB0899_PCKLENUL , 0xbc }, | ||
222 | { STB0899_PCKLENLL , 0xcc }, | ||
223 | { STB0899_RSPCKLEN , 0xbd }, | ||
224 | { STB0899_TSSTATUS , 0x90 }, | ||
225 | { STB0899_ERRCTRL1 , 0xb6 }, | ||
226 | { STB0899_ERRCTRL2 , 0x95 }, | ||
227 | { STB0899_ERRCTRL3 , 0x8d }, | ||
228 | { STB0899_DMONMSK1 , 0x27 }, | ||
229 | { STB0899_DMONMSK0 , 0x03 }, | ||
230 | { STB0899_DEMAPVIT , 0x5c }, | ||
231 | { STB0899_PLPARM , 0x19 }, | ||
232 | { STB0899_PDELCTRL , 0x48 }, | ||
233 | { STB0899_PDELCTRL2 , 0x00 }, | ||
234 | { STB0899_BBHCTRL1 , 0x00 }, | ||
235 | { STB0899_BBHCTRL2 , 0x00 }, | ||
236 | { STB0899_HYSTTHRESH , 0x77 }, | ||
237 | { STB0899_MATCSTM , 0x00 }, | ||
238 | { STB0899_MATCSTL , 0x00 }, | ||
239 | { STB0899_UPLCSTM , 0x00 }, | ||
240 | { STB0899_UPLCSTL , 0x00 }, | ||
241 | { STB0899_DFLCSTM , 0x00 }, | ||
242 | { STB0899_DFLCSTL , 0x00 }, | ||
243 | { STB0899_SYNCCST , 0x00 }, | ||
244 | { STB0899_SYNCDCSTM , 0x00 }, | ||
245 | { STB0899_SYNCDCSTL , 0x00 }, | ||
246 | { STB0899_ISI_ENTRY , 0x00 }, | ||
247 | { STB0899_ISI_BIT_EN , 0x00 }, | ||
248 | { STB0899_MATSTRM , 0xf0 }, | ||
249 | { STB0899_MATSTRL , 0x02 }, | ||
250 | { STB0899_UPLSTRM , 0x45 }, | ||
251 | { STB0899_UPLSTRL , 0x60 }, | ||
252 | { STB0899_DFLSTRM , 0xe3 }, | ||
253 | { STB0899_DFLSTRL , 0x00 }, | ||
254 | { STB0899_SYNCSTR , 0x47 }, | ||
255 | { STB0899_SYNCDSTRM , 0x05 }, | ||
256 | { STB0899_SYNCDSTRL , 0x18 }, | ||
257 | { STB0899_CFGPDELSTATUS1 , 0x19 }, | ||
258 | { STB0899_CFGPDELSTATUS2 , 0x2b }, | ||
259 | { STB0899_BBFERRORM , 0x00 }, | ||
260 | { STB0899_BBFERRORL , 0x01 }, | ||
261 | { STB0899_UPKTERRORM , 0x00 }, | ||
262 | { STB0899_UPKTERRORL , 0x00 }, | ||
263 | { 0xffff , 0xff }, | ||
264 | }; | ||
265 | |||
266 | struct stb0899_config vp1041_stb0899_config = { | ||
267 | .init_dev = vp1041_stb0899_s1_init_1, | ||
268 | .init_s2_demod = stb0899_s2_init_2, | ||
269 | .init_s1_demod = vp1041_stb0899_s1_init_3, | ||
270 | .init_s2_fec = stb0899_s2_init_4, | ||
271 | .init_tst = stb0899_s1_init_5, | ||
272 | |||
273 | .demod_address = 0x68, /* 0xd0 >> 1 */ | ||
274 | |||
275 | .xtal_freq = 27000000, | ||
276 | .inversion = IQ_SWAP_ON, /* 1 */ | ||
277 | |||
278 | .lo_clk = 76500000, | ||
279 | .hi_clk = 99000000, | ||
280 | |||
281 | .esno_ave = STB0899_DVBS2_ESNO_AVE, | ||
282 | .esno_quant = STB0899_DVBS2_ESNO_QUANT, | ||
283 | .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, | ||
284 | .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, | ||
285 | .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, | ||
286 | .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, | ||
287 | .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, | ||
288 | .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, | ||
289 | .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | ||
290 | |||
291 | .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, | ||
292 | .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | ||
293 | .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, | ||
294 | .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, | ||
295 | |||
296 | .tuner_get_frequency = stb6100_get_frequency, | ||
297 | .tuner_set_frequency = stb6100_set_frequency, | ||
298 | .tuner_set_bandwidth = stb6100_set_bandwidth, | ||
299 | .tuner_get_bandwidth = stb6100_get_bandwidth, | ||
300 | .tuner_set_rfsiggain = NULL, | ||
301 | }; | ||
302 | |||
303 | struct stb6100_config vp1041_stb6100_config = { | ||
304 | .tuner_address = 0x60, | ||
305 | .refclock = 27000000, | ||
306 | }; | ||
307 | |||
308 | static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
309 | { | ||
310 | struct i2c_adapter *adapter = &mantis->adapter; | ||
311 | |||
312 | int err = 0; | ||
313 | |||
314 | err = mantis_frontend_power(mantis, POWER_ON); | ||
315 | if (err == 0) { | ||
316 | mantis_frontend_soft_reset(mantis); | ||
317 | msleep(250); | ||
318 | mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter); | ||
319 | if (mantis->fe) { | ||
320 | dprintk(MANTIS_ERROR, 1, | ||
321 | "found STB0899 DVB-S/DVB-S2 frontend @0x%02x", | ||
322 | vp1041_stb0899_config.demod_address); | ||
323 | |||
324 | if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) { | ||
325 | if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0)) | ||
326 | dprintk(MANTIS_ERROR, 1, "No LNBP21 found!"); | ||
327 | } | ||
328 | } else { | ||
329 | return -EREMOTEIO; | ||
330 | } | ||
331 | } else { | ||
332 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
333 | adapter->name, | ||
334 | err); | ||
335 | |||
336 | return -EIO; | ||
337 | } | ||
338 | |||
339 | |||
340 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | struct mantis_hwconfig vp1041_config = { | ||
346 | .model_name = MANTIS_MODEL_NAME, | ||
347 | .dev_type = MANTIS_DEV_TYPE, | ||
348 | .ts_size = MANTIS_TS_188, | ||
349 | |||
350 | .baud_rate = MANTIS_BAUD_9600, | ||
351 | .parity = MANTIS_PARITY_NONE, | ||
352 | .bytes = 0, | ||
353 | |||
354 | .frontend_init = vp1041_frontend_init, | ||
355 | .power = GPIF_A12, | ||
356 | .reset = GPIF_A13, | ||
357 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.h b/drivers/media/dvb/mantis/mantis_vp1041.h deleted file mode 100644 index 1ae5b3de8081..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp1041.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-1041 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP1041_H | ||
22 | #define __MANTIS_VP1041_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_1041_DVB_S2 0x0031 | ||
27 | #define SKYSTAR_HD2_10 0x0001 | ||
28 | #define SKYSTAR_HD2_20 0x0003 | ||
29 | #define CINERGY_S2_PCI_HD 0x1179 | ||
30 | |||
31 | extern struct mantis_hwconfig vp1041_config; | ||
32 | |||
33 | #endif /* __MANTIS_VP1041_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c deleted file mode 100644 index 1ca6837fbe46..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp2033.c +++ /dev/null | |||
@@ -1,188 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-2033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "tda1002x.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp2033.h" | ||
36 | |||
37 | #define MANTIS_MODEL_NAME "VP-2033" | ||
38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
39 | |||
40 | struct tda1002x_config vp2033_tda1002x_cu1216_config = { | ||
41 | .demod_address = 0x18 >> 1, | ||
42 | .invert = 1, | ||
43 | }; | ||
44 | |||
45 | struct tda10023_config vp2033_tda10023_cu1216_config = { | ||
46 | .demod_address = 0x18 >> 1, | ||
47 | .invert = 1, | ||
48 | }; | ||
49 | |||
50 | static u8 read_pwm(struct mantis_pci *mantis) | ||
51 | { | ||
52 | struct i2c_adapter *adapter = &mantis->adapter; | ||
53 | |||
54 | u8 b = 0xff; | ||
55 | u8 pwm; | ||
56 | struct i2c_msg msg[] = { | ||
57 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
58 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
59 | }; | ||
60 | |||
61 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
62 | || (pwm == 0xff)) | ||
63 | pwm = 0x48; | ||
64 | |||
65 | return pwm; | ||
66 | } | ||
67 | |||
68 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe) | ||
69 | { | ||
70 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
71 | struct mantis_pci *mantis = fe->dvb->priv; | ||
72 | struct i2c_adapter *adapter = &mantis->adapter; | ||
73 | |||
74 | u8 buf[6]; | ||
75 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
76 | int i; | ||
77 | |||
78 | #define CU1216_IF 36125000 | ||
79 | #define TUNER_MUL 62500 | ||
80 | |||
81 | u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
82 | |||
83 | buf[0] = (div >> 8) & 0x7f; | ||
84 | buf[1] = div & 0xff; | ||
85 | buf[2] = 0xce; | ||
86 | buf[3] = (p->frequency < 150000000 ? 0x01 : | ||
87 | p->frequency < 445000000 ? 0x02 : 0x04); | ||
88 | buf[4] = 0xde; | ||
89 | buf[5] = 0x20; | ||
90 | |||
91 | if (fe->ops.i2c_gate_ctrl) | ||
92 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
93 | |||
94 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
95 | return -EIO; | ||
96 | |||
97 | /* wait for the pll lock */ | ||
98 | msg.flags = I2C_M_RD; | ||
99 | msg.len = 1; | ||
100 | for (i = 0; i < 20; i++) { | ||
101 | if (fe->ops.i2c_gate_ctrl) | ||
102 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
103 | |||
104 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
105 | break; | ||
106 | |||
107 | msleep(10); | ||
108 | } | ||
109 | |||
110 | /* switch the charge pump to the lower current */ | ||
111 | msg.flags = 0; | ||
112 | msg.len = 2; | ||
113 | msg.buf = &buf[2]; | ||
114 | buf[2] &= ~0x40; | ||
115 | if (fe->ops.i2c_gate_ctrl) | ||
116 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
117 | |||
118 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
119 | return -EIO; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
125 | { | ||
126 | struct i2c_adapter *adapter = &mantis->adapter; | ||
127 | |||
128 | int err = 0; | ||
129 | |||
130 | err = mantis_frontend_power(mantis, POWER_ON); | ||
131 | if (err == 0) { | ||
132 | mantis_frontend_soft_reset(mantis); | ||
133 | msleep(250); | ||
134 | |||
135 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
136 | fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config, | ||
137 | adapter, | ||
138 | read_pwm(mantis)); | ||
139 | |||
140 | if (fe) { | ||
141 | dprintk(MANTIS_ERROR, 1, | ||
142 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
143 | vp2033_tda1002x_cu1216_config.demod_address); | ||
144 | } else { | ||
145 | fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config, | ||
146 | adapter, | ||
147 | read_pwm(mantis)); | ||
148 | |||
149 | if (fe) { | ||
150 | dprintk(MANTIS_ERROR, 1, | ||
151 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
152 | vp2033_tda1002x_cu1216_config.demod_address); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | if (fe) { | ||
157 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
158 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
159 | } else { | ||
160 | return -1; | ||
161 | } | ||
162 | } else { | ||
163 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
164 | adapter->name, | ||
165 | err); | ||
166 | |||
167 | return -EIO; | ||
168 | } | ||
169 | |||
170 | mantis->fe = fe; | ||
171 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | struct mantis_hwconfig vp2033_config = { | ||
177 | .model_name = MANTIS_MODEL_NAME, | ||
178 | .dev_type = MANTIS_DEV_TYPE, | ||
179 | .ts_size = MANTIS_TS_204, | ||
180 | |||
181 | .baud_rate = MANTIS_BAUD_9600, | ||
182 | .parity = MANTIS_PARITY_NONE, | ||
183 | .bytes = 0, | ||
184 | |||
185 | .frontend_init = vp2033_frontend_init, | ||
186 | .power = GPIF_A12, | ||
187 | .reset = GPIF_A13, | ||
188 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.h b/drivers/media/dvb/mantis/mantis_vp2033.h deleted file mode 100644 index c55242b79d54..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp2033.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-2033 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP2033_H | ||
22 | #define __MANTIS_VP2033_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_2033_DVB_C 0x0008 | ||
27 | |||
28 | extern struct mantis_hwconfig vp2033_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP2033_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/dvb/mantis/mantis_vp2040.c deleted file mode 100644 index d480741afd78..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp2040.c +++ /dev/null | |||
@@ -1,187 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-2040 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "tda1002x.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp2040.h" | ||
36 | |||
37 | #define MANTIS_MODEL_NAME "VP-2040" | ||
38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
39 | |||
40 | struct tda1002x_config vp2040_tda1002x_cu1216_config = { | ||
41 | .demod_address = 0x18 >> 1, | ||
42 | .invert = 1, | ||
43 | }; | ||
44 | |||
45 | struct tda10023_config vp2040_tda10023_cu1216_config = { | ||
46 | .demod_address = 0x18 >> 1, | ||
47 | .invert = 1, | ||
48 | }; | ||
49 | |||
50 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe) | ||
51 | { | ||
52 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
53 | struct mantis_pci *mantis = fe->dvb->priv; | ||
54 | struct i2c_adapter *adapter = &mantis->adapter; | ||
55 | |||
56 | u8 buf[6]; | ||
57 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
58 | int i; | ||
59 | |||
60 | #define CU1216_IF 36125000 | ||
61 | #define TUNER_MUL 62500 | ||
62 | |||
63 | u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
64 | |||
65 | buf[0] = (div >> 8) & 0x7f; | ||
66 | buf[1] = div & 0xff; | ||
67 | buf[2] = 0xce; | ||
68 | buf[3] = (p->frequency < 150000000 ? 0x01 : | ||
69 | p->frequency < 445000000 ? 0x02 : 0x04); | ||
70 | buf[4] = 0xde; | ||
71 | buf[5] = 0x20; | ||
72 | |||
73 | if (fe->ops.i2c_gate_ctrl) | ||
74 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
75 | |||
76 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
77 | return -EIO; | ||
78 | |||
79 | /* wait for the pll lock */ | ||
80 | msg.flags = I2C_M_RD; | ||
81 | msg.len = 1; | ||
82 | for (i = 0; i < 20; i++) { | ||
83 | if (fe->ops.i2c_gate_ctrl) | ||
84 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
85 | |||
86 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
87 | break; | ||
88 | |||
89 | msleep(10); | ||
90 | } | ||
91 | |||
92 | /* switch the charge pump to the lower current */ | ||
93 | msg.flags = 0; | ||
94 | msg.len = 2; | ||
95 | msg.buf = &buf[2]; | ||
96 | buf[2] &= ~0x40; | ||
97 | if (fe->ops.i2c_gate_ctrl) | ||
98 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
99 | |||
100 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
101 | return -EIO; | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static u8 read_pwm(struct mantis_pci *mantis) | ||
107 | { | ||
108 | struct i2c_adapter *adapter = &mantis->adapter; | ||
109 | |||
110 | u8 b = 0xff; | ||
111 | u8 pwm; | ||
112 | struct i2c_msg msg[] = { | ||
113 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
114 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
115 | }; | ||
116 | |||
117 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
118 | || (pwm == 0xff)) | ||
119 | pwm = 0x48; | ||
120 | |||
121 | return pwm; | ||
122 | } | ||
123 | |||
124 | static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
125 | { | ||
126 | struct i2c_adapter *adapter = &mantis->adapter; | ||
127 | |||
128 | int err = 0; | ||
129 | |||
130 | err = mantis_frontend_power(mantis, POWER_ON); | ||
131 | if (err == 0) { | ||
132 | mantis_frontend_soft_reset(mantis); | ||
133 | msleep(250); | ||
134 | |||
135 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
136 | fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config, | ||
137 | adapter, | ||
138 | read_pwm(mantis)); | ||
139 | |||
140 | if (fe) { | ||
141 | dprintk(MANTIS_ERROR, 1, | ||
142 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
143 | vp2040_tda1002x_cu1216_config.demod_address); | ||
144 | } else { | ||
145 | fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config, | ||
146 | adapter, | ||
147 | read_pwm(mantis)); | ||
148 | |||
149 | if (fe) { | ||
150 | dprintk(MANTIS_ERROR, 1, | ||
151 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
152 | vp2040_tda1002x_cu1216_config.demod_address); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | if (fe) { | ||
157 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
158 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
159 | } else { | ||
160 | return -1; | ||
161 | } | ||
162 | } else { | ||
163 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
164 | adapter->name, | ||
165 | err); | ||
166 | |||
167 | return -EIO; | ||
168 | } | ||
169 | mantis->fe = fe; | ||
170 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | struct mantis_hwconfig vp2040_config = { | ||
176 | .model_name = MANTIS_MODEL_NAME, | ||
177 | .dev_type = MANTIS_DEV_TYPE, | ||
178 | .ts_size = MANTIS_TS_204, | ||
179 | |||
180 | .baud_rate = MANTIS_BAUD_9600, | ||
181 | .parity = MANTIS_PARITY_NONE, | ||
182 | .bytes = 0, | ||
183 | |||
184 | .frontend_init = vp2040_frontend_init, | ||
185 | .power = GPIF_A12, | ||
186 | .reset = GPIF_A13, | ||
187 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.h b/drivers/media/dvb/mantis/mantis_vp2040.h deleted file mode 100644 index d125e219b685..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp2040.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-2040 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP2040_H | ||
22 | #define __MANTIS_VP2040_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_2040_DVB_C 0x0043 | ||
27 | #define CINERGY_C 0x1178 | ||
28 | #define CABLESTAR_HD2 0x0002 | ||
29 | |||
30 | extern struct mantis_hwconfig vp2040_config; | ||
31 | |||
32 | #endif /* __MANTIS_VP2040_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.c b/drivers/media/dvb/mantis/mantis_vp3028.c deleted file mode 100644 index 4155c838a18a..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp3028.c +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include "mantis_common.h" | ||
22 | #include "mantis_vp3028.h" | ||
23 | |||
24 | struct zl10353_config mantis_vp3028_config = { | ||
25 | .demod_address = 0x0f, | ||
26 | }; | ||
27 | |||
28 | #define MANTIS_MODEL_NAME "VP-3028" | ||
29 | #define MANTIS_DEV_TYPE "DVB-T" | ||
30 | |||
31 | struct mantis_hwconfig vp3028_mantis_config = { | ||
32 | .model_name = MANTIS_MODEL_NAME, | ||
33 | .dev_type = MANTIS_DEV_TYPE, | ||
34 | .ts_size = MANTIS_TS_188, | ||
35 | .baud_rate = MANTIS_BAUD_9600, | ||
36 | .parity = MANTIS_PARITY_NONE, | ||
37 | .bytes = 0, | ||
38 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.h b/drivers/media/dvb/mantis/mantis_vp3028.h deleted file mode 100644 index b07be6adc522..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp3028.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP3028_H | ||
22 | #define __MANTIS_VP3028_H | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | #include "mantis_common.h" | ||
26 | #include "zl10353.h" | ||
27 | |||
28 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
29 | |||
30 | extern struct zl10353_config mantis_vp3028_config; | ||
31 | extern struct mantis_hwconfig vp3028_mantis_config; | ||
32 | |||
33 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c deleted file mode 100644 index c09308cd3ac6..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp3030.c +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-3030 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "zl10353.h" | ||
32 | #include "tda665x.h" | ||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_ioc.h" | ||
35 | #include "mantis_dvb.h" | ||
36 | #include "mantis_vp3030.h" | ||
37 | |||
38 | struct zl10353_config mantis_vp3030_config = { | ||
39 | .demod_address = 0x0f, | ||
40 | }; | ||
41 | |||
42 | struct tda665x_config env57h12d5_config = { | ||
43 | .name = "ENV57H12D5 (ET-50DT)", | ||
44 | .addr = 0x60, | ||
45 | .frequency_min = 47000000, | ||
46 | .frequency_max = 862000000, | ||
47 | .frequency_offst = 3616667, | ||
48 | .ref_multiplier = 6, /* 1/6 MHz */ | ||
49 | .ref_divider = 100000, /* 1/6 MHz */ | ||
50 | }; | ||
51 | |||
52 | #define MANTIS_MODEL_NAME "VP-3030" | ||
53 | #define MANTIS_DEV_TYPE "DVB-T" | ||
54 | |||
55 | |||
56 | static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
57 | { | ||
58 | struct i2c_adapter *adapter = &mantis->adapter; | ||
59 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
60 | int err = 0; | ||
61 | |||
62 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
63 | msleep(100); | ||
64 | err = mantis_frontend_power(mantis, POWER_ON); | ||
65 | msleep(100); | ||
66 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
67 | |||
68 | if (err == 0) { | ||
69 | msleep(250); | ||
70 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
71 | fe = dvb_attach(zl10353_attach, &mantis_vp3030_config, adapter); | ||
72 | |||
73 | if (!fe) | ||
74 | return -1; | ||
75 | |||
76 | dvb_attach(tda665x_attach, fe, &env57h12d5_config, adapter); | ||
77 | } else { | ||
78 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
79 | adapter->name, | ||
80 | err); | ||
81 | |||
82 | return -EIO; | ||
83 | |||
84 | } | ||
85 | mantis->fe = fe; | ||
86 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | struct mantis_hwconfig vp3030_config = { | ||
92 | .model_name = MANTIS_MODEL_NAME, | ||
93 | .dev_type = MANTIS_DEV_TYPE, | ||
94 | .ts_size = MANTIS_TS_188, | ||
95 | |||
96 | .baud_rate = MANTIS_BAUD_9600, | ||
97 | .parity = MANTIS_PARITY_NONE, | ||
98 | .bytes = 0, | ||
99 | |||
100 | .frontend_init = vp3030_frontend_init, | ||
101 | .power = GPIF_A12, | ||
102 | .reset = GPIF_A13, | ||
103 | |||
104 | .i2c_mode = MANTIS_BYTE_MODE | ||
105 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.h b/drivers/media/dvb/mantis/mantis_vp3030.h deleted file mode 100644 index 5f12c4266277..000000000000 --- a/drivers/media/dvb/mantis/mantis_vp3030.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-3030 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP3030_H | ||
22 | #define __MANTIS_VP3030_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_3030_DVB_T 0x0024 | ||
27 | |||
28 | extern struct mantis_hwconfig vp3030_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP3030_H */ | ||
diff --git a/drivers/media/dvb/ngene/Kconfig b/drivers/media/dvb/ngene/Kconfig deleted file mode 100644 index 64c84702ba5c..000000000000 --- a/drivers/media/dvb/ngene/Kconfig +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | config DVB_NGENE | ||
2 | tristate "Micronas nGene support" | ||
3 | depends on DVB_CORE && PCI && I2C | ||
4 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
5 | select DVB_STV6110x if !DVB_FE_CUSTOMISE | ||
6 | select DVB_STV090x if !DVB_FE_CUSTOMISE | ||
7 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | ||
8 | select DVB_DRXK if !DVB_FE_CUSTOMISE | ||
9 | select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE | ||
10 | select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE | ||
11 | ---help--- | ||
12 | Support for Micronas PCI express cards with nGene bridge. | ||
13 | |||
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile deleted file mode 100644 index 63997089f9d1..000000000000 --- a/drivers/media/dvb/ngene/Makefile +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the nGene device driver | ||
3 | # | ||
4 | |||
5 | ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o | ||
6 | |||
7 | obj-$(CONFIG_DVB_NGENE) += ngene.o | ||
8 | |||
9 | ccflags-y += -Idrivers/media/dvb-core/ | ||
10 | ccflags-y += -Idrivers/media/dvb-frontends/ | ||
11 | ccflags-y += -Idrivers/media/common/tuners/ | ||
12 | |||
13 | # For the staging CI driver cxd2099 | ||
14 | ccflags-y += -Idrivers/staging/media/cxd2099/ | ||
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c deleted file mode 100644 index a6cd6959ad19..000000000000 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ /dev/null | |||
@@ -1,823 +0,0 @@ | |||
1 | /* | ||
2 | * ngene-cards.c: nGene PCIe bridge driver - card specific info | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * Modifications for new nGene firmware, | ||
8 | * support for EEPROM-copying, | ||
9 | * support for new dual DVB-S2 card prototype | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * version 2 only, as published by the Free Software Foundation. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
26 | * 02110-1301, USA | ||
27 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/pci_ids.h> | ||
34 | |||
35 | #include "ngene.h" | ||
36 | |||
37 | /* demods/tuners */ | ||
38 | #include "stv6110x.h" | ||
39 | #include "stv090x.h" | ||
40 | #include "lnbh24.h" | ||
41 | #include "lgdt330x.h" | ||
42 | #include "mt2131.h" | ||
43 | #include "tda18271c2dd.h" | ||
44 | #include "drxk.h" | ||
45 | #include "drxd.h" | ||
46 | #include "dvb-pll.h" | ||
47 | |||
48 | |||
49 | /****************************************************************************/ | ||
50 | /* Demod/tuner attachment ***************************************************/ | ||
51 | /****************************************************************************/ | ||
52 | |||
53 | static int tuner_attach_stv6110(struct ngene_channel *chan) | ||
54 | { | ||
55 | struct i2c_adapter *i2c; | ||
56 | struct stv090x_config *feconf = (struct stv090x_config *) | ||
57 | chan->dev->card_info->fe_config[chan->number]; | ||
58 | struct stv6110x_config *tunerconf = (struct stv6110x_config *) | ||
59 | chan->dev->card_info->tuner_config[chan->number]; | ||
60 | struct stv6110x_devctl *ctl; | ||
61 | |||
62 | /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ | ||
63 | if (chan->number < 2) | ||
64 | i2c = &chan->dev->channel[0].i2c_adapter; | ||
65 | else | ||
66 | i2c = &chan->dev->channel[1].i2c_adapter; | ||
67 | |||
68 | ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c); | ||
69 | if (ctl == NULL) { | ||
70 | printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n"); | ||
71 | return -ENODEV; | ||
72 | } | ||
73 | |||
74 | feconf->tuner_init = ctl->tuner_init; | ||
75 | feconf->tuner_sleep = ctl->tuner_sleep; | ||
76 | feconf->tuner_set_mode = ctl->tuner_set_mode; | ||
77 | feconf->tuner_set_frequency = ctl->tuner_set_frequency; | ||
78 | feconf->tuner_get_frequency = ctl->tuner_get_frequency; | ||
79 | feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
80 | feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
81 | feconf->tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
82 | feconf->tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
83 | feconf->tuner_set_refclk = ctl->tuner_set_refclk; | ||
84 | feconf->tuner_get_status = ctl->tuner_get_status; | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | |||
90 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
91 | { | ||
92 | struct ngene_channel *chan = fe->sec_priv; | ||
93 | int status; | ||
94 | |||
95 | if (enable) { | ||
96 | down(&chan->dev->pll_mutex); | ||
97 | status = chan->gate_ctrl(fe, 1); | ||
98 | } else { | ||
99 | status = chan->gate_ctrl(fe, 0); | ||
100 | up(&chan->dev->pll_mutex); | ||
101 | } | ||
102 | return status; | ||
103 | } | ||
104 | |||
105 | static int tuner_attach_tda18271(struct ngene_channel *chan) | ||
106 | { | ||
107 | struct i2c_adapter *i2c; | ||
108 | struct dvb_frontend *fe; | ||
109 | |||
110 | i2c = &chan->dev->channel[0].i2c_adapter; | ||
111 | if (chan->fe->ops.i2c_gate_ctrl) | ||
112 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 1); | ||
113 | fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60); | ||
114 | if (chan->fe->ops.i2c_gate_ctrl) | ||
115 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 0); | ||
116 | if (!fe) { | ||
117 | printk(KERN_ERR "No TDA18271 found!\n"); | ||
118 | return -ENODEV; | ||
119 | } | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int tuner_attach_probe(struct ngene_channel *chan) | ||
125 | { | ||
126 | if (chan->demod_type == 0) | ||
127 | return tuner_attach_stv6110(chan); | ||
128 | if (chan->demod_type == 1) | ||
129 | return tuner_attach_tda18271(chan); | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | |||
133 | static int demod_attach_stv0900(struct ngene_channel *chan) | ||
134 | { | ||
135 | struct i2c_adapter *i2c; | ||
136 | struct stv090x_config *feconf = (struct stv090x_config *) | ||
137 | chan->dev->card_info->fe_config[chan->number]; | ||
138 | |||
139 | /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ | ||
140 | /* Note: Both adapters share the same i2c bus, but the demod */ | ||
141 | /* driver requires that each demod has its own i2c adapter */ | ||
142 | if (chan->number < 2) | ||
143 | i2c = &chan->dev->channel[0].i2c_adapter; | ||
144 | else | ||
145 | i2c = &chan->dev->channel[1].i2c_adapter; | ||
146 | |||
147 | chan->fe = dvb_attach(stv090x_attach, feconf, i2c, | ||
148 | (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0 | ||
149 | : STV090x_DEMODULATOR_1); | ||
150 | if (chan->fe == NULL) { | ||
151 | printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n"); | ||
152 | return -ENODEV; | ||
153 | } | ||
154 | |||
155 | /* store channel info */ | ||
156 | if (feconf->tuner_i2c_lock) | ||
157 | chan->fe->analog_demod_priv = chan; | ||
158 | |||
159 | if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0, | ||
160 | 0, chan->dev->card_info->lnb[chan->number])) { | ||
161 | printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n"); | ||
162 | dvb_frontend_detach(chan->fe); | ||
163 | chan->fe = NULL; | ||
164 | return -ENODEV; | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock) | ||
171 | { | ||
172 | struct ngene_channel *chan = fe->analog_demod_priv; | ||
173 | |||
174 | if (lock) | ||
175 | down(&chan->dev->pll_mutex); | ||
176 | else | ||
177 | up(&chan->dev->pll_mutex); | ||
178 | } | ||
179 | |||
180 | static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) | ||
181 | { | ||
182 | struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, | ||
183 | .buf = val, .len = 1 } }; | ||
184 | return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; | ||
185 | } | ||
186 | |||
187 | static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, | ||
188 | u16 reg, u8 *val) | ||
189 | { | ||
190 | u8 msg[2] = {reg>>8, reg&0xff}; | ||
191 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
192 | .buf = msg, .len = 2}, | ||
193 | {.addr = adr, .flags = I2C_M_RD, | ||
194 | .buf = val, .len = 1} }; | ||
195 | return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||
196 | } | ||
197 | |||
198 | static int port_has_stv0900(struct i2c_adapter *i2c, int port) | ||
199 | { | ||
200 | u8 val; | ||
201 | if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0) | ||
202 | return 0; | ||
203 | return 1; | ||
204 | } | ||
205 | |||
206 | static int port_has_drxk(struct i2c_adapter *i2c, int port) | ||
207 | { | ||
208 | u8 val; | ||
209 | |||
210 | if (i2c_read(i2c, 0x29+port, &val) < 0) | ||
211 | return 0; | ||
212 | return 1; | ||
213 | } | ||
214 | |||
215 | static int demod_attach_drxk(struct ngene_channel *chan, | ||
216 | struct i2c_adapter *i2c) | ||
217 | { | ||
218 | struct drxk_config config; | ||
219 | |||
220 | memset(&config, 0, sizeof(config)); | ||
221 | config.microcode_name = "drxk_a3.mc"; | ||
222 | config.qam_demod_parameter_count = 4; | ||
223 | config.adr = 0x29 + (chan->number ^ 2); | ||
224 | |||
225 | chan->fe = dvb_attach(drxk_attach, &config, i2c); | ||
226 | if (!chan->fe) { | ||
227 | printk(KERN_ERR "No DRXK found!\n"); | ||
228 | return -ENODEV; | ||
229 | } | ||
230 | chan->fe->sec_priv = chan; | ||
231 | chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; | ||
232 | chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int cineS2_probe(struct ngene_channel *chan) | ||
237 | { | ||
238 | struct i2c_adapter *i2c; | ||
239 | struct stv090x_config *fe_conf; | ||
240 | u8 buf[3]; | ||
241 | struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; | ||
242 | int rc; | ||
243 | |||
244 | /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ | ||
245 | if (chan->number < 2) | ||
246 | i2c = &chan->dev->channel[0].i2c_adapter; | ||
247 | else | ||
248 | i2c = &chan->dev->channel[1].i2c_adapter; | ||
249 | |||
250 | if (port_has_stv0900(i2c, chan->number)) { | ||
251 | chan->demod_type = 0; | ||
252 | fe_conf = chan->dev->card_info->fe_config[chan->number]; | ||
253 | /* demod found, attach it */ | ||
254 | rc = demod_attach_stv0900(chan); | ||
255 | if (rc < 0 || chan->number < 2) | ||
256 | return rc; | ||
257 | |||
258 | /* demod #2: reprogram outputs DPN1 & DPN2 */ | ||
259 | i2c_msg.addr = fe_conf->address; | ||
260 | i2c_msg.len = 3; | ||
261 | buf[0] = 0xf1; | ||
262 | switch (chan->number) { | ||
263 | case 2: | ||
264 | buf[1] = 0x5c; | ||
265 | buf[2] = 0xc2; | ||
266 | break; | ||
267 | case 3: | ||
268 | buf[1] = 0x61; | ||
269 | buf[2] = 0xcc; | ||
270 | break; | ||
271 | default: | ||
272 | return -ENODEV; | ||
273 | } | ||
274 | rc = i2c_transfer(i2c, &i2c_msg, 1); | ||
275 | if (rc != 1) { | ||
276 | printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); | ||
277 | return -EIO; | ||
278 | } | ||
279 | } else if (port_has_drxk(i2c, chan->number^2)) { | ||
280 | chan->demod_type = 1; | ||
281 | demod_attach_drxk(chan, i2c); | ||
282 | } else { | ||
283 | printk(KERN_ERR "No demod found on chan %d\n", chan->number); | ||
284 | return -ENODEV; | ||
285 | } | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | |||
290 | static struct lgdt330x_config aver_m780 = { | ||
291 | .demod_address = 0xb2 >> 1, | ||
292 | .demod_chip = LGDT3303, | ||
293 | .serial_mpeg = 0x00, /* PARALLEL */ | ||
294 | .clock_polarity_flip = 1, | ||
295 | }; | ||
296 | |||
297 | static struct mt2131_config m780_tunerconfig = { | ||
298 | 0xc0 >> 1 | ||
299 | }; | ||
300 | |||
301 | /* A single func to attach the demo and tuner, rather than | ||
302 | * use two sep funcs like the current design mandates. | ||
303 | */ | ||
304 | static int demod_attach_lg330x(struct ngene_channel *chan) | ||
305 | { | ||
306 | chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter); | ||
307 | if (chan->fe == NULL) { | ||
308 | printk(KERN_ERR DEVICE_NAME ": No LGDT330x found!\n"); | ||
309 | return -ENODEV; | ||
310 | } | ||
311 | |||
312 | dvb_attach(mt2131_attach, chan->fe, &chan->i2c_adapter, | ||
313 | &m780_tunerconfig, 0); | ||
314 | |||
315 | return (chan->fe) ? 0 : -ENODEV; | ||
316 | } | ||
317 | |||
318 | static int demod_attach_drxd(struct ngene_channel *chan) | ||
319 | { | ||
320 | struct drxd_config *feconf; | ||
321 | |||
322 | feconf = chan->dev->card_info->fe_config[chan->number]; | ||
323 | |||
324 | chan->fe = dvb_attach(drxd_attach, feconf, chan, | ||
325 | &chan->i2c_adapter, &chan->dev->pci_dev->dev); | ||
326 | if (!chan->fe) { | ||
327 | pr_err("No DRXD found!\n"); | ||
328 | return -ENODEV; | ||
329 | } | ||
330 | |||
331 | if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address, | ||
332 | &chan->i2c_adapter, | ||
333 | feconf->pll_type)) { | ||
334 | pr_err("No pll(%d) found!\n", feconf->pll_type); | ||
335 | return -ENODEV; | ||
336 | } | ||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | /****************************************************************************/ | ||
341 | /* EEPROM TAGS **************************************************************/ | ||
342 | /****************************************************************************/ | ||
343 | |||
344 | #define MICNG_EE_START 0x0100 | ||
345 | #define MICNG_EE_END 0x0FF0 | ||
346 | |||
347 | #define MICNG_EETAG_END0 0x0000 | ||
348 | #define MICNG_EETAG_END1 0xFFFF | ||
349 | |||
350 | /* 0x0001 - 0x000F reserved for housekeeping */ | ||
351 | /* 0xFFFF - 0xFFFE reserved for housekeeping */ | ||
352 | |||
353 | /* Micronas assigned tags | ||
354 | EEProm tags for hardware support */ | ||
355 | |||
356 | #define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */ | ||
357 | #define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */ | ||
358 | |||
359 | #define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */ | ||
360 | #define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */ | ||
361 | |||
362 | /* Tag range for OEMs */ | ||
363 | |||
364 | #define MICNG_EETAG_OEM_FIRST 0xC000 | ||
365 | #define MICNG_EETAG_OEM_LAST 0xFFEF | ||
366 | |||
367 | static int i2c_write_eeprom(struct i2c_adapter *adapter, | ||
368 | u8 adr, u16 reg, u8 data) | ||
369 | { | ||
370 | u8 m[3] = {(reg >> 8), (reg & 0xff), data}; | ||
371 | struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, | ||
372 | .len = sizeof(m)}; | ||
373 | |||
374 | if (i2c_transfer(adapter, &msg, 1) != 1) { | ||
375 | pr_err(DEVICE_NAME ": Error writing EEPROM!\n"); | ||
376 | return -EIO; | ||
377 | } | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int i2c_read_eeprom(struct i2c_adapter *adapter, | ||
382 | u8 adr, u16 reg, u8 *data, int len) | ||
383 | { | ||
384 | u8 msg[2] = {(reg >> 8), (reg & 0xff)}; | ||
385 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
386 | .buf = msg, .len = 2 }, | ||
387 | {.addr = adr, .flags = I2C_M_RD, | ||
388 | .buf = data, .len = len} }; | ||
389 | |||
390 | if (i2c_transfer(adapter, msgs, 2) != 2) { | ||
391 | pr_err(DEVICE_NAME ": Error reading EEPROM\n"); | ||
392 | return -EIO; | ||
393 | } | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static int ReadEEProm(struct i2c_adapter *adapter, | ||
398 | u16 Tag, u32 MaxLen, u8 *data, u32 *pLength) | ||
399 | { | ||
400 | int status = 0; | ||
401 | u16 Addr = MICNG_EE_START, Length, tag = 0; | ||
402 | u8 EETag[3]; | ||
403 | |||
404 | while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { | ||
405 | if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) | ||
406 | return -1; | ||
407 | tag = (EETag[0] << 8) | EETag[1]; | ||
408 | if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) | ||
409 | return -1; | ||
410 | if (tag == Tag) | ||
411 | break; | ||
412 | Addr += sizeof(u16) + 1 + EETag[2]; | ||
413 | } | ||
414 | if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { | ||
415 | pr_err(DEVICE_NAME | ||
416 | ": Reached EOEE @ Tag = %04x Length = %3d\n", | ||
417 | tag, EETag[2]); | ||
418 | return -1; | ||
419 | } | ||
420 | Length = EETag[2]; | ||
421 | if (Length > MaxLen) | ||
422 | Length = (u16) MaxLen; | ||
423 | if (Length > 0) { | ||
424 | Addr += sizeof(u16) + 1; | ||
425 | status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length); | ||
426 | if (!status) { | ||
427 | *pLength = EETag[2]; | ||
428 | if (Length < EETag[2]) | ||
429 | ; /*status=STATUS_BUFFER_OVERFLOW; */ | ||
430 | } | ||
431 | } | ||
432 | return status; | ||
433 | } | ||
434 | |||
435 | static int WriteEEProm(struct i2c_adapter *adapter, | ||
436 | u16 Tag, u32 Length, u8 *data) | ||
437 | { | ||
438 | int status = 0; | ||
439 | u16 Addr = MICNG_EE_START; | ||
440 | u8 EETag[3]; | ||
441 | u16 tag = 0; | ||
442 | int retry, i; | ||
443 | |||
444 | while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { | ||
445 | if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) | ||
446 | return -1; | ||
447 | tag = (EETag[0] << 8) | EETag[1]; | ||
448 | if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) | ||
449 | return -1; | ||
450 | if (tag == Tag) | ||
451 | break; | ||
452 | Addr += sizeof(u16) + 1 + EETag[2]; | ||
453 | } | ||
454 | if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { | ||
455 | pr_err(DEVICE_NAME | ||
456 | ": Reached EOEE @ Tag = %04x Length = %3d\n", | ||
457 | tag, EETag[2]); | ||
458 | return -1; | ||
459 | } | ||
460 | |||
461 | if (Length > EETag[2]) | ||
462 | return -EINVAL; | ||
463 | /* Note: We write the data one byte at a time to avoid | ||
464 | issues with page sizes. (which are different for | ||
465 | each manufacture and eeprom size) | ||
466 | */ | ||
467 | Addr += sizeof(u16) + 1; | ||
468 | for (i = 0; i < Length; i++, Addr++) { | ||
469 | status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]); | ||
470 | |||
471 | if (status) | ||
472 | break; | ||
473 | |||
474 | /* Poll for finishing write cycle */ | ||
475 | retry = 10; | ||
476 | while (retry) { | ||
477 | u8 Tmp; | ||
478 | |||
479 | msleep(50); | ||
480 | status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1); | ||
481 | if (status) | ||
482 | break; | ||
483 | if (Tmp != data[i]) | ||
484 | pr_err(DEVICE_NAME | ||
485 | "eeprom write error\n"); | ||
486 | retry -= 1; | ||
487 | } | ||
488 | if (status) { | ||
489 | pr_err(DEVICE_NAME | ||
490 | ": Timeout polling eeprom\n"); | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | return status; | ||
495 | } | ||
496 | |||
497 | static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data) | ||
498 | { | ||
499 | int stat; | ||
500 | u8 buf[2]; | ||
501 | u32 len = 0; | ||
502 | |||
503 | stat = ReadEEProm(adapter, tag, 2, buf, &len); | ||
504 | if (stat) | ||
505 | return stat; | ||
506 | if (len != 2) | ||
507 | return -EINVAL; | ||
508 | |||
509 | *data = (buf[0] << 8) | buf[1]; | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data) | ||
514 | { | ||
515 | int stat; | ||
516 | u8 buf[2]; | ||
517 | |||
518 | buf[0] = data >> 8; | ||
519 | buf[1] = data & 0xff; | ||
520 | stat = WriteEEProm(adapter, tag, 2, buf); | ||
521 | if (stat) | ||
522 | return stat; | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | static s16 osc_deviation(void *priv, s16 deviation, int flag) | ||
527 | { | ||
528 | struct ngene_channel *chan = priv; | ||
529 | struct i2c_adapter *adap = &chan->i2c_adapter; | ||
530 | u16 data = 0; | ||
531 | |||
532 | if (flag) { | ||
533 | data = (u16) deviation; | ||
534 | pr_info(DEVICE_NAME ": write deviation %d\n", | ||
535 | deviation); | ||
536 | eeprom_write_ushort(adap, 0x1000 + chan->number, data); | ||
537 | } else { | ||
538 | if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data)) | ||
539 | data = 0; | ||
540 | pr_info(DEVICE_NAME ": read deviation %d\n", | ||
541 | (s16) data); | ||
542 | } | ||
543 | |||
544 | return (s16) data; | ||
545 | } | ||
546 | |||
547 | /****************************************************************************/ | ||
548 | /* Switch control (I2C gates, etc.) *****************************************/ | ||
549 | /****************************************************************************/ | ||
550 | |||
551 | |||
552 | static struct stv090x_config fe_cineS2 = { | ||
553 | .device = STV0900, | ||
554 | .demod_mode = STV090x_DUAL, | ||
555 | .clk_mode = STV090x_CLK_EXT, | ||
556 | |||
557 | .xtal = 27000000, | ||
558 | .address = 0x68, | ||
559 | |||
560 | .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
561 | .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
562 | |||
563 | .repeater_level = STV090x_RPTLEVEL_16, | ||
564 | |||
565 | .adc1_range = STV090x_ADC_1Vpp, | ||
566 | .adc2_range = STV090x_ADC_1Vpp, | ||
567 | |||
568 | .diseqc_envelope_mode = true, | ||
569 | |||
570 | .tuner_i2c_lock = cineS2_tuner_i2c_lock, | ||
571 | }; | ||
572 | |||
573 | static struct stv090x_config fe_cineS2_2 = { | ||
574 | .device = STV0900, | ||
575 | .demod_mode = STV090x_DUAL, | ||
576 | .clk_mode = STV090x_CLK_EXT, | ||
577 | |||
578 | .xtal = 27000000, | ||
579 | .address = 0x69, | ||
580 | |||
581 | .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
582 | .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
583 | |||
584 | .repeater_level = STV090x_RPTLEVEL_16, | ||
585 | |||
586 | .adc1_range = STV090x_ADC_1Vpp, | ||
587 | .adc2_range = STV090x_ADC_1Vpp, | ||
588 | |||
589 | .diseqc_envelope_mode = true, | ||
590 | |||
591 | .tuner_i2c_lock = cineS2_tuner_i2c_lock, | ||
592 | }; | ||
593 | |||
594 | static struct stv6110x_config tuner_cineS2_0 = { | ||
595 | .addr = 0x60, | ||
596 | .refclk = 27000000, | ||
597 | .clk_div = 1, | ||
598 | }; | ||
599 | |||
600 | static struct stv6110x_config tuner_cineS2_1 = { | ||
601 | .addr = 0x63, | ||
602 | .refclk = 27000000, | ||
603 | .clk_div = 1, | ||
604 | }; | ||
605 | |||
606 | static struct ngene_info ngene_info_cineS2 = { | ||
607 | .type = NGENE_SIDEWINDER, | ||
608 | .name = "Linux4Media cineS2 DVB-S2 Twin Tuner", | ||
609 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
610 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
611 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
612 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
613 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
614 | .lnb = {0x0b, 0x08}, | ||
615 | .tsf = {3, 3}, | ||
616 | .fw_version = 18, | ||
617 | .msi_supported = true, | ||
618 | }; | ||
619 | |||
620 | static struct ngene_info ngene_info_satixS2 = { | ||
621 | .type = NGENE_SIDEWINDER, | ||
622 | .name = "Mystique SaTiX-S2 Dual", | ||
623 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
624 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
625 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
626 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
627 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
628 | .lnb = {0x0b, 0x08}, | ||
629 | .tsf = {3, 3}, | ||
630 | .fw_version = 18, | ||
631 | .msi_supported = true, | ||
632 | }; | ||
633 | |||
634 | static struct ngene_info ngene_info_satixS2v2 = { | ||
635 | .type = NGENE_SIDEWINDER, | ||
636 | .name = "Mystique SaTiX-S2 Dual (v2)", | ||
637 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, | ||
638 | NGENE_IO_TSOUT}, | ||
639 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe}, | ||
640 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe}, | ||
641 | .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, | ||
642 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, | ||
643 | .lnb = {0x0a, 0x08, 0x0b, 0x09}, | ||
644 | .tsf = {3, 3}, | ||
645 | .fw_version = 18, | ||
646 | .msi_supported = true, | ||
647 | }; | ||
648 | |||
649 | static struct ngene_info ngene_info_cineS2v5 = { | ||
650 | .type = NGENE_SIDEWINDER, | ||
651 | .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)", | ||
652 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, | ||
653 | NGENE_IO_TSOUT}, | ||
654 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe}, | ||
655 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe}, | ||
656 | .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, | ||
657 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, | ||
658 | .lnb = {0x0a, 0x08, 0x0b, 0x09}, | ||
659 | .tsf = {3, 3}, | ||
660 | .fw_version = 18, | ||
661 | .msi_supported = true, | ||
662 | }; | ||
663 | |||
664 | |||
665 | static struct ngene_info ngene_info_duoFlex = { | ||
666 | .type = NGENE_SIDEWINDER, | ||
667 | .name = "Digital Devices DuoFlex PCIe or miniPCIe", | ||
668 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, | ||
669 | NGENE_IO_TSOUT}, | ||
670 | .demod_attach = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe}, | ||
671 | .tuner_attach = {tuner_attach_probe, tuner_attach_probe, tuner_attach_probe, tuner_attach_probe}, | ||
672 | .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, | ||
673 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, | ||
674 | .lnb = {0x0a, 0x08, 0x0b, 0x09}, | ||
675 | .tsf = {3, 3}, | ||
676 | .fw_version = 18, | ||
677 | .msi_supported = true, | ||
678 | }; | ||
679 | |||
680 | static struct ngene_info ngene_info_m780 = { | ||
681 | .type = NGENE_APP, | ||
682 | .name = "Aver M780 ATSC/QAM-B", | ||
683 | |||
684 | /* Channel 0 is analog, which is currently unsupported */ | ||
685 | .io_type = { NGENE_IO_NONE, NGENE_IO_TSIN }, | ||
686 | .demod_attach = { NULL, demod_attach_lg330x }, | ||
687 | |||
688 | /* Ensure these are NULL else the frame will call them (as funcs) */ | ||
689 | .tuner_attach = { 0, 0, 0, 0 }, | ||
690 | .fe_config = { NULL, &aver_m780 }, | ||
691 | .avf = { 0 }, | ||
692 | |||
693 | /* A custom electrical interface config for the demod to bridge */ | ||
694 | .tsf = { 4, 4 }, | ||
695 | .fw_version = 15, | ||
696 | }; | ||
697 | |||
698 | static struct drxd_config fe_terratec_dvbt_0 = { | ||
699 | .index = 0, | ||
700 | .demod_address = 0x70, | ||
701 | .demod_revision = 0xa2, | ||
702 | .demoda_address = 0x00, | ||
703 | .pll_address = 0x60, | ||
704 | .pll_type = DVB_PLL_THOMSON_DTT7520X, | ||
705 | .clock = 20000, | ||
706 | .osc_deviation = osc_deviation, | ||
707 | }; | ||
708 | |||
709 | static struct drxd_config fe_terratec_dvbt_1 = { | ||
710 | .index = 1, | ||
711 | .demod_address = 0x71, | ||
712 | .demod_revision = 0xa2, | ||
713 | .demoda_address = 0x00, | ||
714 | .pll_address = 0x60, | ||
715 | .pll_type = DVB_PLL_THOMSON_DTT7520X, | ||
716 | .clock = 20000, | ||
717 | .osc_deviation = osc_deviation, | ||
718 | }; | ||
719 | |||
720 | static struct ngene_info ngene_info_terratec = { | ||
721 | .type = NGENE_TERRATEC, | ||
722 | .name = "Terratec Integra/Cinergy2400i Dual DVB-T", | ||
723 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
724 | .demod_attach = {demod_attach_drxd, demod_attach_drxd}, | ||
725 | .fe_config = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1}, | ||
726 | .i2c_access = 1, | ||
727 | }; | ||
728 | |||
729 | /****************************************************************************/ | ||
730 | |||
731 | |||
732 | |||
733 | /****************************************************************************/ | ||
734 | /* PCI Subsystem ID *********************************************************/ | ||
735 | /****************************************************************************/ | ||
736 | |||
737 | #define NGENE_ID(_subvend, _subdev, _driverdata) { \ | ||
738 | .vendor = NGENE_VID, .device = NGENE_PID, \ | ||
739 | .subvendor = _subvend, .subdevice = _subdev, \ | ||
740 | .driver_data = (unsigned long) &_driverdata } | ||
741 | |||
742 | /****************************************************************************/ | ||
743 | |||
744 | static const struct pci_device_id ngene_id_tbl[] __devinitdata = { | ||
745 | NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), | ||
746 | NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), | ||
747 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), | ||
748 | NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), | ||
749 | NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), | ||
750 | NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex), | ||
751 | NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex), | ||
752 | NGENE_ID(0x1461, 0x062e, ngene_info_m780), | ||
753 | NGENE_ID(0x153b, 0x1167, ngene_info_terratec), | ||
754 | {0} | ||
755 | }; | ||
756 | MODULE_DEVICE_TABLE(pci, ngene_id_tbl); | ||
757 | |||
758 | /****************************************************************************/ | ||
759 | /* Init/Exit ****************************************************************/ | ||
760 | /****************************************************************************/ | ||
761 | |||
762 | static pci_ers_result_t ngene_error_detected(struct pci_dev *dev, | ||
763 | enum pci_channel_state state) | ||
764 | { | ||
765 | printk(KERN_ERR DEVICE_NAME ": PCI error\n"); | ||
766 | if (state == pci_channel_io_perm_failure) | ||
767 | return PCI_ERS_RESULT_DISCONNECT; | ||
768 | if (state == pci_channel_io_frozen) | ||
769 | return PCI_ERS_RESULT_NEED_RESET; | ||
770 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
771 | } | ||
772 | |||
773 | static pci_ers_result_t ngene_link_reset(struct pci_dev *dev) | ||
774 | { | ||
775 | printk(KERN_INFO DEVICE_NAME ": link reset\n"); | ||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev) | ||
780 | { | ||
781 | printk(KERN_INFO DEVICE_NAME ": slot reset\n"); | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static void ngene_resume(struct pci_dev *dev) | ||
786 | { | ||
787 | printk(KERN_INFO DEVICE_NAME ": resume\n"); | ||
788 | } | ||
789 | |||
790 | static struct pci_error_handlers ngene_errors = { | ||
791 | .error_detected = ngene_error_detected, | ||
792 | .link_reset = ngene_link_reset, | ||
793 | .slot_reset = ngene_slot_reset, | ||
794 | .resume = ngene_resume, | ||
795 | }; | ||
796 | |||
797 | static struct pci_driver ngene_pci_driver = { | ||
798 | .name = "ngene", | ||
799 | .id_table = ngene_id_tbl, | ||
800 | .probe = ngene_probe, | ||
801 | .remove = __devexit_p(ngene_remove), | ||
802 | .err_handler = &ngene_errors, | ||
803 | .shutdown = ngene_shutdown, | ||
804 | }; | ||
805 | |||
806 | static __init int module_init_ngene(void) | ||
807 | { | ||
808 | printk(KERN_INFO | ||
809 | "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n"); | ||
810 | return pci_register_driver(&ngene_pci_driver); | ||
811 | } | ||
812 | |||
813 | static __exit void module_exit_ngene(void) | ||
814 | { | ||
815 | pci_unregister_driver(&ngene_pci_driver); | ||
816 | } | ||
817 | |||
818 | module_init(module_init_ngene); | ||
819 | module_exit(module_exit_ngene); | ||
820 | |||
821 | MODULE_DESCRIPTION("nGene"); | ||
822 | MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel"); | ||
823 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c deleted file mode 100644 index c8e0d5b99d4c..000000000000 --- a/drivers/media/dvb/ngene/ngene-core.c +++ /dev/null | |||
@@ -1,1707 +0,0 @@ | |||
1 | /* | ||
2 | * ngene.c: nGene PCIe bridge driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * Modifications for new nGene firmware, | ||
8 | * support for EEPROM-copying, | ||
9 | * support for new dual DVB-S2 card prototype | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * version 2 only, as published by the Free Software Foundation. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
26 | * 02110-1301, USA | ||
27 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/poll.h> | ||
34 | #include <linux/io.h> | ||
35 | #include <asm/div64.h> | ||
36 | #include <linux/pci.h> | ||
37 | #include <linux/timer.h> | ||
38 | #include <linux/byteorder/generic.h> | ||
39 | #include <linux/firmware.h> | ||
40 | #include <linux/vmalloc.h> | ||
41 | |||
42 | #include "ngene.h" | ||
43 | |||
44 | static int one_adapter; | ||
45 | module_param(one_adapter, int, 0444); | ||
46 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); | ||
47 | |||
48 | static int shutdown_workaround; | ||
49 | module_param(shutdown_workaround, int, 0644); | ||
50 | MODULE_PARM_DESC(shutdown_workaround, "Activate workaround for shutdown problem with some chipsets."); | ||
51 | |||
52 | static int debug; | ||
53 | module_param(debug, int, 0444); | ||
54 | MODULE_PARM_DESC(debug, "Print debugging information."); | ||
55 | |||
56 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
57 | |||
58 | #define dprintk if (debug) printk | ||
59 | |||
60 | #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) | ||
61 | #define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr))) | ||
62 | #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) | ||
63 | #define ngreadl(adr) readl(dev->iomem + (adr)) | ||
64 | #define ngreadb(adr) readb(dev->iomem + (adr)) | ||
65 | #define ngcpyto(adr, src, count) memcpy_toio((char *) \ | ||
66 | (dev->iomem + (adr)), (src), (count)) | ||
67 | #define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \ | ||
68 | (dev->iomem + (adr)), (count)) | ||
69 | |||
70 | /****************************************************************************/ | ||
71 | /* nGene interrupt handler **************************************************/ | ||
72 | /****************************************************************************/ | ||
73 | |||
74 | static void event_tasklet(unsigned long data) | ||
75 | { | ||
76 | struct ngene *dev = (struct ngene *)data; | ||
77 | |||
78 | while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) { | ||
79 | struct EVENT_BUFFER Event = | ||
80 | dev->EventQueue[dev->EventQueueReadIndex]; | ||
81 | dev->EventQueueReadIndex = | ||
82 | (dev->EventQueueReadIndex + 1) & (EVENT_QUEUE_SIZE - 1); | ||
83 | |||
84 | if ((Event.UARTStatus & 0x01) && (dev->TxEventNotify)) | ||
85 | dev->TxEventNotify(dev, Event.TimeStamp); | ||
86 | if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify)) | ||
87 | dev->RxEventNotify(dev, Event.TimeStamp, | ||
88 | Event.RXCharacter); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static void demux_tasklet(unsigned long data) | ||
93 | { | ||
94 | struct ngene_channel *chan = (struct ngene_channel *)data; | ||
95 | struct SBufferHeader *Cur = chan->nextBuffer; | ||
96 | |||
97 | spin_lock_irq(&chan->state_lock); | ||
98 | |||
99 | while (Cur->ngeneBuffer.SR.Flags & 0x80) { | ||
100 | if (chan->mode & NGENE_IO_TSOUT) { | ||
101 | u32 Flags = chan->DataFormatFlags; | ||
102 | if (Cur->ngeneBuffer.SR.Flags & 0x20) | ||
103 | Flags |= BEF_OVERFLOW; | ||
104 | if (chan->pBufferExchange) { | ||
105 | if (!chan->pBufferExchange(chan, | ||
106 | Cur->Buffer1, | ||
107 | chan->Capture1Length, | ||
108 | Cur->ngeneBuffer.SR. | ||
109 | Clock, Flags)) { | ||
110 | /* | ||
111 | We didn't get data | ||
112 | Clear in service flag to make sure we | ||
113 | get called on next interrupt again. | ||
114 | leave fill/empty (0x80) flag alone | ||
115 | to avoid hardware running out of | ||
116 | buffers during startup, we hold only | ||
117 | in run state ( the source may be late | ||
118 | delivering data ) | ||
119 | */ | ||
120 | |||
121 | if (chan->HWState == HWSTATE_RUN) { | ||
122 | Cur->ngeneBuffer.SR.Flags &= | ||
123 | ~0x40; | ||
124 | break; | ||
125 | /* Stop processing stream */ | ||
126 | } | ||
127 | } else { | ||
128 | /* We got a valid buffer, | ||
129 | so switch to run state */ | ||
130 | chan->HWState = HWSTATE_RUN; | ||
131 | } | ||
132 | } else { | ||
133 | printk(KERN_ERR DEVICE_NAME ": OOPS\n"); | ||
134 | if (chan->HWState == HWSTATE_RUN) { | ||
135 | Cur->ngeneBuffer.SR.Flags &= ~0x40; | ||
136 | break; /* Stop processing stream */ | ||
137 | } | ||
138 | } | ||
139 | if (chan->AudioDTOUpdated) { | ||
140 | printk(KERN_INFO DEVICE_NAME | ||
141 | ": Update AudioDTO = %d\n", | ||
142 | chan->AudioDTOValue); | ||
143 | Cur->ngeneBuffer.SR.DTOUpdate = | ||
144 | chan->AudioDTOValue; | ||
145 | chan->AudioDTOUpdated = 0; | ||
146 | } | ||
147 | } else { | ||
148 | if (chan->HWState == HWSTATE_RUN) { | ||
149 | u32 Flags = chan->DataFormatFlags; | ||
150 | IBufferExchange *exch1 = chan->pBufferExchange; | ||
151 | IBufferExchange *exch2 = chan->pBufferExchange2; | ||
152 | if (Cur->ngeneBuffer.SR.Flags & 0x01) | ||
153 | Flags |= BEF_EVEN_FIELD; | ||
154 | if (Cur->ngeneBuffer.SR.Flags & 0x20) | ||
155 | Flags |= BEF_OVERFLOW; | ||
156 | spin_unlock_irq(&chan->state_lock); | ||
157 | if (exch1) | ||
158 | exch1(chan, Cur->Buffer1, | ||
159 | chan->Capture1Length, | ||
160 | Cur->ngeneBuffer.SR.Clock, | ||
161 | Flags); | ||
162 | if (exch2) | ||
163 | exch2(chan, Cur->Buffer2, | ||
164 | chan->Capture2Length, | ||
165 | Cur->ngeneBuffer.SR.Clock, | ||
166 | Flags); | ||
167 | spin_lock_irq(&chan->state_lock); | ||
168 | } else if (chan->HWState != HWSTATE_STOP) | ||
169 | chan->HWState = HWSTATE_RUN; | ||
170 | } | ||
171 | Cur->ngeneBuffer.SR.Flags = 0x00; | ||
172 | Cur = Cur->Next; | ||
173 | } | ||
174 | chan->nextBuffer = Cur; | ||
175 | |||
176 | spin_unlock_irq(&chan->state_lock); | ||
177 | } | ||
178 | |||
179 | static irqreturn_t irq_handler(int irq, void *dev_id) | ||
180 | { | ||
181 | struct ngene *dev = (struct ngene *)dev_id; | ||
182 | u32 icounts = 0; | ||
183 | irqreturn_t rc = IRQ_NONE; | ||
184 | u32 i = MAX_STREAM; | ||
185 | u8 *tmpCmdDoneByte; | ||
186 | |||
187 | if (dev->BootFirmware) { | ||
188 | icounts = ngreadl(NGENE_INT_COUNTS); | ||
189 | if (icounts != dev->icounts) { | ||
190 | ngwritel(0, FORCE_NMI); | ||
191 | dev->cmd_done = 1; | ||
192 | wake_up(&dev->cmd_wq); | ||
193 | dev->icounts = icounts; | ||
194 | rc = IRQ_HANDLED; | ||
195 | } | ||
196 | return rc; | ||
197 | } | ||
198 | |||
199 | ngwritel(0, FORCE_NMI); | ||
200 | |||
201 | spin_lock(&dev->cmd_lock); | ||
202 | tmpCmdDoneByte = dev->CmdDoneByte; | ||
203 | if (tmpCmdDoneByte && | ||
204 | (*tmpCmdDoneByte || | ||
205 | (dev->ngenetohost[0] == 1 && dev->ngenetohost[1] != 0))) { | ||
206 | dev->CmdDoneByte = NULL; | ||
207 | dev->cmd_done = 1; | ||
208 | wake_up(&dev->cmd_wq); | ||
209 | rc = IRQ_HANDLED; | ||
210 | } | ||
211 | spin_unlock(&dev->cmd_lock); | ||
212 | |||
213 | if (dev->EventBuffer->EventStatus & 0x80) { | ||
214 | u8 nextWriteIndex = | ||
215 | (dev->EventQueueWriteIndex + 1) & | ||
216 | (EVENT_QUEUE_SIZE - 1); | ||
217 | if (nextWriteIndex != dev->EventQueueReadIndex) { | ||
218 | dev->EventQueue[dev->EventQueueWriteIndex] = | ||
219 | *(dev->EventBuffer); | ||
220 | dev->EventQueueWriteIndex = nextWriteIndex; | ||
221 | } else { | ||
222 | printk(KERN_ERR DEVICE_NAME ": event overflow\n"); | ||
223 | dev->EventQueueOverflowCount += 1; | ||
224 | dev->EventQueueOverflowFlag = 1; | ||
225 | } | ||
226 | dev->EventBuffer->EventStatus &= ~0x80; | ||
227 | tasklet_schedule(&dev->event_tasklet); | ||
228 | rc = IRQ_HANDLED; | ||
229 | } | ||
230 | |||
231 | while (i > 0) { | ||
232 | i--; | ||
233 | spin_lock(&dev->channel[i].state_lock); | ||
234 | /* if (dev->channel[i].State>=KSSTATE_RUN) { */ | ||
235 | if (dev->channel[i].nextBuffer) { | ||
236 | if ((dev->channel[i].nextBuffer-> | ||
237 | ngeneBuffer.SR.Flags & 0xC0) == 0x80) { | ||
238 | dev->channel[i].nextBuffer-> | ||
239 | ngeneBuffer.SR.Flags |= 0x40; | ||
240 | tasklet_schedule( | ||
241 | &dev->channel[i].demux_tasklet); | ||
242 | rc = IRQ_HANDLED; | ||
243 | } | ||
244 | } | ||
245 | spin_unlock(&dev->channel[i].state_lock); | ||
246 | } | ||
247 | |||
248 | /* Request might have been processed by a previous call. */ | ||
249 | return IRQ_HANDLED; | ||
250 | } | ||
251 | |||
252 | /****************************************************************************/ | ||
253 | /* nGene command interface **************************************************/ | ||
254 | /****************************************************************************/ | ||
255 | |||
256 | static void dump_command_io(struct ngene *dev) | ||
257 | { | ||
258 | u8 buf[8], *b; | ||
259 | |||
260 | ngcpyfrom(buf, HOST_TO_NGENE, 8); | ||
261 | printk(KERN_ERR "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf); | ||
262 | |||
263 | ngcpyfrom(buf, NGENE_TO_HOST, 8); | ||
264 | printk(KERN_ERR "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf); | ||
265 | |||
266 | b = dev->hosttongene; | ||
267 | printk(KERN_ERR "dev->hosttongene (%p): %*ph\n", b, 8, b); | ||
268 | |||
269 | b = dev->ngenetohost; | ||
270 | printk(KERN_ERR "dev->ngenetohost (%p): %*ph\n", b, 8, b); | ||
271 | } | ||
272 | |||
273 | static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) | ||
274 | { | ||
275 | int ret; | ||
276 | u8 *tmpCmdDoneByte; | ||
277 | |||
278 | dev->cmd_done = 0; | ||
279 | |||
280 | if (com->cmd.hdr.Opcode == CMD_FWLOAD_PREPARE) { | ||
281 | dev->BootFirmware = 1; | ||
282 | dev->icounts = ngreadl(NGENE_INT_COUNTS); | ||
283 | ngwritel(0, NGENE_COMMAND); | ||
284 | ngwritel(0, NGENE_COMMAND_HI); | ||
285 | ngwritel(0, NGENE_STATUS); | ||
286 | ngwritel(0, NGENE_STATUS_HI); | ||
287 | ngwritel(0, NGENE_EVENT); | ||
288 | ngwritel(0, NGENE_EVENT_HI); | ||
289 | } else if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) { | ||
290 | u64 fwio = dev->PAFWInterfaceBuffer; | ||
291 | |||
292 | ngwritel(fwio & 0xffffffff, NGENE_COMMAND); | ||
293 | ngwritel(fwio >> 32, NGENE_COMMAND_HI); | ||
294 | ngwritel((fwio + 256) & 0xffffffff, NGENE_STATUS); | ||
295 | ngwritel((fwio + 256) >> 32, NGENE_STATUS_HI); | ||
296 | ngwritel((fwio + 512) & 0xffffffff, NGENE_EVENT); | ||
297 | ngwritel((fwio + 512) >> 32, NGENE_EVENT_HI); | ||
298 | } | ||
299 | |||
300 | memcpy(dev->FWInterfaceBuffer, com->cmd.raw8, com->in_len + 2); | ||
301 | |||
302 | if (dev->BootFirmware) | ||
303 | ngcpyto(HOST_TO_NGENE, com->cmd.raw8, com->in_len + 2); | ||
304 | |||
305 | spin_lock_irq(&dev->cmd_lock); | ||
306 | tmpCmdDoneByte = dev->ngenetohost + com->out_len; | ||
307 | if (!com->out_len) | ||
308 | tmpCmdDoneByte++; | ||
309 | *tmpCmdDoneByte = 0; | ||
310 | dev->ngenetohost[0] = 0; | ||
311 | dev->ngenetohost[1] = 0; | ||
312 | dev->CmdDoneByte = tmpCmdDoneByte; | ||
313 | spin_unlock_irq(&dev->cmd_lock); | ||
314 | |||
315 | /* Notify 8051. */ | ||
316 | ngwritel(1, FORCE_INT); | ||
317 | |||
318 | ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ); | ||
319 | if (!ret) { | ||
320 | /*ngwritel(0, FORCE_NMI);*/ | ||
321 | |||
322 | printk(KERN_ERR DEVICE_NAME | ||
323 | ": Command timeout cmd=%02x prev=%02x\n", | ||
324 | com->cmd.hdr.Opcode, dev->prev_cmd); | ||
325 | dump_command_io(dev); | ||
326 | return -1; | ||
327 | } | ||
328 | if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) | ||
329 | dev->BootFirmware = 0; | ||
330 | |||
331 | dev->prev_cmd = com->cmd.hdr.Opcode; | ||
332 | |||
333 | if (!com->out_len) | ||
334 | return 0; | ||
335 | |||
336 | memcpy(com->cmd.raw8, dev->ngenetohost, com->out_len); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | int ngene_command(struct ngene *dev, struct ngene_command *com) | ||
342 | { | ||
343 | int result; | ||
344 | |||
345 | down(&dev->cmd_mutex); | ||
346 | result = ngene_command_mutex(dev, com); | ||
347 | up(&dev->cmd_mutex); | ||
348 | return result; | ||
349 | } | ||
350 | |||
351 | |||
352 | static int ngene_command_load_firmware(struct ngene *dev, | ||
353 | u8 *ngene_fw, u32 size) | ||
354 | { | ||
355 | #define FIRSTCHUNK (1024) | ||
356 | u32 cleft; | ||
357 | struct ngene_command com; | ||
358 | |||
359 | com.cmd.hdr.Opcode = CMD_FWLOAD_PREPARE; | ||
360 | com.cmd.hdr.Length = 0; | ||
361 | com.in_len = 0; | ||
362 | com.out_len = 0; | ||
363 | |||
364 | ngene_command(dev, &com); | ||
365 | |||
366 | cleft = (size + 3) & ~3; | ||
367 | if (cleft > FIRSTCHUNK) { | ||
368 | ngcpyto(PROGRAM_SRAM + FIRSTCHUNK, ngene_fw + FIRSTCHUNK, | ||
369 | cleft - FIRSTCHUNK); | ||
370 | cleft = FIRSTCHUNK; | ||
371 | } | ||
372 | ngcpyto(DATA_FIFO_AREA, ngene_fw, cleft); | ||
373 | |||
374 | memset(&com, 0, sizeof(struct ngene_command)); | ||
375 | com.cmd.hdr.Opcode = CMD_FWLOAD_FINISH; | ||
376 | com.cmd.hdr.Length = 4; | ||
377 | com.cmd.FWLoadFinish.Address = DATA_FIFO_AREA; | ||
378 | com.cmd.FWLoadFinish.Length = (unsigned short)cleft; | ||
379 | com.in_len = 4; | ||
380 | com.out_len = 0; | ||
381 | |||
382 | return ngene_command(dev, &com); | ||
383 | } | ||
384 | |||
385 | |||
386 | static int ngene_command_config_buf(struct ngene *dev, u8 config) | ||
387 | { | ||
388 | struct ngene_command com; | ||
389 | |||
390 | com.cmd.hdr.Opcode = CMD_CONFIGURE_BUFFER; | ||
391 | com.cmd.hdr.Length = 1; | ||
392 | com.cmd.ConfigureBuffers.config = config; | ||
393 | com.in_len = 1; | ||
394 | com.out_len = 0; | ||
395 | |||
396 | if (ngene_command(dev, &com) < 0) | ||
397 | return -EIO; | ||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static int ngene_command_config_free_buf(struct ngene *dev, u8 *config) | ||
402 | { | ||
403 | struct ngene_command com; | ||
404 | |||
405 | com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER; | ||
406 | com.cmd.hdr.Length = 6; | ||
407 | memcpy(&com.cmd.ConfigureBuffers.config, config, 6); | ||
408 | com.in_len = 6; | ||
409 | com.out_len = 0; | ||
410 | |||
411 | if (ngene_command(dev, &com) < 0) | ||
412 | return -EIO; | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level) | ||
418 | { | ||
419 | struct ngene_command com; | ||
420 | |||
421 | com.cmd.hdr.Opcode = CMD_SET_GPIO_PIN; | ||
422 | com.cmd.hdr.Length = 1; | ||
423 | com.cmd.SetGpioPin.select = select | (level << 7); | ||
424 | com.in_len = 1; | ||
425 | com.out_len = 0; | ||
426 | |||
427 | return ngene_command(dev, &com); | ||
428 | } | ||
429 | |||
430 | |||
431 | /* | ||
432 | 02000640 is sample on rising edge. | ||
433 | 02000740 is sample on falling edge. | ||
434 | 02000040 is ignore "valid" signal | ||
435 | |||
436 | 0: FD_CTL1 Bit 7,6 must be 0,1 | ||
437 | 7 disable(fw controlled) | ||
438 | 6 0-AUX,1-TS | ||
439 | 5 0-par,1-ser | ||
440 | 4 0-lsb/1-msb | ||
441 | 3,2 reserved | ||
442 | 1,0 0-no sync, 1-use ext. start, 2-use 0x47, 3-both | ||
443 | 1: FD_CTL2 has 3-valid must be hi, 2-use valid, 1-edge | ||
444 | 2: FD_STA is read-only. 0-sync | ||
445 | 3: FD_INSYNC is number of 47s to trigger "in sync". | ||
446 | 4: FD_OUTSYNC is number of 47s to trigger "out of sync". | ||
447 | 5: FD_MAXBYTE1 is low-order of bytes per packet. | ||
448 | 6: FD_MAXBYTE2 is high-order of bytes per packet. | ||
449 | 7: Top byte is unused. | ||
450 | */ | ||
451 | |||
452 | /****************************************************************************/ | ||
453 | |||
454 | static u8 TSFeatureDecoderSetup[8 * 5] = { | ||
455 | 0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, | ||
456 | 0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */ | ||
457 | 0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */ | ||
458 | 0x72, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */ | ||
459 | 0x40, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* LGDT3303 */ | ||
460 | }; | ||
461 | |||
462 | /* Set NGENE I2S Config to 16 bit packed */ | ||
463 | static u8 I2SConfiguration[] = { | ||
464 | 0x00, 0x10, 0x00, 0x00, | ||
465 | 0x80, 0x10, 0x00, 0x00, | ||
466 | }; | ||
467 | |||
468 | static u8 SPDIFConfiguration[10] = { | ||
469 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
470 | }; | ||
471 | |||
472 | /* Set NGENE I2S Config to transport stream compatible mode */ | ||
473 | |||
474 | static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 }; | ||
475 | |||
476 | static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x04, 0x00, 0x00 }; | ||
477 | |||
478 | static u8 ITUDecoderSetup[4][16] = { | ||
479 | {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ | ||
480 | 0x00, 0x00, 0x01, 0xb0, 0x9c, 0x00, 0x00, 0x00}, | ||
481 | {0x9c, 0x03, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00, | ||
482 | 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00}, | ||
483 | {0x9f, 0x00, 0x23, 0xC0, 0x60, 0x0F, 0x13, 0x00, /* HDTV 1080i50 */ | ||
484 | 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00}, | ||
485 | {0x9c, 0x01, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00, /* HDTV 1080i60 */ | ||
486 | 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00}, | ||
487 | }; | ||
488 | |||
489 | /* | ||
490 | * 50 48 60 gleich | ||
491 | * 27p50 9f 00 22 80 42 69 18 ... | ||
492 | * 27p60 93 00 22 80 82 69 1c ... | ||
493 | */ | ||
494 | |||
495 | /* Maxbyte to 1144 (for raw data) */ | ||
496 | static u8 ITUFeatureDecoderSetup[8] = { | ||
497 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00 | ||
498 | }; | ||
499 | |||
500 | void FillTSBuffer(void *Buffer, int Length, u32 Flags) | ||
501 | { | ||
502 | u32 *ptr = Buffer; | ||
503 | |||
504 | memset(Buffer, TS_FILLER, Length); | ||
505 | while (Length > 0) { | ||
506 | if (Flags & DF_SWAP32) | ||
507 | *ptr = 0x471FFF10; | ||
508 | else | ||
509 | *ptr = 0x10FF1F47; | ||
510 | ptr += (188 / 4); | ||
511 | Length -= 188; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | |||
516 | static void flush_buffers(struct ngene_channel *chan) | ||
517 | { | ||
518 | u8 val; | ||
519 | |||
520 | do { | ||
521 | msleep(1); | ||
522 | spin_lock_irq(&chan->state_lock); | ||
523 | val = chan->nextBuffer->ngeneBuffer.SR.Flags & 0x80; | ||
524 | spin_unlock_irq(&chan->state_lock); | ||
525 | } while (val); | ||
526 | } | ||
527 | |||
528 | static void clear_buffers(struct ngene_channel *chan) | ||
529 | { | ||
530 | struct SBufferHeader *Cur = chan->nextBuffer; | ||
531 | |||
532 | do { | ||
533 | memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR)); | ||
534 | if (chan->mode & NGENE_IO_TSOUT) | ||
535 | FillTSBuffer(Cur->Buffer1, | ||
536 | chan->Capture1Length, | ||
537 | chan->DataFormatFlags); | ||
538 | Cur = Cur->Next; | ||
539 | } while (Cur != chan->nextBuffer); | ||
540 | |||
541 | if (chan->mode & NGENE_IO_TSOUT) { | ||
542 | chan->nextBuffer->ngeneBuffer.SR.DTOUpdate = | ||
543 | chan->AudioDTOValue; | ||
544 | chan->AudioDTOUpdated = 0; | ||
545 | |||
546 | Cur = chan->TSIdleBuffer.Head; | ||
547 | |||
548 | do { | ||
549 | memset(&Cur->ngeneBuffer.SR, 0, | ||
550 | sizeof(Cur->ngeneBuffer.SR)); | ||
551 | FillTSBuffer(Cur->Buffer1, | ||
552 | chan->Capture1Length, | ||
553 | chan->DataFormatFlags); | ||
554 | Cur = Cur->Next; | ||
555 | } while (Cur != chan->TSIdleBuffer.Head); | ||
556 | } | ||
557 | } | ||
558 | |||
559 | static int ngene_command_stream_control(struct ngene *dev, u8 stream, | ||
560 | u8 control, u8 mode, u8 flags) | ||
561 | { | ||
562 | struct ngene_channel *chan = &dev->channel[stream]; | ||
563 | struct ngene_command com; | ||
564 | u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300); | ||
565 | u16 BsSDI = ((stream & 1) ? 0x9600 : 0x9500); | ||
566 | u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); | ||
567 | u16 BsSDO = 0x9B00; | ||
568 | |||
569 | down(&dev->stream_mutex); | ||
570 | memset(&com, 0, sizeof(com)); | ||
571 | com.cmd.hdr.Opcode = CMD_CONTROL; | ||
572 | com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; | ||
573 | com.cmd.StreamControl.Stream = stream | (control ? 8 : 0); | ||
574 | if (chan->mode & NGENE_IO_TSOUT) | ||
575 | com.cmd.StreamControl.Stream |= 0x07; | ||
576 | com.cmd.StreamControl.Control = control | | ||
577 | (flags & SFLAG_ORDER_LUMA_CHROMA); | ||
578 | com.cmd.StreamControl.Mode = mode; | ||
579 | com.in_len = sizeof(struct FW_STREAM_CONTROL); | ||
580 | com.out_len = 0; | ||
581 | |||
582 | dprintk(KERN_INFO DEVICE_NAME | ||
583 | ": Stream=%02x, Control=%02x, Mode=%02x\n", | ||
584 | com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control, | ||
585 | com.cmd.StreamControl.Mode); | ||
586 | |||
587 | chan->Mode = mode; | ||
588 | |||
589 | if (!(control & 0x80)) { | ||
590 | spin_lock_irq(&chan->state_lock); | ||
591 | if (chan->State == KSSTATE_RUN) { | ||
592 | chan->State = KSSTATE_ACQUIRE; | ||
593 | chan->HWState = HWSTATE_STOP; | ||
594 | spin_unlock_irq(&chan->state_lock); | ||
595 | if (ngene_command(dev, &com) < 0) { | ||
596 | up(&dev->stream_mutex); | ||
597 | return -1; | ||
598 | } | ||
599 | /* clear_buffers(chan); */ | ||
600 | flush_buffers(chan); | ||
601 | up(&dev->stream_mutex); | ||
602 | return 0; | ||
603 | } | ||
604 | spin_unlock_irq(&chan->state_lock); | ||
605 | up(&dev->stream_mutex); | ||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | if (mode & SMODE_AUDIO_CAPTURE) { | ||
610 | com.cmd.StreamControl.CaptureBlockCount = | ||
611 | chan->Capture1Length / AUDIO_BLOCK_SIZE; | ||
612 | com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead; | ||
613 | } else if (mode & SMODE_TRANSPORT_STREAM) { | ||
614 | com.cmd.StreamControl.CaptureBlockCount = | ||
615 | chan->Capture1Length / TS_BLOCK_SIZE; | ||
616 | com.cmd.StreamControl.MaxLinesPerField = | ||
617 | chan->Capture1Length / TS_BLOCK_SIZE; | ||
618 | com.cmd.StreamControl.Buffer_Address = | ||
619 | chan->TSRingBuffer.PAHead; | ||
620 | if (chan->mode & NGENE_IO_TSOUT) { | ||
621 | com.cmd.StreamControl.BytesPerVBILine = | ||
622 | chan->Capture1Length / TS_BLOCK_SIZE; | ||
623 | com.cmd.StreamControl.Stream |= 0x07; | ||
624 | } | ||
625 | } else { | ||
626 | com.cmd.StreamControl.BytesPerVideoLine = chan->nBytesPerLine; | ||
627 | com.cmd.StreamControl.MaxLinesPerField = chan->nLines; | ||
628 | com.cmd.StreamControl.MinLinesPerField = 100; | ||
629 | com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead; | ||
630 | |||
631 | if (mode & SMODE_VBI_CAPTURE) { | ||
632 | com.cmd.StreamControl.MaxVBILinesPerField = | ||
633 | chan->nVBILines; | ||
634 | com.cmd.StreamControl.MinVBILinesPerField = 0; | ||
635 | com.cmd.StreamControl.BytesPerVBILine = | ||
636 | chan->nBytesPerVBILine; | ||
637 | } | ||
638 | if (flags & SFLAG_COLORBAR) | ||
639 | com.cmd.StreamControl.Stream |= 0x04; | ||
640 | } | ||
641 | |||
642 | spin_lock_irq(&chan->state_lock); | ||
643 | if (mode & SMODE_AUDIO_CAPTURE) { | ||
644 | chan->nextBuffer = chan->RingBuffer.Head; | ||
645 | if (mode & SMODE_AUDIO_SPDIF) { | ||
646 | com.cmd.StreamControl.SetupDataLen = | ||
647 | sizeof(SPDIFConfiguration); | ||
648 | com.cmd.StreamControl.SetupDataAddr = BsSPI; | ||
649 | memcpy(com.cmd.StreamControl.SetupData, | ||
650 | SPDIFConfiguration, sizeof(SPDIFConfiguration)); | ||
651 | } else { | ||
652 | com.cmd.StreamControl.SetupDataLen = 4; | ||
653 | com.cmd.StreamControl.SetupDataAddr = BsSDI; | ||
654 | memcpy(com.cmd.StreamControl.SetupData, | ||
655 | I2SConfiguration + | ||
656 | 4 * dev->card_info->i2s[stream], 4); | ||
657 | } | ||
658 | } else if (mode & SMODE_TRANSPORT_STREAM) { | ||
659 | chan->nextBuffer = chan->TSRingBuffer.Head; | ||
660 | if (stream >= STREAM_AUDIOIN1) { | ||
661 | if (chan->mode & NGENE_IO_TSOUT) { | ||
662 | com.cmd.StreamControl.SetupDataLen = | ||
663 | sizeof(TS_I2SOutConfiguration); | ||
664 | com.cmd.StreamControl.SetupDataAddr = BsSDO; | ||
665 | memcpy(com.cmd.StreamControl.SetupData, | ||
666 | TS_I2SOutConfiguration, | ||
667 | sizeof(TS_I2SOutConfiguration)); | ||
668 | } else { | ||
669 | com.cmd.StreamControl.SetupDataLen = | ||
670 | sizeof(TS_I2SConfiguration); | ||
671 | com.cmd.StreamControl.SetupDataAddr = BsSDI; | ||
672 | memcpy(com.cmd.StreamControl.SetupData, | ||
673 | TS_I2SConfiguration, | ||
674 | sizeof(TS_I2SConfiguration)); | ||
675 | } | ||
676 | } else { | ||
677 | com.cmd.StreamControl.SetupDataLen = 8; | ||
678 | com.cmd.StreamControl.SetupDataAddr = BsUVI + 0x10; | ||
679 | memcpy(com.cmd.StreamControl.SetupData, | ||
680 | TSFeatureDecoderSetup + | ||
681 | 8 * dev->card_info->tsf[stream], 8); | ||
682 | } | ||
683 | } else { | ||
684 | chan->nextBuffer = chan->RingBuffer.Head; | ||
685 | com.cmd.StreamControl.SetupDataLen = | ||
686 | 16 + sizeof(ITUFeatureDecoderSetup); | ||
687 | com.cmd.StreamControl.SetupDataAddr = BsUVI; | ||
688 | memcpy(com.cmd.StreamControl.SetupData, | ||
689 | ITUDecoderSetup[chan->itumode], 16); | ||
690 | memcpy(com.cmd.StreamControl.SetupData + 16, | ||
691 | ITUFeatureDecoderSetup, sizeof(ITUFeatureDecoderSetup)); | ||
692 | } | ||
693 | clear_buffers(chan); | ||
694 | chan->State = KSSTATE_RUN; | ||
695 | if (mode & SMODE_TRANSPORT_STREAM) | ||
696 | chan->HWState = HWSTATE_RUN; | ||
697 | else | ||
698 | chan->HWState = HWSTATE_STARTUP; | ||
699 | spin_unlock_irq(&chan->state_lock); | ||
700 | |||
701 | if (ngene_command(dev, &com) < 0) { | ||
702 | up(&dev->stream_mutex); | ||
703 | return -1; | ||
704 | } | ||
705 | up(&dev->stream_mutex); | ||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | void set_transfer(struct ngene_channel *chan, int state) | ||
710 | { | ||
711 | u8 control = 0, mode = 0, flags = 0; | ||
712 | struct ngene *dev = chan->dev; | ||
713 | int ret; | ||
714 | |||
715 | /* | ||
716 | printk(KERN_INFO DEVICE_NAME ": st %d\n", state); | ||
717 | msleep(100); | ||
718 | */ | ||
719 | |||
720 | if (state) { | ||
721 | if (chan->running) { | ||
722 | printk(KERN_INFO DEVICE_NAME ": already running\n"); | ||
723 | return; | ||
724 | } | ||
725 | } else { | ||
726 | if (!chan->running) { | ||
727 | printk(KERN_INFO DEVICE_NAME ": already stopped\n"); | ||
728 | return; | ||
729 | } | ||
730 | } | ||
731 | |||
732 | if (dev->card_info->switch_ctrl) | ||
733 | dev->card_info->switch_ctrl(chan, 1, state ^ 1); | ||
734 | |||
735 | if (state) { | ||
736 | spin_lock_irq(&chan->state_lock); | ||
737 | |||
738 | /* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | ||
739 | ngreadl(0x9310)); */ | ||
740 | dvb_ringbuffer_flush(&dev->tsout_rbuf); | ||
741 | control = 0x80; | ||
742 | if (chan->mode & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | ||
743 | chan->Capture1Length = 512 * 188; | ||
744 | mode = SMODE_TRANSPORT_STREAM; | ||
745 | } | ||
746 | if (chan->mode & NGENE_IO_TSOUT) { | ||
747 | chan->pBufferExchange = tsout_exchange; | ||
748 | /* 0x66666666 = 50MHz *2^33 /250MHz */ | ||
749 | chan->AudioDTOValue = 0x80000000; | ||
750 | chan->AudioDTOUpdated = 1; | ||
751 | } | ||
752 | if (chan->mode & NGENE_IO_TSIN) | ||
753 | chan->pBufferExchange = tsin_exchange; | ||
754 | spin_unlock_irq(&chan->state_lock); | ||
755 | } else | ||
756 | ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | ||
757 | ngreadl(0x9310)); */ | ||
758 | |||
759 | ret = ngene_command_stream_control(dev, chan->number, | ||
760 | control, mode, flags); | ||
761 | if (!ret) | ||
762 | chan->running = state; | ||
763 | else | ||
764 | printk(KERN_ERR DEVICE_NAME ": set_transfer %d failed\n", | ||
765 | state); | ||
766 | if (!state) { | ||
767 | spin_lock_irq(&chan->state_lock); | ||
768 | chan->pBufferExchange = NULL; | ||
769 | dvb_ringbuffer_flush(&dev->tsout_rbuf); | ||
770 | spin_unlock_irq(&chan->state_lock); | ||
771 | } | ||
772 | } | ||
773 | |||
774 | |||
775 | /****************************************************************************/ | ||
776 | /* nGene hardware init and release functions ********************************/ | ||
777 | /****************************************************************************/ | ||
778 | |||
779 | static void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb) | ||
780 | { | ||
781 | struct SBufferHeader *Cur = rb->Head; | ||
782 | u32 j; | ||
783 | |||
784 | if (!Cur) | ||
785 | return; | ||
786 | |||
787 | for (j = 0; j < rb->NumBuffers; j++, Cur = Cur->Next) { | ||
788 | if (Cur->Buffer1) | ||
789 | pci_free_consistent(dev->pci_dev, | ||
790 | rb->Buffer1Length, | ||
791 | Cur->Buffer1, | ||
792 | Cur->scList1->Address); | ||
793 | |||
794 | if (Cur->Buffer2) | ||
795 | pci_free_consistent(dev->pci_dev, | ||
796 | rb->Buffer2Length, | ||
797 | Cur->Buffer2, | ||
798 | Cur->scList2->Address); | ||
799 | } | ||
800 | |||
801 | if (rb->SCListMem) | ||
802 | pci_free_consistent(dev->pci_dev, rb->SCListMemSize, | ||
803 | rb->SCListMem, rb->PASCListMem); | ||
804 | |||
805 | pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead); | ||
806 | } | ||
807 | |||
808 | static void free_idlebuffer(struct ngene *dev, | ||
809 | struct SRingBufferDescriptor *rb, | ||
810 | struct SRingBufferDescriptor *tb) | ||
811 | { | ||
812 | int j; | ||
813 | struct SBufferHeader *Cur = tb->Head; | ||
814 | |||
815 | if (!rb->Head) | ||
816 | return; | ||
817 | free_ringbuffer(dev, rb); | ||
818 | for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) { | ||
819 | Cur->Buffer2 = NULL; | ||
820 | Cur->scList2 = NULL; | ||
821 | Cur->ngeneBuffer.Address_of_first_entry_2 = 0; | ||
822 | Cur->ngeneBuffer.Number_of_entries_2 = 0; | ||
823 | } | ||
824 | } | ||
825 | |||
826 | static void free_common_buffers(struct ngene *dev) | ||
827 | { | ||
828 | u32 i; | ||
829 | struct ngene_channel *chan; | ||
830 | |||
831 | for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) { | ||
832 | chan = &dev->channel[i]; | ||
833 | free_idlebuffer(dev, &chan->TSIdleBuffer, &chan->TSRingBuffer); | ||
834 | free_ringbuffer(dev, &chan->RingBuffer); | ||
835 | free_ringbuffer(dev, &chan->TSRingBuffer); | ||
836 | } | ||
837 | |||
838 | if (dev->OverflowBuffer) | ||
839 | pci_free_consistent(dev->pci_dev, | ||
840 | OVERFLOW_BUFFER_SIZE, | ||
841 | dev->OverflowBuffer, dev->PAOverflowBuffer); | ||
842 | |||
843 | if (dev->FWInterfaceBuffer) | ||
844 | pci_free_consistent(dev->pci_dev, | ||
845 | 4096, | ||
846 | dev->FWInterfaceBuffer, | ||
847 | dev->PAFWInterfaceBuffer); | ||
848 | } | ||
849 | |||
850 | /****************************************************************************/ | ||
851 | /* Ring buffer handling *****************************************************/ | ||
852 | /****************************************************************************/ | ||
853 | |||
854 | static int create_ring_buffer(struct pci_dev *pci_dev, | ||
855 | struct SRingBufferDescriptor *descr, u32 NumBuffers) | ||
856 | { | ||
857 | dma_addr_t tmp; | ||
858 | struct SBufferHeader *Head; | ||
859 | u32 i; | ||
860 | u32 MemSize = SIZEOF_SBufferHeader * NumBuffers; | ||
861 | u64 PARingBufferHead; | ||
862 | u64 PARingBufferCur; | ||
863 | u64 PARingBufferNext; | ||
864 | struct SBufferHeader *Cur, *Next; | ||
865 | |||
866 | descr->Head = NULL; | ||
867 | descr->MemSize = 0; | ||
868 | descr->PAHead = 0; | ||
869 | descr->NumBuffers = 0; | ||
870 | |||
871 | if (MemSize < 4096) | ||
872 | MemSize = 4096; | ||
873 | |||
874 | Head = pci_alloc_consistent(pci_dev, MemSize, &tmp); | ||
875 | PARingBufferHead = tmp; | ||
876 | |||
877 | if (!Head) | ||
878 | return -ENOMEM; | ||
879 | |||
880 | memset(Head, 0, MemSize); | ||
881 | |||
882 | PARingBufferCur = PARingBufferHead; | ||
883 | Cur = Head; | ||
884 | |||
885 | for (i = 0; i < NumBuffers - 1; i++) { | ||
886 | Next = (struct SBufferHeader *) | ||
887 | (((u8 *) Cur) + SIZEOF_SBufferHeader); | ||
888 | PARingBufferNext = PARingBufferCur + SIZEOF_SBufferHeader; | ||
889 | Cur->Next = Next; | ||
890 | Cur->ngeneBuffer.Next = PARingBufferNext; | ||
891 | Cur = Next; | ||
892 | PARingBufferCur = PARingBufferNext; | ||
893 | } | ||
894 | /* Last Buffer points back to first one */ | ||
895 | Cur->Next = Head; | ||
896 | Cur->ngeneBuffer.Next = PARingBufferHead; | ||
897 | |||
898 | descr->Head = Head; | ||
899 | descr->MemSize = MemSize; | ||
900 | descr->PAHead = PARingBufferHead; | ||
901 | descr->NumBuffers = NumBuffers; | ||
902 | |||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | static int AllocateRingBuffers(struct pci_dev *pci_dev, | ||
907 | dma_addr_t of, | ||
908 | struct SRingBufferDescriptor *pRingBuffer, | ||
909 | u32 Buffer1Length, u32 Buffer2Length) | ||
910 | { | ||
911 | dma_addr_t tmp; | ||
912 | u32 i, j; | ||
913 | int status = 0; | ||
914 | u32 SCListMemSize = pRingBuffer->NumBuffers | ||
915 | * ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) : | ||
916 | NUM_SCATTER_GATHER_ENTRIES) | ||
917 | * sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
918 | |||
919 | u64 PASCListMem; | ||
920 | struct HW_SCATTER_GATHER_ELEMENT *SCListEntry; | ||
921 | u64 PASCListEntry; | ||
922 | struct SBufferHeader *Cur; | ||
923 | void *SCListMem; | ||
924 | |||
925 | if (SCListMemSize < 4096) | ||
926 | SCListMemSize = 4096; | ||
927 | |||
928 | SCListMem = pci_alloc_consistent(pci_dev, SCListMemSize, &tmp); | ||
929 | |||
930 | PASCListMem = tmp; | ||
931 | if (SCListMem == NULL) | ||
932 | return -ENOMEM; | ||
933 | |||
934 | memset(SCListMem, 0, SCListMemSize); | ||
935 | |||
936 | pRingBuffer->SCListMem = SCListMem; | ||
937 | pRingBuffer->PASCListMem = PASCListMem; | ||
938 | pRingBuffer->SCListMemSize = SCListMemSize; | ||
939 | pRingBuffer->Buffer1Length = Buffer1Length; | ||
940 | pRingBuffer->Buffer2Length = Buffer2Length; | ||
941 | |||
942 | SCListEntry = SCListMem; | ||
943 | PASCListEntry = PASCListMem; | ||
944 | Cur = pRingBuffer->Head; | ||
945 | |||
946 | for (i = 0; i < pRingBuffer->NumBuffers; i += 1, Cur = Cur->Next) { | ||
947 | u64 PABuffer; | ||
948 | |||
949 | void *Buffer = pci_alloc_consistent(pci_dev, Buffer1Length, | ||
950 | &tmp); | ||
951 | PABuffer = tmp; | ||
952 | |||
953 | if (Buffer == NULL) | ||
954 | return -ENOMEM; | ||
955 | |||
956 | Cur->Buffer1 = Buffer; | ||
957 | |||
958 | SCListEntry->Address = PABuffer; | ||
959 | SCListEntry->Length = Buffer1Length; | ||
960 | |||
961 | Cur->scList1 = SCListEntry; | ||
962 | Cur->ngeneBuffer.Address_of_first_entry_1 = PASCListEntry; | ||
963 | Cur->ngeneBuffer.Number_of_entries_1 = | ||
964 | NUM_SCATTER_GATHER_ENTRIES; | ||
965 | |||
966 | SCListEntry += 1; | ||
967 | PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
968 | |||
969 | #if NUM_SCATTER_GATHER_ENTRIES > 1 | ||
970 | for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j += 1) { | ||
971 | SCListEntry->Address = of; | ||
972 | SCListEntry->Length = OVERFLOW_BUFFER_SIZE; | ||
973 | SCListEntry += 1; | ||
974 | PASCListEntry += | ||
975 | sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
976 | } | ||
977 | #endif | ||
978 | |||
979 | if (!Buffer2Length) | ||
980 | continue; | ||
981 | |||
982 | Buffer = pci_alloc_consistent(pci_dev, Buffer2Length, &tmp); | ||
983 | PABuffer = tmp; | ||
984 | |||
985 | if (Buffer == NULL) | ||
986 | return -ENOMEM; | ||
987 | |||
988 | Cur->Buffer2 = Buffer; | ||
989 | |||
990 | SCListEntry->Address = PABuffer; | ||
991 | SCListEntry->Length = Buffer2Length; | ||
992 | |||
993 | Cur->scList2 = SCListEntry; | ||
994 | Cur->ngeneBuffer.Address_of_first_entry_2 = PASCListEntry; | ||
995 | Cur->ngeneBuffer.Number_of_entries_2 = | ||
996 | NUM_SCATTER_GATHER_ENTRIES; | ||
997 | |||
998 | SCListEntry += 1; | ||
999 | PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
1000 | |||
1001 | #if NUM_SCATTER_GATHER_ENTRIES > 1 | ||
1002 | for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j++) { | ||
1003 | SCListEntry->Address = of; | ||
1004 | SCListEntry->Length = OVERFLOW_BUFFER_SIZE; | ||
1005 | SCListEntry += 1; | ||
1006 | PASCListEntry += | ||
1007 | sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
1008 | } | ||
1009 | #endif | ||
1010 | |||
1011 | } | ||
1012 | |||
1013 | return status; | ||
1014 | } | ||
1015 | |||
1016 | static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer, | ||
1017 | struct SRingBufferDescriptor *pRingBuffer) | ||
1018 | { | ||
1019 | int status = 0; | ||
1020 | |||
1021 | /* Copy pointer to scatter gather list in TSRingbuffer | ||
1022 | structure for buffer 2 | ||
1023 | Load number of buffer | ||
1024 | */ | ||
1025 | u32 n = pRingBuffer->NumBuffers; | ||
1026 | |||
1027 | /* Point to first buffer entry */ | ||
1028 | struct SBufferHeader *Cur = pRingBuffer->Head; | ||
1029 | int i; | ||
1030 | /* Loop thru all buffer and set Buffer 2 pointers to TSIdlebuffer */ | ||
1031 | for (i = 0; i < n; i++) { | ||
1032 | Cur->Buffer2 = pIdleBuffer->Head->Buffer1; | ||
1033 | Cur->scList2 = pIdleBuffer->Head->scList1; | ||
1034 | Cur->ngeneBuffer.Address_of_first_entry_2 = | ||
1035 | pIdleBuffer->Head->ngeneBuffer. | ||
1036 | Address_of_first_entry_1; | ||
1037 | Cur->ngeneBuffer.Number_of_entries_2 = | ||
1038 | pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1; | ||
1039 | Cur = Cur->Next; | ||
1040 | } | ||
1041 | return status; | ||
1042 | } | ||
1043 | |||
1044 | static u32 RingBufferSizes[MAX_STREAM] = { | ||
1045 | RING_SIZE_VIDEO, | ||
1046 | RING_SIZE_VIDEO, | ||
1047 | RING_SIZE_AUDIO, | ||
1048 | RING_SIZE_AUDIO, | ||
1049 | RING_SIZE_AUDIO, | ||
1050 | }; | ||
1051 | |||
1052 | static u32 Buffer1Sizes[MAX_STREAM] = { | ||
1053 | MAX_VIDEO_BUFFER_SIZE, | ||
1054 | MAX_VIDEO_BUFFER_SIZE, | ||
1055 | MAX_AUDIO_BUFFER_SIZE, | ||
1056 | MAX_AUDIO_BUFFER_SIZE, | ||
1057 | MAX_AUDIO_BUFFER_SIZE | ||
1058 | }; | ||
1059 | |||
1060 | static u32 Buffer2Sizes[MAX_STREAM] = { | ||
1061 | MAX_VBI_BUFFER_SIZE, | ||
1062 | MAX_VBI_BUFFER_SIZE, | ||
1063 | 0, | ||
1064 | 0, | ||
1065 | 0 | ||
1066 | }; | ||
1067 | |||
1068 | |||
1069 | static int AllocCommonBuffers(struct ngene *dev) | ||
1070 | { | ||
1071 | int status = 0, i; | ||
1072 | |||
1073 | dev->FWInterfaceBuffer = pci_alloc_consistent(dev->pci_dev, 4096, | ||
1074 | &dev->PAFWInterfaceBuffer); | ||
1075 | if (!dev->FWInterfaceBuffer) | ||
1076 | return -ENOMEM; | ||
1077 | dev->hosttongene = dev->FWInterfaceBuffer; | ||
1078 | dev->ngenetohost = dev->FWInterfaceBuffer + 256; | ||
1079 | dev->EventBuffer = dev->FWInterfaceBuffer + 512; | ||
1080 | |||
1081 | dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev, | ||
1082 | OVERFLOW_BUFFER_SIZE, | ||
1083 | &dev->PAOverflowBuffer); | ||
1084 | if (!dev->OverflowBuffer) | ||
1085 | return -ENOMEM; | ||
1086 | memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE); | ||
1087 | |||
1088 | for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) { | ||
1089 | int type = dev->card_info->io_type[i]; | ||
1090 | |||
1091 | dev->channel[i].State = KSSTATE_STOP; | ||
1092 | |||
1093 | if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) { | ||
1094 | status = create_ring_buffer(dev->pci_dev, | ||
1095 | &dev->channel[i].RingBuffer, | ||
1096 | RingBufferSizes[i]); | ||
1097 | if (status < 0) | ||
1098 | break; | ||
1099 | |||
1100 | if (type & (NGENE_IO_TV | NGENE_IO_AIN)) { | ||
1101 | status = AllocateRingBuffers(dev->pci_dev, | ||
1102 | dev-> | ||
1103 | PAOverflowBuffer, | ||
1104 | &dev->channel[i]. | ||
1105 | RingBuffer, | ||
1106 | Buffer1Sizes[i], | ||
1107 | Buffer2Sizes[i]); | ||
1108 | if (status < 0) | ||
1109 | break; | ||
1110 | } else if (type & NGENE_IO_HDTV) { | ||
1111 | status = AllocateRingBuffers(dev->pci_dev, | ||
1112 | dev-> | ||
1113 | PAOverflowBuffer, | ||
1114 | &dev->channel[i]. | ||
1115 | RingBuffer, | ||
1116 | MAX_HDTV_BUFFER_SIZE, | ||
1117 | 0); | ||
1118 | if (status < 0) | ||
1119 | break; | ||
1120 | } | ||
1121 | } | ||
1122 | |||
1123 | if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | ||
1124 | |||
1125 | status = create_ring_buffer(dev->pci_dev, | ||
1126 | &dev->channel[i]. | ||
1127 | TSRingBuffer, RING_SIZE_TS); | ||
1128 | if (status < 0) | ||
1129 | break; | ||
1130 | |||
1131 | status = AllocateRingBuffers(dev->pci_dev, | ||
1132 | dev->PAOverflowBuffer, | ||
1133 | &dev->channel[i]. | ||
1134 | TSRingBuffer, | ||
1135 | MAX_TS_BUFFER_SIZE, 0); | ||
1136 | if (status) | ||
1137 | break; | ||
1138 | } | ||
1139 | |||
1140 | if (type & NGENE_IO_TSOUT) { | ||
1141 | status = create_ring_buffer(dev->pci_dev, | ||
1142 | &dev->channel[i]. | ||
1143 | TSIdleBuffer, 1); | ||
1144 | if (status < 0) | ||
1145 | break; | ||
1146 | status = AllocateRingBuffers(dev->pci_dev, | ||
1147 | dev->PAOverflowBuffer, | ||
1148 | &dev->channel[i]. | ||
1149 | TSIdleBuffer, | ||
1150 | MAX_TS_BUFFER_SIZE, 0); | ||
1151 | if (status) | ||
1152 | break; | ||
1153 | FillTSIdleBuffer(&dev->channel[i].TSIdleBuffer, | ||
1154 | &dev->channel[i].TSRingBuffer); | ||
1155 | } | ||
1156 | } | ||
1157 | return status; | ||
1158 | } | ||
1159 | |||
1160 | static void ngene_release_buffers(struct ngene *dev) | ||
1161 | { | ||
1162 | if (dev->iomem) | ||
1163 | iounmap(dev->iomem); | ||
1164 | free_common_buffers(dev); | ||
1165 | vfree(dev->tsout_buf); | ||
1166 | vfree(dev->tsin_buf); | ||
1167 | vfree(dev->ain_buf); | ||
1168 | vfree(dev->vin_buf); | ||
1169 | vfree(dev); | ||
1170 | } | ||
1171 | |||
1172 | static int ngene_get_buffers(struct ngene *dev) | ||
1173 | { | ||
1174 | if (AllocCommonBuffers(dev)) | ||
1175 | return -ENOMEM; | ||
1176 | if (dev->card_info->io_type[4] & NGENE_IO_TSOUT) { | ||
1177 | dev->tsout_buf = vmalloc(TSOUT_BUF_SIZE); | ||
1178 | if (!dev->tsout_buf) | ||
1179 | return -ENOMEM; | ||
1180 | dvb_ringbuffer_init(&dev->tsout_rbuf, | ||
1181 | dev->tsout_buf, TSOUT_BUF_SIZE); | ||
1182 | } | ||
1183 | if (dev->card_info->io_type[2]&NGENE_IO_TSIN) { | ||
1184 | dev->tsin_buf = vmalloc(TSIN_BUF_SIZE); | ||
1185 | if (!dev->tsin_buf) | ||
1186 | return -ENOMEM; | ||
1187 | dvb_ringbuffer_init(&dev->tsin_rbuf, | ||
1188 | dev->tsin_buf, TSIN_BUF_SIZE); | ||
1189 | } | ||
1190 | if (dev->card_info->io_type[2] & NGENE_IO_AIN) { | ||
1191 | dev->ain_buf = vmalloc(AIN_BUF_SIZE); | ||
1192 | if (!dev->ain_buf) | ||
1193 | return -ENOMEM; | ||
1194 | dvb_ringbuffer_init(&dev->ain_rbuf, dev->ain_buf, AIN_BUF_SIZE); | ||
1195 | } | ||
1196 | if (dev->card_info->io_type[0] & NGENE_IO_HDTV) { | ||
1197 | dev->vin_buf = vmalloc(VIN_BUF_SIZE); | ||
1198 | if (!dev->vin_buf) | ||
1199 | return -ENOMEM; | ||
1200 | dvb_ringbuffer_init(&dev->vin_rbuf, dev->vin_buf, VIN_BUF_SIZE); | ||
1201 | } | ||
1202 | dev->iomem = ioremap(pci_resource_start(dev->pci_dev, 0), | ||
1203 | pci_resource_len(dev->pci_dev, 0)); | ||
1204 | if (!dev->iomem) | ||
1205 | return -ENOMEM; | ||
1206 | |||
1207 | return 0; | ||
1208 | } | ||
1209 | |||
1210 | static void ngene_init(struct ngene *dev) | ||
1211 | { | ||
1212 | int i; | ||
1213 | |||
1214 | tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev); | ||
1215 | |||
1216 | memset_io(dev->iomem + 0xc000, 0x00, 0x220); | ||
1217 | memset_io(dev->iomem + 0xc400, 0x00, 0x100); | ||
1218 | |||
1219 | for (i = 0; i < MAX_STREAM; i++) { | ||
1220 | dev->channel[i].dev = dev; | ||
1221 | dev->channel[i].number = i; | ||
1222 | } | ||
1223 | |||
1224 | dev->fw_interface_version = 0; | ||
1225 | |||
1226 | ngwritel(0, NGENE_INT_ENABLE); | ||
1227 | |||
1228 | dev->icounts = ngreadl(NGENE_INT_COUNTS); | ||
1229 | |||
1230 | dev->device_version = ngreadl(DEV_VER) & 0x0f; | ||
1231 | printk(KERN_INFO DEVICE_NAME ": Device version %d\n", | ||
1232 | dev->device_version); | ||
1233 | } | ||
1234 | |||
1235 | static int ngene_load_firm(struct ngene *dev) | ||
1236 | { | ||
1237 | u32 size; | ||
1238 | const struct firmware *fw = NULL; | ||
1239 | u8 *ngene_fw; | ||
1240 | char *fw_name; | ||
1241 | int err, version; | ||
1242 | |||
1243 | version = dev->card_info->fw_version; | ||
1244 | |||
1245 | switch (version) { | ||
1246 | default: | ||
1247 | case 15: | ||
1248 | version = 15; | ||
1249 | size = 23466; | ||
1250 | fw_name = "ngene_15.fw"; | ||
1251 | dev->cmd_timeout_workaround = true; | ||
1252 | break; | ||
1253 | case 16: | ||
1254 | size = 23498; | ||
1255 | fw_name = "ngene_16.fw"; | ||
1256 | dev->cmd_timeout_workaround = true; | ||
1257 | break; | ||
1258 | case 17: | ||
1259 | size = 24446; | ||
1260 | fw_name = "ngene_17.fw"; | ||
1261 | dev->cmd_timeout_workaround = true; | ||
1262 | break; | ||
1263 | case 18: | ||
1264 | size = 0; | ||
1265 | fw_name = "ngene_18.fw"; | ||
1266 | break; | ||
1267 | } | ||
1268 | |||
1269 | if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { | ||
1270 | printk(KERN_ERR DEVICE_NAME | ||
1271 | ": Could not load firmware file %s.\n", fw_name); | ||
1272 | printk(KERN_INFO DEVICE_NAME | ||
1273 | ": Copy %s to your hotplug directory!\n", fw_name); | ||
1274 | return -1; | ||
1275 | } | ||
1276 | if (size == 0) | ||
1277 | size = fw->size; | ||
1278 | if (size != fw->size) { | ||
1279 | printk(KERN_ERR DEVICE_NAME | ||
1280 | ": Firmware %s has invalid size!", fw_name); | ||
1281 | err = -1; | ||
1282 | } else { | ||
1283 | printk(KERN_INFO DEVICE_NAME | ||
1284 | ": Loading firmware file %s.\n", fw_name); | ||
1285 | ngene_fw = (u8 *) fw->data; | ||
1286 | err = ngene_command_load_firmware(dev, ngene_fw, size); | ||
1287 | } | ||
1288 | |||
1289 | release_firmware(fw); | ||
1290 | |||
1291 | return err; | ||
1292 | } | ||
1293 | |||
1294 | static void ngene_stop(struct ngene *dev) | ||
1295 | { | ||
1296 | down(&dev->cmd_mutex); | ||
1297 | i2c_del_adapter(&(dev->channel[0].i2c_adapter)); | ||
1298 | i2c_del_adapter(&(dev->channel[1].i2c_adapter)); | ||
1299 | ngwritel(0, NGENE_INT_ENABLE); | ||
1300 | ngwritel(0, NGENE_COMMAND); | ||
1301 | ngwritel(0, NGENE_COMMAND_HI); | ||
1302 | ngwritel(0, NGENE_STATUS); | ||
1303 | ngwritel(0, NGENE_STATUS_HI); | ||
1304 | ngwritel(0, NGENE_EVENT); | ||
1305 | ngwritel(0, NGENE_EVENT_HI); | ||
1306 | free_irq(dev->pci_dev->irq, dev); | ||
1307 | #ifdef CONFIG_PCI_MSI | ||
1308 | if (dev->msi_enabled) | ||
1309 | pci_disable_msi(dev->pci_dev); | ||
1310 | #endif | ||
1311 | } | ||
1312 | |||
1313 | static int ngene_buffer_config(struct ngene *dev) | ||
1314 | { | ||
1315 | int stat; | ||
1316 | |||
1317 | if (dev->card_info->fw_version >= 17) { | ||
1318 | u8 tsin12_config[6] = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }; | ||
1319 | u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 }; | ||
1320 | u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 }; | ||
1321 | u8 *bconf = tsin12_config; | ||
1322 | |||
1323 | if (dev->card_info->io_type[2]&NGENE_IO_TSIN && | ||
1324 | dev->card_info->io_type[3]&NGENE_IO_TSIN) { | ||
1325 | bconf = tsin1234_config; | ||
1326 | if (dev->card_info->io_type[4]&NGENE_IO_TSOUT && | ||
1327 | dev->ci.en) | ||
1328 | bconf = tsio1235_config; | ||
1329 | } | ||
1330 | stat = ngene_command_config_free_buf(dev, bconf); | ||
1331 | } else { | ||
1332 | int bconf = BUFFER_CONFIG_4422; | ||
1333 | |||
1334 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1335 | bconf = BUFFER_CONFIG_3333; | ||
1336 | stat = ngene_command_config_buf(dev, bconf); | ||
1337 | } | ||
1338 | return stat; | ||
1339 | } | ||
1340 | |||
1341 | |||
1342 | static int ngene_start(struct ngene *dev) | ||
1343 | { | ||
1344 | int stat; | ||
1345 | int i; | ||
1346 | |||
1347 | pci_set_master(dev->pci_dev); | ||
1348 | ngene_init(dev); | ||
1349 | |||
1350 | stat = request_irq(dev->pci_dev->irq, irq_handler, | ||
1351 | IRQF_SHARED, "nGene", | ||
1352 | (void *)dev); | ||
1353 | if (stat < 0) | ||
1354 | return stat; | ||
1355 | |||
1356 | init_waitqueue_head(&dev->cmd_wq); | ||
1357 | init_waitqueue_head(&dev->tx_wq); | ||
1358 | init_waitqueue_head(&dev->rx_wq); | ||
1359 | sema_init(&dev->cmd_mutex, 1); | ||
1360 | sema_init(&dev->stream_mutex, 1); | ||
1361 | sema_init(&dev->pll_mutex, 1); | ||
1362 | sema_init(&dev->i2c_switch_mutex, 1); | ||
1363 | spin_lock_init(&dev->cmd_lock); | ||
1364 | for (i = 0; i < MAX_STREAM; i++) | ||
1365 | spin_lock_init(&dev->channel[i].state_lock); | ||
1366 | ngwritel(1, TIMESTAMPS); | ||
1367 | |||
1368 | ngwritel(1, NGENE_INT_ENABLE); | ||
1369 | |||
1370 | stat = ngene_load_firm(dev); | ||
1371 | if (stat < 0) | ||
1372 | goto fail; | ||
1373 | |||
1374 | #ifdef CONFIG_PCI_MSI | ||
1375 | /* enable MSI if kernel and card support it */ | ||
1376 | if (pci_msi_enabled() && dev->card_info->msi_supported) { | ||
1377 | unsigned long flags; | ||
1378 | |||
1379 | ngwritel(0, NGENE_INT_ENABLE); | ||
1380 | free_irq(dev->pci_dev->irq, dev); | ||
1381 | stat = pci_enable_msi(dev->pci_dev); | ||
1382 | if (stat) { | ||
1383 | printk(KERN_INFO DEVICE_NAME | ||
1384 | ": MSI not available\n"); | ||
1385 | flags = IRQF_SHARED; | ||
1386 | } else { | ||
1387 | flags = 0; | ||
1388 | dev->msi_enabled = true; | ||
1389 | } | ||
1390 | stat = request_irq(dev->pci_dev->irq, irq_handler, | ||
1391 | flags, "nGene", dev); | ||
1392 | if (stat < 0) | ||
1393 | goto fail2; | ||
1394 | ngwritel(1, NGENE_INT_ENABLE); | ||
1395 | } | ||
1396 | #endif | ||
1397 | |||
1398 | stat = ngene_i2c_init(dev, 0); | ||
1399 | if (stat < 0) | ||
1400 | goto fail; | ||
1401 | |||
1402 | stat = ngene_i2c_init(dev, 1); | ||
1403 | if (stat < 0) | ||
1404 | goto fail; | ||
1405 | |||
1406 | return 0; | ||
1407 | |||
1408 | fail: | ||
1409 | ngwritel(0, NGENE_INT_ENABLE); | ||
1410 | free_irq(dev->pci_dev->irq, dev); | ||
1411 | #ifdef CONFIG_PCI_MSI | ||
1412 | fail2: | ||
1413 | if (dev->msi_enabled) | ||
1414 | pci_disable_msi(dev->pci_dev); | ||
1415 | #endif | ||
1416 | return stat; | ||
1417 | } | ||
1418 | |||
1419 | /****************************************************************************/ | ||
1420 | /****************************************************************************/ | ||
1421 | /****************************************************************************/ | ||
1422 | |||
1423 | static void release_channel(struct ngene_channel *chan) | ||
1424 | { | ||
1425 | struct dvb_demux *dvbdemux = &chan->demux; | ||
1426 | struct ngene *dev = chan->dev; | ||
1427 | |||
1428 | if (chan->running) | ||
1429 | set_transfer(chan, 0); | ||
1430 | |||
1431 | tasklet_kill(&chan->demux_tasklet); | ||
1432 | |||
1433 | if (chan->ci_dev) { | ||
1434 | dvb_unregister_device(chan->ci_dev); | ||
1435 | chan->ci_dev = NULL; | ||
1436 | } | ||
1437 | |||
1438 | if (chan->fe2) | ||
1439 | dvb_unregister_frontend(chan->fe2); | ||
1440 | |||
1441 | if (chan->fe) { | ||
1442 | dvb_unregister_frontend(chan->fe); | ||
1443 | dvb_frontend_detach(chan->fe); | ||
1444 | chan->fe = NULL; | ||
1445 | } | ||
1446 | |||
1447 | if (chan->has_demux) { | ||
1448 | dvb_net_release(&chan->dvbnet); | ||
1449 | dvbdemux->dmx.close(&dvbdemux->dmx); | ||
1450 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | ||
1451 | &chan->hw_frontend); | ||
1452 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | ||
1453 | &chan->mem_frontend); | ||
1454 | dvb_dmxdev_release(&chan->dmxdev); | ||
1455 | dvb_dmx_release(&chan->demux); | ||
1456 | chan->has_demux = false; | ||
1457 | } | ||
1458 | |||
1459 | if (chan->has_adapter) { | ||
1460 | dvb_unregister_adapter(&dev->adapter[chan->number]); | ||
1461 | chan->has_adapter = false; | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1465 | static int init_channel(struct ngene_channel *chan) | ||
1466 | { | ||
1467 | int ret = 0, nr = chan->number; | ||
1468 | struct dvb_adapter *adapter = NULL; | ||
1469 | struct dvb_demux *dvbdemux = &chan->demux; | ||
1470 | struct ngene *dev = chan->dev; | ||
1471 | struct ngene_info *ni = dev->card_info; | ||
1472 | int io = ni->io_type[nr]; | ||
1473 | |||
1474 | tasklet_init(&chan->demux_tasklet, demux_tasklet, (unsigned long)chan); | ||
1475 | chan->users = 0; | ||
1476 | chan->type = io; | ||
1477 | chan->mode = chan->type; /* for now only one mode */ | ||
1478 | |||
1479 | if (io & NGENE_IO_TSIN) { | ||
1480 | chan->fe = NULL; | ||
1481 | if (ni->demod_attach[nr]) { | ||
1482 | ret = ni->demod_attach[nr](chan); | ||
1483 | if (ret < 0) | ||
1484 | goto err; | ||
1485 | } | ||
1486 | if (chan->fe && ni->tuner_attach[nr]) { | ||
1487 | ret = ni->tuner_attach[nr](chan); | ||
1488 | if (ret < 0) | ||
1489 | goto err; | ||
1490 | } | ||
1491 | } | ||
1492 | |||
1493 | if (!dev->ci.en && (io & NGENE_IO_TSOUT)) | ||
1494 | return 0; | ||
1495 | |||
1496 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | ||
1497 | if (nr >= STREAM_AUDIOIN1) | ||
1498 | chan->DataFormatFlags = DF_SWAP32; | ||
1499 | |||
1500 | if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { | ||
1501 | adapter = &dev->adapter[nr]; | ||
1502 | ret = dvb_register_adapter(adapter, "nGene", | ||
1503 | THIS_MODULE, | ||
1504 | &chan->dev->pci_dev->dev, | ||
1505 | adapter_nr); | ||
1506 | if (ret < 0) | ||
1507 | goto err; | ||
1508 | if (dev->first_adapter == NULL) | ||
1509 | dev->first_adapter = adapter; | ||
1510 | chan->has_adapter = true; | ||
1511 | } else | ||
1512 | adapter = dev->first_adapter; | ||
1513 | } | ||
1514 | |||
1515 | if (dev->ci.en && (io & NGENE_IO_TSOUT)) { | ||
1516 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); | ||
1517 | set_transfer(chan, 1); | ||
1518 | chan->dev->channel[2].DataFormatFlags = DF_SWAP32; | ||
1519 | set_transfer(&chan->dev->channel[2], 1); | ||
1520 | dvb_register_device(adapter, &chan->ci_dev, | ||
1521 | &ngene_dvbdev_ci, (void *) chan, | ||
1522 | DVB_DEVICE_SEC); | ||
1523 | if (!chan->ci_dev) | ||
1524 | goto err; | ||
1525 | } | ||
1526 | |||
1527 | if (chan->fe) { | ||
1528 | if (dvb_register_frontend(adapter, chan->fe) < 0) | ||
1529 | goto err; | ||
1530 | chan->has_demux = true; | ||
1531 | } | ||
1532 | if (chan->fe2) { | ||
1533 | if (dvb_register_frontend(adapter, chan->fe2) < 0) | ||
1534 | goto err; | ||
1535 | chan->fe2->tuner_priv = chan->fe->tuner_priv; | ||
1536 | memcpy(&chan->fe2->ops.tuner_ops, | ||
1537 | &chan->fe->ops.tuner_ops, | ||
1538 | sizeof(struct dvb_tuner_ops)); | ||
1539 | } | ||
1540 | |||
1541 | if (chan->has_demux) { | ||
1542 | ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", | ||
1543 | ngene_start_feed, | ||
1544 | ngene_stop_feed, chan); | ||
1545 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, | ||
1546 | &chan->hw_frontend, | ||
1547 | &chan->mem_frontend, adapter); | ||
1548 | ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx); | ||
1549 | } | ||
1550 | |||
1551 | return ret; | ||
1552 | |||
1553 | err: | ||
1554 | if (chan->fe) { | ||
1555 | dvb_frontend_detach(chan->fe); | ||
1556 | chan->fe = NULL; | ||
1557 | } | ||
1558 | release_channel(chan); | ||
1559 | return 0; | ||
1560 | } | ||
1561 | |||
1562 | static int init_channels(struct ngene *dev) | ||
1563 | { | ||
1564 | int i, j; | ||
1565 | |||
1566 | for (i = 0; i < MAX_STREAM; i++) { | ||
1567 | dev->channel[i].number = i; | ||
1568 | if (init_channel(&dev->channel[i]) < 0) { | ||
1569 | for (j = i - 1; j >= 0; j--) | ||
1570 | release_channel(&dev->channel[j]); | ||
1571 | return -1; | ||
1572 | } | ||
1573 | } | ||
1574 | return 0; | ||
1575 | } | ||
1576 | |||
1577 | static struct cxd2099_cfg cxd_cfg = { | ||
1578 | .bitrate = 62000, | ||
1579 | .adr = 0x40, | ||
1580 | .polarity = 0, | ||
1581 | .clock_mode = 0, | ||
1582 | }; | ||
1583 | |||
1584 | static void cxd_attach(struct ngene *dev) | ||
1585 | { | ||
1586 | struct ngene_ci *ci = &dev->ci; | ||
1587 | |||
1588 | ci->en = cxd2099_attach(&cxd_cfg, dev, &dev->channel[0].i2c_adapter); | ||
1589 | ci->dev = dev; | ||
1590 | return; | ||
1591 | } | ||
1592 | |||
1593 | static void cxd_detach(struct ngene *dev) | ||
1594 | { | ||
1595 | struct ngene_ci *ci = &dev->ci; | ||
1596 | |||
1597 | dvb_ca_en50221_release(ci->en); | ||
1598 | kfree(ci->en); | ||
1599 | ci->en = 0; | ||
1600 | } | ||
1601 | |||
1602 | /***********************************/ | ||
1603 | /* workaround for shutdown failure */ | ||
1604 | /***********************************/ | ||
1605 | |||
1606 | static void ngene_unlink(struct ngene *dev) | ||
1607 | { | ||
1608 | struct ngene_command com; | ||
1609 | |||
1610 | com.cmd.hdr.Opcode = CMD_MEM_WRITE; | ||
1611 | com.cmd.hdr.Length = 3; | ||
1612 | com.cmd.MemoryWrite.address = 0x910c; | ||
1613 | com.cmd.MemoryWrite.data = 0xff; | ||
1614 | com.in_len = 3; | ||
1615 | com.out_len = 1; | ||
1616 | |||
1617 | down(&dev->cmd_mutex); | ||
1618 | ngwritel(0, NGENE_INT_ENABLE); | ||
1619 | ngene_command_mutex(dev, &com); | ||
1620 | up(&dev->cmd_mutex); | ||
1621 | } | ||
1622 | |||
1623 | void ngene_shutdown(struct pci_dev *pdev) | ||
1624 | { | ||
1625 | struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); | ||
1626 | |||
1627 | if (!dev || !shutdown_workaround) | ||
1628 | return; | ||
1629 | |||
1630 | printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n"); | ||
1631 | ngene_unlink(dev); | ||
1632 | pci_disable_device(pdev); | ||
1633 | } | ||
1634 | |||
1635 | /****************************************************************************/ | ||
1636 | /* device probe/remove calls ************************************************/ | ||
1637 | /****************************************************************************/ | ||
1638 | |||
1639 | void __devexit ngene_remove(struct pci_dev *pdev) | ||
1640 | { | ||
1641 | struct ngene *dev = pci_get_drvdata(pdev); | ||
1642 | int i; | ||
1643 | |||
1644 | tasklet_kill(&dev->event_tasklet); | ||
1645 | for (i = MAX_STREAM - 1; i >= 0; i--) | ||
1646 | release_channel(&dev->channel[i]); | ||
1647 | if (dev->ci.en) | ||
1648 | cxd_detach(dev); | ||
1649 | ngene_stop(dev); | ||
1650 | ngene_release_buffers(dev); | ||
1651 | pci_set_drvdata(pdev, NULL); | ||
1652 | pci_disable_device(pdev); | ||
1653 | } | ||
1654 | |||
1655 | int __devinit ngene_probe(struct pci_dev *pci_dev, | ||
1656 | const struct pci_device_id *id) | ||
1657 | { | ||
1658 | struct ngene *dev; | ||
1659 | int stat = 0; | ||
1660 | |||
1661 | if (pci_enable_device(pci_dev) < 0) | ||
1662 | return -ENODEV; | ||
1663 | |||
1664 | dev = vzalloc(sizeof(struct ngene)); | ||
1665 | if (dev == NULL) { | ||
1666 | stat = -ENOMEM; | ||
1667 | goto fail0; | ||
1668 | } | ||
1669 | |||
1670 | dev->pci_dev = pci_dev; | ||
1671 | dev->card_info = (struct ngene_info *)id->driver_data; | ||
1672 | printk(KERN_INFO DEVICE_NAME ": Found %s\n", dev->card_info->name); | ||
1673 | |||
1674 | pci_set_drvdata(pci_dev, dev); | ||
1675 | |||
1676 | /* Alloc buffers and start nGene */ | ||
1677 | stat = ngene_get_buffers(dev); | ||
1678 | if (stat < 0) | ||
1679 | goto fail1; | ||
1680 | stat = ngene_start(dev); | ||
1681 | if (stat < 0) | ||
1682 | goto fail1; | ||
1683 | |||
1684 | cxd_attach(dev); | ||
1685 | |||
1686 | stat = ngene_buffer_config(dev); | ||
1687 | if (stat < 0) | ||
1688 | goto fail1; | ||
1689 | |||
1690 | |||
1691 | dev->i2c_current_bus = -1; | ||
1692 | |||
1693 | /* Register DVB adapters and devices for both channels */ | ||
1694 | if (init_channels(dev) < 0) | ||
1695 | goto fail2; | ||
1696 | |||
1697 | return 0; | ||
1698 | |||
1699 | fail2: | ||
1700 | ngene_stop(dev); | ||
1701 | fail1: | ||
1702 | ngene_release_buffers(dev); | ||
1703 | fail0: | ||
1704 | pci_disable_device(pci_dev); | ||
1705 | pci_set_drvdata(pci_dev, NULL); | ||
1706 | return stat; | ||
1707 | } | ||
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c deleted file mode 100644 index fcb16a615aab..000000000000 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ /dev/null | |||
@@ -1,261 +0,0 @@ | |||
1 | /* | ||
2 | * ngene-dvb.c: nGene PCIe bridge driver - DVB functions | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * Modifications for new nGene firmware, | ||
8 | * support for EEPROM-copying, | ||
9 | * support for new dual DVB-S2 card prototype | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * version 2 only, as published by the Free Software Foundation. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
26 | * 02110-1301, USA | ||
27 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/poll.h> | ||
35 | #include <linux/io.h> | ||
36 | #include <asm/div64.h> | ||
37 | #include <linux/pci.h> | ||
38 | #include <linux/timer.h> | ||
39 | #include <linux/byteorder/generic.h> | ||
40 | #include <linux/firmware.h> | ||
41 | #include <linux/vmalloc.h> | ||
42 | |||
43 | #include "ngene.h" | ||
44 | |||
45 | |||
46 | /****************************************************************************/ | ||
47 | /* COMMAND API interface ****************************************************/ | ||
48 | /****************************************************************************/ | ||
49 | |||
50 | static ssize_t ts_write(struct file *file, const char *buf, | ||
51 | size_t count, loff_t *ppos) | ||
52 | { | ||
53 | struct dvb_device *dvbdev = file->private_data; | ||
54 | struct ngene_channel *chan = dvbdev->priv; | ||
55 | struct ngene *dev = chan->dev; | ||
56 | |||
57 | if (wait_event_interruptible(dev->tsout_rbuf.queue, | ||
58 | dvb_ringbuffer_free | ||
59 | (&dev->tsout_rbuf) >= count) < 0) | ||
60 | return 0; | ||
61 | |||
62 | dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count); | ||
63 | |||
64 | return count; | ||
65 | } | ||
66 | |||
67 | static ssize_t ts_read(struct file *file, char *buf, | ||
68 | size_t count, loff_t *ppos) | ||
69 | { | ||
70 | struct dvb_device *dvbdev = file->private_data; | ||
71 | struct ngene_channel *chan = dvbdev->priv; | ||
72 | struct ngene *dev = chan->dev; | ||
73 | int left, avail; | ||
74 | |||
75 | left = count; | ||
76 | while (left) { | ||
77 | if (wait_event_interruptible( | ||
78 | dev->tsin_rbuf.queue, | ||
79 | dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0) | ||
80 | return -EAGAIN; | ||
81 | avail = dvb_ringbuffer_avail(&dev->tsin_rbuf); | ||
82 | if (avail > left) | ||
83 | avail = left; | ||
84 | dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail); | ||
85 | left -= avail; | ||
86 | buf += avail; | ||
87 | } | ||
88 | return count; | ||
89 | } | ||
90 | |||
91 | static const struct file_operations ci_fops = { | ||
92 | .owner = THIS_MODULE, | ||
93 | .read = ts_read, | ||
94 | .write = ts_write, | ||
95 | .open = dvb_generic_open, | ||
96 | .release = dvb_generic_release, | ||
97 | }; | ||
98 | |||
99 | struct dvb_device ngene_dvbdev_ci = { | ||
100 | .priv = 0, | ||
101 | .readers = -1, | ||
102 | .writers = -1, | ||
103 | .users = -1, | ||
104 | .fops = &ci_fops, | ||
105 | }; | ||
106 | |||
107 | |||
108 | /****************************************************************************/ | ||
109 | /* DVB functions and API interface ******************************************/ | ||
110 | /****************************************************************************/ | ||
111 | |||
112 | static void swap_buffer(u32 *p, u32 len) | ||
113 | { | ||
114 | while (len) { | ||
115 | *p = swab32(*p); | ||
116 | p++; | ||
117 | len -= 4; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | /* start of filler packet */ | ||
122 | static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER }; | ||
123 | |||
124 | /* #define DEBUG_CI_XFER */ | ||
125 | #ifdef DEBUG_CI_XFER | ||
126 | static u32 ok; | ||
127 | static u32 overflow; | ||
128 | static u32 stripped; | ||
129 | #endif | ||
130 | |||
131 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | ||
132 | { | ||
133 | struct ngene_channel *chan = priv; | ||
134 | struct ngene *dev = chan->dev; | ||
135 | |||
136 | |||
137 | if (flags & DF_SWAP32) | ||
138 | swap_buffer(buf, len); | ||
139 | |||
140 | if (dev->ci.en && chan->number == 2) { | ||
141 | while (len >= 188) { | ||
142 | if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) { | ||
143 | if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) { | ||
144 | dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188); | ||
145 | wake_up(&dev->tsin_rbuf.queue); | ||
146 | #ifdef DEBUG_CI_XFER | ||
147 | ok++; | ||
148 | #endif | ||
149 | } | ||
150 | #ifdef DEBUG_CI_XFER | ||
151 | else | ||
152 | overflow++; | ||
153 | #endif | ||
154 | } | ||
155 | #ifdef DEBUG_CI_XFER | ||
156 | else | ||
157 | stripped++; | ||
158 | |||
159 | if (ok % 100 == 0 && overflow) | ||
160 | printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped); | ||
161 | #endif | ||
162 | buf += 188; | ||
163 | len -= 188; | ||
164 | } | ||
165 | return NULL; | ||
166 | } | ||
167 | |||
168 | if (chan->users > 0) | ||
169 | dvb_dmx_swfilter(&chan->demux, buf, len); | ||
170 | |||
171 | return NULL; | ||
172 | } | ||
173 | |||
174 | void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | ||
175 | { | ||
176 | struct ngene_channel *chan = priv; | ||
177 | struct ngene *dev = chan->dev; | ||
178 | u32 alen; | ||
179 | |||
180 | alen = dvb_ringbuffer_avail(&dev->tsout_rbuf); | ||
181 | alen -= alen % 188; | ||
182 | |||
183 | if (alen < len) | ||
184 | FillTSBuffer(buf + alen, len - alen, flags); | ||
185 | else | ||
186 | alen = len; | ||
187 | dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen); | ||
188 | if (flags & DF_SWAP32) | ||
189 | swap_buffer((u32 *)buf, alen); | ||
190 | wake_up_interruptible(&dev->tsout_rbuf.queue); | ||
191 | return buf; | ||
192 | } | ||
193 | |||
194 | |||
195 | |||
196 | int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
197 | { | ||
198 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
199 | struct ngene_channel *chan = dvbdmx->priv; | ||
200 | |||
201 | if (chan->users == 0) { | ||
202 | if (!chan->dev->cmd_timeout_workaround || !chan->running) | ||
203 | set_transfer(chan, 1); | ||
204 | } | ||
205 | |||
206 | return ++chan->users; | ||
207 | } | ||
208 | |||
209 | int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
210 | { | ||
211 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
212 | struct ngene_channel *chan = dvbdmx->priv; | ||
213 | |||
214 | if (--chan->users) | ||
215 | return chan->users; | ||
216 | |||
217 | if (!chan->dev->cmd_timeout_workaround) | ||
218 | set_transfer(chan, 0); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, | ||
224 | int (*start_feed)(struct dvb_demux_feed *), | ||
225 | int (*stop_feed)(struct dvb_demux_feed *), | ||
226 | void *priv) | ||
227 | { | ||
228 | dvbdemux->priv = priv; | ||
229 | |||
230 | dvbdemux->filternum = 256; | ||
231 | dvbdemux->feednum = 256; | ||
232 | dvbdemux->start_feed = start_feed; | ||
233 | dvbdemux->stop_feed = stop_feed; | ||
234 | dvbdemux->write_to_decoder = NULL; | ||
235 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | | ||
236 | DMX_SECTION_FILTERING | | ||
237 | DMX_MEMORY_BASED_FILTERING); | ||
238 | return dvb_dmx_init(dvbdemux); | ||
239 | } | ||
240 | |||
241 | int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, | ||
242 | struct dvb_demux *dvbdemux, | ||
243 | struct dmx_frontend *hw_frontend, | ||
244 | struct dmx_frontend *mem_frontend, | ||
245 | struct dvb_adapter *dvb_adapter) | ||
246 | { | ||
247 | int ret; | ||
248 | |||
249 | dmxdev->filternum = 256; | ||
250 | dmxdev->demux = &dvbdemux->dmx; | ||
251 | dmxdev->capabilities = 0; | ||
252 | ret = dvb_dmxdev_init(dmxdev, dvb_adapter); | ||
253 | if (ret < 0) | ||
254 | return ret; | ||
255 | |||
256 | hw_frontend->source = DMX_FRONTEND_0; | ||
257 | dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); | ||
258 | mem_frontend->source = DMX_MEMORY_FE; | ||
259 | dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); | ||
260 | return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); | ||
261 | } | ||
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c deleted file mode 100644 index d28554f8ce99..000000000000 --- a/drivers/media/dvb/ngene/ngene-i2c.c +++ /dev/null | |||
@@ -1,176 +0,0 @@ | |||
1 | /* | ||
2 | * ngene-i2c.c: nGene PCIe bridge driver i2c functions | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * Modifications for new nGene firmware, | ||
8 | * support for EEPROM-copying, | ||
9 | * support for new dual DVB-S2 card prototype | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * version 2 only, as published by the Free Software Foundation. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
26 | * 02110-1301, USA | ||
27 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
28 | */ | ||
29 | |||
30 | /* FIXME - some of these can probably be removed */ | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/poll.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <asm/div64.h> | ||
38 | #include <linux/pci.h> | ||
39 | #include <linux/pci_ids.h> | ||
40 | #include <linux/timer.h> | ||
41 | #include <linux/byteorder/generic.h> | ||
42 | #include <linux/firmware.h> | ||
43 | #include <linux/vmalloc.h> | ||
44 | |||
45 | #include "ngene.h" | ||
46 | |||
47 | /* Firmware command for i2c operations */ | ||
48 | static int ngene_command_i2c_read(struct ngene *dev, u8 adr, | ||
49 | u8 *out, u8 outlen, u8 *in, u8 inlen, int flag) | ||
50 | { | ||
51 | struct ngene_command com; | ||
52 | |||
53 | com.cmd.hdr.Opcode = CMD_I2C_READ; | ||
54 | com.cmd.hdr.Length = outlen + 3; | ||
55 | com.cmd.I2CRead.Device = adr << 1; | ||
56 | memcpy(com.cmd.I2CRead.Data, out, outlen); | ||
57 | com.cmd.I2CRead.Data[outlen] = inlen; | ||
58 | com.cmd.I2CRead.Data[outlen + 1] = 0; | ||
59 | com.in_len = outlen + 3; | ||
60 | com.out_len = inlen + 1; | ||
61 | |||
62 | if (ngene_command(dev, &com) < 0) | ||
63 | return -EIO; | ||
64 | |||
65 | if ((com.cmd.raw8[0] >> 1) != adr) | ||
66 | return -EIO; | ||
67 | |||
68 | if (flag) | ||
69 | memcpy(in, com.cmd.raw8, inlen + 1); | ||
70 | else | ||
71 | memcpy(in, com.cmd.raw8 + 1, inlen); | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int ngene_command_i2c_write(struct ngene *dev, u8 adr, | ||
76 | u8 *out, u8 outlen) | ||
77 | { | ||
78 | struct ngene_command com; | ||
79 | |||
80 | |||
81 | com.cmd.hdr.Opcode = CMD_I2C_WRITE; | ||
82 | com.cmd.hdr.Length = outlen + 1; | ||
83 | com.cmd.I2CRead.Device = adr << 1; | ||
84 | memcpy(com.cmd.I2CRead.Data, out, outlen); | ||
85 | com.in_len = outlen + 1; | ||
86 | com.out_len = 1; | ||
87 | |||
88 | if (ngene_command(dev, &com) < 0) | ||
89 | return -EIO; | ||
90 | |||
91 | if (com.cmd.raw8[0] == 1) | ||
92 | return -EIO; | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static void ngene_i2c_set_bus(struct ngene *dev, int bus) | ||
98 | { | ||
99 | if (!(dev->card_info->i2c_access & 2)) | ||
100 | return; | ||
101 | if (dev->i2c_current_bus == bus) | ||
102 | return; | ||
103 | |||
104 | switch (bus) { | ||
105 | case 0: | ||
106 | ngene_command_gpio_set(dev, 3, 0); | ||
107 | ngene_command_gpio_set(dev, 2, 1); | ||
108 | break; | ||
109 | |||
110 | case 1: | ||
111 | ngene_command_gpio_set(dev, 2, 0); | ||
112 | ngene_command_gpio_set(dev, 3, 1); | ||
113 | break; | ||
114 | } | ||
115 | dev->i2c_current_bus = bus; | ||
116 | } | ||
117 | |||
118 | static int ngene_i2c_master_xfer(struct i2c_adapter *adapter, | ||
119 | struct i2c_msg msg[], int num) | ||
120 | { | ||
121 | struct ngene_channel *chan = | ||
122 | (struct ngene_channel *)i2c_get_adapdata(adapter); | ||
123 | struct ngene *dev = chan->dev; | ||
124 | |||
125 | down(&dev->i2c_switch_mutex); | ||
126 | ngene_i2c_set_bus(dev, chan->number); | ||
127 | |||
128 | if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD)) | ||
129 | if (!ngene_command_i2c_read(dev, msg[0].addr, | ||
130 | msg[0].buf, msg[0].len, | ||
131 | msg[1].buf, msg[1].len, 0)) | ||
132 | goto done; | ||
133 | |||
134 | if (num == 1 && !(msg[0].flags & I2C_M_RD)) | ||
135 | if (!ngene_command_i2c_write(dev, msg[0].addr, | ||
136 | msg[0].buf, msg[0].len)) | ||
137 | goto done; | ||
138 | if (num == 1 && (msg[0].flags & I2C_M_RD)) | ||
139 | if (!ngene_command_i2c_read(dev, msg[0].addr, NULL, 0, | ||
140 | msg[0].buf, msg[0].len, 0)) | ||
141 | goto done; | ||
142 | |||
143 | up(&dev->i2c_switch_mutex); | ||
144 | return -EIO; | ||
145 | |||
146 | done: | ||
147 | up(&dev->i2c_switch_mutex); | ||
148 | return num; | ||
149 | } | ||
150 | |||
151 | |||
152 | static u32 ngene_i2c_functionality(struct i2c_adapter *adap) | ||
153 | { | ||
154 | return I2C_FUNC_SMBUS_EMUL; | ||
155 | } | ||
156 | |||
157 | static struct i2c_algorithm ngene_i2c_algo = { | ||
158 | .master_xfer = ngene_i2c_master_xfer, | ||
159 | .functionality = ngene_i2c_functionality, | ||
160 | }; | ||
161 | |||
162 | int ngene_i2c_init(struct ngene *dev, int dev_nr) | ||
163 | { | ||
164 | struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter); | ||
165 | |||
166 | i2c_set_adapdata(adap, &(dev->channel[dev_nr])); | ||
167 | |||
168 | strcpy(adap->name, "nGene"); | ||
169 | |||
170 | adap->algo = &ngene_i2c_algo; | ||
171 | adap->algo_data = (void *)&(dev->channel[dev_nr]); | ||
172 | adap->dev.parent = &dev->pci_dev->dev; | ||
173 | |||
174 | return i2c_add_adapter(adap); | ||
175 | } | ||
176 | |||
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h deleted file mode 100644 index 5443dc0caea5..000000000000 --- a/drivers/media/dvb/ngene/ngene.h +++ /dev/null | |||
@@ -1,921 +0,0 @@ | |||
1 | /* | ||
2 | * ngene.h: nGene PCIe bridge driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 only, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
22 | */ | ||
23 | |||
24 | #ifndef _NGENE_H_ | ||
25 | #define _NGENE_H_ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <asm/dma.h> | ||
32 | #include <linux/scatterlist.h> | ||
33 | |||
34 | #include <linux/dvb/frontend.h> | ||
35 | |||
36 | #include "dmxdev.h" | ||
37 | #include "dvbdev.h" | ||
38 | #include "dvb_demux.h" | ||
39 | #include "dvb_ca_en50221.h" | ||
40 | #include "dvb_frontend.h" | ||
41 | #include "dvb_ringbuffer.h" | ||
42 | #include "dvb_net.h" | ||
43 | #include "cxd2099.h" | ||
44 | |||
45 | #define DEVICE_NAME "ngene" | ||
46 | |||
47 | #define NGENE_VID 0x18c3 | ||
48 | #define NGENE_PID 0x0720 | ||
49 | |||
50 | #ifndef VIDEO_CAP_VC1 | ||
51 | #define VIDEO_CAP_AVC 128 | ||
52 | #define VIDEO_CAP_H264 128 | ||
53 | #define VIDEO_CAP_VC1 256 | ||
54 | #define VIDEO_CAP_WMV9 256 | ||
55 | #define VIDEO_CAP_MPEG4 512 | ||
56 | #endif | ||
57 | |||
58 | enum STREAM { | ||
59 | STREAM_VIDEOIN1 = 0, /* ITU656 or TS Input */ | ||
60 | STREAM_VIDEOIN2, | ||
61 | STREAM_AUDIOIN1, /* I2S or SPI Input */ | ||
62 | STREAM_AUDIOIN2, | ||
63 | STREAM_AUDIOOUT, | ||
64 | MAX_STREAM | ||
65 | }; | ||
66 | |||
67 | enum SMODE_BITS { | ||
68 | SMODE_AUDIO_SPDIF = 0x20, | ||
69 | SMODE_AVSYNC = 0x10, | ||
70 | SMODE_TRANSPORT_STREAM = 0x08, | ||
71 | SMODE_AUDIO_CAPTURE = 0x04, | ||
72 | SMODE_VBI_CAPTURE = 0x02, | ||
73 | SMODE_VIDEO_CAPTURE = 0x01 | ||
74 | }; | ||
75 | |||
76 | enum STREAM_FLAG_BITS { | ||
77 | SFLAG_CHROMA_FORMAT_2COMP = 0x01, /* Chroma Format : 2's complement */ | ||
78 | SFLAG_CHROMA_FORMAT_OFFSET = 0x00, /* Chroma Format : Binary offset */ | ||
79 | SFLAG_ORDER_LUMA_CHROMA = 0x02, /* Byte order: Y,Cb,Y,Cr */ | ||
80 | SFLAG_ORDER_CHROMA_LUMA = 0x00, /* Byte order: Cb,Y,Cr,Y */ | ||
81 | SFLAG_COLORBAR = 0x04, /* Select colorbar */ | ||
82 | }; | ||
83 | |||
84 | #define PROGRAM_ROM 0x0000 | ||
85 | #define PROGRAM_SRAM 0x1000 | ||
86 | #define PERIPHERALS0 0x8000 | ||
87 | #define PERIPHERALS1 0x9000 | ||
88 | #define SHARED_BUFFER 0xC000 | ||
89 | |||
90 | #define HOST_TO_NGENE (SHARED_BUFFER+0x0000) | ||
91 | #define NGENE_TO_HOST (SHARED_BUFFER+0x0100) | ||
92 | #define NGENE_COMMAND (SHARED_BUFFER+0x0200) | ||
93 | #define NGENE_COMMAND_HI (SHARED_BUFFER+0x0204) | ||
94 | #define NGENE_STATUS (SHARED_BUFFER+0x0208) | ||
95 | #define NGENE_STATUS_HI (SHARED_BUFFER+0x020C) | ||
96 | #define NGENE_EVENT (SHARED_BUFFER+0x0210) | ||
97 | #define NGENE_EVENT_HI (SHARED_BUFFER+0x0214) | ||
98 | #define VARIABLES (SHARED_BUFFER+0x0210) | ||
99 | |||
100 | #define NGENE_INT_COUNTS (SHARED_BUFFER+0x0260) | ||
101 | #define NGENE_INT_ENABLE (SHARED_BUFFER+0x0264) | ||
102 | #define NGENE_VBI_LINE_COUNT (SHARED_BUFFER+0x0268) | ||
103 | |||
104 | #define BUFFER_GP_XMIT (SHARED_BUFFER+0x0800) | ||
105 | #define BUFFER_GP_RECV (SHARED_BUFFER+0x0900) | ||
106 | #define EEPROM_AREA (SHARED_BUFFER+0x0A00) | ||
107 | |||
108 | #define SG_V_IN_1 (SHARED_BUFFER+0x0A80) | ||
109 | #define SG_VBI_1 (SHARED_BUFFER+0x0B00) | ||
110 | #define SG_A_IN_1 (SHARED_BUFFER+0x0B80) | ||
111 | #define SG_V_IN_2 (SHARED_BUFFER+0x0C00) | ||
112 | #define SG_VBI_2 (SHARED_BUFFER+0x0C80) | ||
113 | #define SG_A_IN_2 (SHARED_BUFFER+0x0D00) | ||
114 | #define SG_V_OUT (SHARED_BUFFER+0x0D80) | ||
115 | #define SG_A_OUT2 (SHARED_BUFFER+0x0E00) | ||
116 | |||
117 | #define DATA_A_IN_1 (SHARED_BUFFER+0x0E80) | ||
118 | #define DATA_A_IN_2 (SHARED_BUFFER+0x0F00) | ||
119 | #define DATA_A_OUT (SHARED_BUFFER+0x0F80) | ||
120 | #define DATA_V_IN_1 (SHARED_BUFFER+0x1000) | ||
121 | #define DATA_V_IN_2 (SHARED_BUFFER+0x2000) | ||
122 | #define DATA_V_OUT (SHARED_BUFFER+0x3000) | ||
123 | |||
124 | #define DATA_FIFO_AREA (SHARED_BUFFER+0x1000) | ||
125 | |||
126 | #define TIMESTAMPS 0xA000 | ||
127 | #define SCRATCHPAD 0xA080 | ||
128 | #define FORCE_INT 0xA088 | ||
129 | #define FORCE_NMI 0xA090 | ||
130 | #define INT_STATUS 0xA0A0 | ||
131 | |||
132 | #define DEV_VER 0x9004 | ||
133 | |||
134 | #define FW_DEBUG_DEFAULT (PROGRAM_SRAM+0x00FF) | ||
135 | |||
136 | struct SG_ADDR { | ||
137 | u64 start; | ||
138 | u64 curr; | ||
139 | u16 curr_ptr; | ||
140 | u16 elements; | ||
141 | u32 pad[3]; | ||
142 | } __attribute__ ((__packed__)); | ||
143 | |||
144 | struct SHARED_MEMORY { | ||
145 | /* C000 */ | ||
146 | u32 HostToNgene[64]; | ||
147 | |||
148 | /* C100 */ | ||
149 | u32 NgeneToHost[64]; | ||
150 | |||
151 | /* C200 */ | ||
152 | u64 NgeneCommand; | ||
153 | u64 NgeneStatus; | ||
154 | u64 NgeneEvent; | ||
155 | |||
156 | /* C210 */ | ||
157 | u8 pad1[0xc260 - 0xc218]; | ||
158 | |||
159 | /* C260 */ | ||
160 | u32 IntCounts; | ||
161 | u32 IntEnable; | ||
162 | |||
163 | /* C268 */ | ||
164 | u8 pad2[0xd000 - 0xc268]; | ||
165 | |||
166 | } __attribute__ ((__packed__)); | ||
167 | |||
168 | struct BUFFER_STREAM_RESULTS { | ||
169 | u32 Clock; /* Stream time in 100ns units */ | ||
170 | u16 RemainingLines; /* Remaining lines in this field. | ||
171 | 0 for complete field */ | ||
172 | u8 FieldCount; /* Video field number */ | ||
173 | u8 Flags; /* Bit 7 = Done, Bit 6 = seen, Bit 5 = overflow, | ||
174 | Bit 0 = FieldID */ | ||
175 | u16 BlockCount; /* Audio block count (unused) */ | ||
176 | u8 Reserved[2]; | ||
177 | u32 DTOUpdate; | ||
178 | } __attribute__ ((__packed__)); | ||
179 | |||
180 | struct HW_SCATTER_GATHER_ELEMENT { | ||
181 | u64 Address; | ||
182 | u32 Length; | ||
183 | u32 Reserved; | ||
184 | } __attribute__ ((__packed__)); | ||
185 | |||
186 | struct BUFFER_HEADER { | ||
187 | u64 Next; | ||
188 | struct BUFFER_STREAM_RESULTS SR; | ||
189 | |||
190 | u32 Number_of_entries_1; | ||
191 | u32 Reserved5; | ||
192 | u64 Address_of_first_entry_1; | ||
193 | |||
194 | u32 Number_of_entries_2; | ||
195 | u32 Reserved7; | ||
196 | u64 Address_of_first_entry_2; | ||
197 | } __attribute__ ((__packed__)); | ||
198 | |||
199 | struct EVENT_BUFFER { | ||
200 | u32 TimeStamp; | ||
201 | u8 GPIOStatus; | ||
202 | u8 UARTStatus; | ||
203 | u8 RXCharacter; | ||
204 | u8 EventStatus; | ||
205 | u32 Reserved[2]; | ||
206 | } __attribute__ ((__packed__)); | ||
207 | |||
208 | /* Firmware commands. */ | ||
209 | |||
210 | enum OPCODES { | ||
211 | CMD_NOP = 0, | ||
212 | CMD_FWLOAD_PREPARE = 0x01, | ||
213 | CMD_FWLOAD_FINISH = 0x02, | ||
214 | CMD_I2C_READ = 0x03, | ||
215 | CMD_I2C_WRITE = 0x04, | ||
216 | |||
217 | CMD_I2C_WRITE_NOSTOP = 0x05, | ||
218 | CMD_I2C_CONTINUE_WRITE = 0x06, | ||
219 | CMD_I2C_CONTINUE_WRITE_NOSTOP = 0x07, | ||
220 | |||
221 | CMD_DEBUG_OUTPUT = 0x09, | ||
222 | |||
223 | CMD_CONTROL = 0x10, | ||
224 | CMD_CONFIGURE_BUFFER = 0x11, | ||
225 | CMD_CONFIGURE_FREE_BUFFER = 0x12, | ||
226 | |||
227 | CMD_SPI_READ = 0x13, | ||
228 | CMD_SPI_WRITE = 0x14, | ||
229 | |||
230 | CMD_MEM_READ = 0x20, | ||
231 | CMD_MEM_WRITE = 0x21, | ||
232 | CMD_SFR_READ = 0x22, | ||
233 | CMD_SFR_WRITE = 0x23, | ||
234 | CMD_IRAM_READ = 0x24, | ||
235 | CMD_IRAM_WRITE = 0x25, | ||
236 | CMD_SET_GPIO_PIN = 0x26, | ||
237 | CMD_SET_GPIO_INT = 0x27, | ||
238 | CMD_CONFIGURE_UART = 0x28, | ||
239 | CMD_WRITE_UART = 0x29, | ||
240 | MAX_CMD | ||
241 | }; | ||
242 | |||
243 | enum RESPONSES { | ||
244 | OK = 0, | ||
245 | ERROR = 1 | ||
246 | }; | ||
247 | |||
248 | struct FW_HEADER { | ||
249 | u8 Opcode; | ||
250 | u8 Length; | ||
251 | } __attribute__ ((__packed__)); | ||
252 | |||
253 | struct FW_I2C_WRITE { | ||
254 | struct FW_HEADER hdr; | ||
255 | u8 Device; | ||
256 | u8 Data[250]; | ||
257 | } __attribute__ ((__packed__)); | ||
258 | |||
259 | struct FW_I2C_CONTINUE_WRITE { | ||
260 | struct FW_HEADER hdr; | ||
261 | u8 Data[250]; | ||
262 | } __attribute__ ((__packed__)); | ||
263 | |||
264 | struct FW_I2C_READ { | ||
265 | struct FW_HEADER hdr; | ||
266 | u8 Device; | ||
267 | u8 Data[252]; /* followed by two bytes of read data count */ | ||
268 | } __attribute__ ((__packed__)); | ||
269 | |||
270 | struct FW_SPI_WRITE { | ||
271 | struct FW_HEADER hdr; | ||
272 | u8 ModeSelect; | ||
273 | u8 Data[250]; | ||
274 | } __attribute__ ((__packed__)); | ||
275 | |||
276 | struct FW_SPI_READ { | ||
277 | struct FW_HEADER hdr; | ||
278 | u8 ModeSelect; | ||
279 | u8 Data[252]; /* followed by two bytes of read data count */ | ||
280 | } __attribute__ ((__packed__)); | ||
281 | |||
282 | struct FW_FWLOAD_PREPARE { | ||
283 | struct FW_HEADER hdr; | ||
284 | } __attribute__ ((__packed__)); | ||
285 | |||
286 | struct FW_FWLOAD_FINISH { | ||
287 | struct FW_HEADER hdr; | ||
288 | u16 Address; /* address of final block */ | ||
289 | u16 Length; | ||
290 | } __attribute__ ((__packed__)); | ||
291 | |||
292 | /* | ||
293 | * Meaning of FW_STREAM_CONTROL::Mode bits: | ||
294 | * Bit 7: Loopback PEXin to PEXout using TVOut channel | ||
295 | * Bit 6: AVLOOP | ||
296 | * Bit 5: Audio select; 0=I2S, 1=SPDIF | ||
297 | * Bit 4: AVSYNC | ||
298 | * Bit 3: Enable transport stream | ||
299 | * Bit 2: Enable audio capture | ||
300 | * Bit 1: Enable ITU-Video VBI capture | ||
301 | * Bit 0: Enable ITU-Video capture | ||
302 | * | ||
303 | * Meaning of FW_STREAM_CONTROL::Control bits (see UVI1_CTL) | ||
304 | * Bit 7: continuous capture | ||
305 | * Bit 6: capture one field | ||
306 | * Bit 5: capture one frame | ||
307 | * Bit 4: unused | ||
308 | * Bit 3: starting field; 0=odd, 1=even | ||
309 | * Bit 2: sample size; 0=8-bit, 1=10-bit | ||
310 | * Bit 1: data format; 0=UYVY, 1=YUY2 | ||
311 | * Bit 0: resets buffer pointers | ||
312 | */ | ||
313 | |||
314 | enum FSC_MODE_BITS { | ||
315 | SMODE_LOOPBACK = 0x80, | ||
316 | SMODE_AVLOOP = 0x40, | ||
317 | _SMODE_AUDIO_SPDIF = 0x20, | ||
318 | _SMODE_AVSYNC = 0x10, | ||
319 | _SMODE_TRANSPORT_STREAM = 0x08, | ||
320 | _SMODE_AUDIO_CAPTURE = 0x04, | ||
321 | _SMODE_VBI_CAPTURE = 0x02, | ||
322 | _SMODE_VIDEO_CAPTURE = 0x01 | ||
323 | }; | ||
324 | |||
325 | |||
326 | /* Meaning of FW_STREAM_CONTROL::Stream bits: | ||
327 | * Bit 3: Audio sample count: 0 = relative, 1 = absolute | ||
328 | * Bit 2: color bar select; 1=color bars, 0=CV3 decoder | ||
329 | * Bits 1-0: stream select, UVI1, UVI2, TVOUT | ||
330 | */ | ||
331 | |||
332 | struct FW_STREAM_CONTROL { | ||
333 | struct FW_HEADER hdr; | ||
334 | u8 Stream; /* Stream number (UVI1, UVI2, TVOUT) */ | ||
335 | u8 Control; /* Value written to UVI1_CTL */ | ||
336 | u8 Mode; /* Controls clock source */ | ||
337 | u8 SetupDataLen; /* Length of setup data, MSB=1 write | ||
338 | backwards */ | ||
339 | u16 CaptureBlockCount; /* Blocks (a 256 Bytes) to capture per buffer | ||
340 | for TS and Audio */ | ||
341 | u64 Buffer_Address; /* Address of first buffer header */ | ||
342 | u16 BytesPerVideoLine; | ||
343 | u16 MaxLinesPerField; | ||
344 | u16 MinLinesPerField; | ||
345 | u16 Reserved_1; | ||
346 | u16 BytesPerVBILine; | ||
347 | u16 MaxVBILinesPerField; | ||
348 | u16 MinVBILinesPerField; | ||
349 | u16 SetupDataAddr; /* ngene relative address of setup data */ | ||
350 | u8 SetupData[32]; /* setup data */ | ||
351 | } __attribute__((__packed__)); | ||
352 | |||
353 | #define AUDIO_BLOCK_SIZE 256 | ||
354 | #define TS_BLOCK_SIZE 256 | ||
355 | |||
356 | struct FW_MEM_READ { | ||
357 | struct FW_HEADER hdr; | ||
358 | u16 address; | ||
359 | } __attribute__ ((__packed__)); | ||
360 | |||
361 | struct FW_MEM_WRITE { | ||
362 | struct FW_HEADER hdr; | ||
363 | u16 address; | ||
364 | u8 data; | ||
365 | } __attribute__ ((__packed__)); | ||
366 | |||
367 | struct FW_SFR_IRAM_READ { | ||
368 | struct FW_HEADER hdr; | ||
369 | u8 address; | ||
370 | } __attribute__ ((__packed__)); | ||
371 | |||
372 | struct FW_SFR_IRAM_WRITE { | ||
373 | struct FW_HEADER hdr; | ||
374 | u8 address; | ||
375 | u8 data; | ||
376 | } __attribute__ ((__packed__)); | ||
377 | |||
378 | struct FW_SET_GPIO_PIN { | ||
379 | struct FW_HEADER hdr; | ||
380 | u8 select; | ||
381 | } __attribute__ ((__packed__)); | ||
382 | |||
383 | struct FW_SET_GPIO_INT { | ||
384 | struct FW_HEADER hdr; | ||
385 | u8 select; | ||
386 | } __attribute__ ((__packed__)); | ||
387 | |||
388 | struct FW_SET_DEBUGMODE { | ||
389 | struct FW_HEADER hdr; | ||
390 | u8 debug_flags; | ||
391 | } __attribute__ ((__packed__)); | ||
392 | |||
393 | struct FW_CONFIGURE_BUFFERS { | ||
394 | struct FW_HEADER hdr; | ||
395 | u8 config; | ||
396 | } __attribute__ ((__packed__)); | ||
397 | |||
398 | enum _BUFFER_CONFIGS { | ||
399 | /* 4k UVI1, 4k UVI2, 2k AUD1, 2k AUD2 (standard usage) */ | ||
400 | BUFFER_CONFIG_4422 = 0, | ||
401 | /* 3k UVI1, 3k UVI2, 3k AUD1, 3k AUD2 (4x TS input usage) */ | ||
402 | BUFFER_CONFIG_3333 = 1, | ||
403 | /* 8k UVI1, 0k UVI2, 2k AUD1, 2k I2SOut (HDTV decoder usage) */ | ||
404 | BUFFER_CONFIG_8022 = 2, | ||
405 | BUFFER_CONFIG_FW17 = 255, /* Use new FW 17 command */ | ||
406 | }; | ||
407 | |||
408 | struct FW_CONFIGURE_FREE_BUFFERS { | ||
409 | struct FW_HEADER hdr; | ||
410 | u8 UVI1_BufferLength; | ||
411 | u8 UVI2_BufferLength; | ||
412 | u8 TVO_BufferLength; | ||
413 | u8 AUD1_BufferLength; | ||
414 | u8 AUD2_BufferLength; | ||
415 | u8 TVA_BufferLength; | ||
416 | } __attribute__ ((__packed__)); | ||
417 | |||
418 | struct FW_CONFIGURE_UART { | ||
419 | struct FW_HEADER hdr; | ||
420 | u8 UartControl; | ||
421 | } __attribute__ ((__packed__)); | ||
422 | |||
423 | enum _UART_CONFIG { | ||
424 | _UART_BAUDRATE_19200 = 0, | ||
425 | _UART_BAUDRATE_9600 = 1, | ||
426 | _UART_BAUDRATE_4800 = 2, | ||
427 | _UART_BAUDRATE_2400 = 3, | ||
428 | _UART_RX_ENABLE = 0x40, | ||
429 | _UART_TX_ENABLE = 0x80, | ||
430 | }; | ||
431 | |||
432 | struct FW_WRITE_UART { | ||
433 | struct FW_HEADER hdr; | ||
434 | u8 Data[252]; | ||
435 | } __attribute__ ((__packed__)); | ||
436 | |||
437 | |||
438 | struct ngene_command { | ||
439 | u32 in_len; | ||
440 | u32 out_len; | ||
441 | union { | ||
442 | u32 raw[64]; | ||
443 | u8 raw8[256]; | ||
444 | struct FW_HEADER hdr; | ||
445 | struct FW_I2C_WRITE I2CWrite; | ||
446 | struct FW_I2C_CONTINUE_WRITE I2CContinueWrite; | ||
447 | struct FW_I2C_READ I2CRead; | ||
448 | struct FW_STREAM_CONTROL StreamControl; | ||
449 | struct FW_FWLOAD_PREPARE FWLoadPrepare; | ||
450 | struct FW_FWLOAD_FINISH FWLoadFinish; | ||
451 | struct FW_MEM_READ MemoryRead; | ||
452 | struct FW_MEM_WRITE MemoryWrite; | ||
453 | struct FW_SFR_IRAM_READ SfrIramRead; | ||
454 | struct FW_SFR_IRAM_WRITE SfrIramWrite; | ||
455 | struct FW_SPI_WRITE SPIWrite; | ||
456 | struct FW_SPI_READ SPIRead; | ||
457 | struct FW_SET_GPIO_PIN SetGpioPin; | ||
458 | struct FW_SET_GPIO_INT SetGpioInt; | ||
459 | struct FW_SET_DEBUGMODE SetDebugMode; | ||
460 | struct FW_CONFIGURE_BUFFERS ConfigureBuffers; | ||
461 | struct FW_CONFIGURE_FREE_BUFFERS ConfigureFreeBuffers; | ||
462 | struct FW_CONFIGURE_UART ConfigureUart; | ||
463 | struct FW_WRITE_UART WriteUart; | ||
464 | } cmd; | ||
465 | } __attribute__ ((__packed__)); | ||
466 | |||
467 | #define NGENE_INTERFACE_VERSION 0x103 | ||
468 | #define MAX_VIDEO_BUFFER_SIZE (417792) /* 288*1440 rounded up to next page */ | ||
469 | #define MAX_AUDIO_BUFFER_SIZE (8192) /* Gives room for about 23msec@48KHz */ | ||
470 | #define MAX_VBI_BUFFER_SIZE (28672) /* 1144*18 rounded up to next page */ | ||
471 | #define MAX_TS_BUFFER_SIZE (98304) /* 512*188 rounded up to next page */ | ||
472 | #define MAX_HDTV_BUFFER_SIZE (2080768) /* 541*1920*2 rounded up to next page | ||
473 | Max: (1920x1080i60) */ | ||
474 | |||
475 | #define OVERFLOW_BUFFER_SIZE (8192) | ||
476 | |||
477 | #define RING_SIZE_VIDEO 4 | ||
478 | #define RING_SIZE_AUDIO 8 | ||
479 | #define RING_SIZE_TS 8 | ||
480 | |||
481 | #define NUM_SCATTER_GATHER_ENTRIES 8 | ||
482 | |||
483 | #define MAX_DMA_LENGTH (((MAX_VIDEO_BUFFER_SIZE + MAX_VBI_BUFFER_SIZE) * \ | ||
484 | RING_SIZE_VIDEO * 2) + \ | ||
485 | (MAX_AUDIO_BUFFER_SIZE * RING_SIZE_AUDIO * 2) + \ | ||
486 | (MAX_TS_BUFFER_SIZE * RING_SIZE_TS * 4) + \ | ||
487 | (RING_SIZE_VIDEO * PAGE_SIZE * 2) + \ | ||
488 | (RING_SIZE_AUDIO * PAGE_SIZE * 2) + \ | ||
489 | (RING_SIZE_TS * PAGE_SIZE * 4) + \ | ||
490 | 8 * PAGE_SIZE + OVERFLOW_BUFFER_SIZE + PAGE_SIZE) | ||
491 | |||
492 | #define EVENT_QUEUE_SIZE 16 | ||
493 | |||
494 | /* Gathers the current state of a single channel. */ | ||
495 | |||
496 | struct SBufferHeader { | ||
497 | struct BUFFER_HEADER ngeneBuffer; /* Physical descriptor */ | ||
498 | struct SBufferHeader *Next; | ||
499 | void *Buffer1; | ||
500 | struct HW_SCATTER_GATHER_ELEMENT *scList1; | ||
501 | void *Buffer2; | ||
502 | struct HW_SCATTER_GATHER_ELEMENT *scList2; | ||
503 | }; | ||
504 | |||
505 | /* Sizeof SBufferHeader aligned to next 64 Bit boundary (hw restriction) */ | ||
506 | #define SIZEOF_SBufferHeader ((sizeof(struct SBufferHeader) + 63) & ~63) | ||
507 | |||
508 | enum HWSTATE { | ||
509 | HWSTATE_STOP, | ||
510 | HWSTATE_STARTUP, | ||
511 | HWSTATE_RUN, | ||
512 | HWSTATE_PAUSE, | ||
513 | }; | ||
514 | |||
515 | enum KSSTATE { | ||
516 | KSSTATE_STOP, | ||
517 | KSSTATE_ACQUIRE, | ||
518 | KSSTATE_PAUSE, | ||
519 | KSSTATE_RUN, | ||
520 | }; | ||
521 | |||
522 | struct SRingBufferDescriptor { | ||
523 | struct SBufferHeader *Head; /* Points to first buffer in ring buffer | ||
524 | structure*/ | ||
525 | u64 PAHead; /* Physical address of first buffer */ | ||
526 | u32 MemSize; /* Memory size of allocated ring buffers | ||
527 | (needed for freeing) */ | ||
528 | u32 NumBuffers; /* Number of buffers in the ring */ | ||
529 | u32 Buffer1Length; /* Allocated length of Buffer 1 */ | ||
530 | u32 Buffer2Length; /* Allocated length of Buffer 2 */ | ||
531 | void *SCListMem; /* Memory to hold scatter gather lists for this | ||
532 | ring */ | ||
533 | u64 PASCListMem; /* Physical address .. */ | ||
534 | u32 SCListMemSize; /* Size of this memory */ | ||
535 | }; | ||
536 | |||
537 | enum STREAMMODEFLAGS { | ||
538 | StreamMode_NONE = 0, /* Stream not used */ | ||
539 | StreamMode_ANALOG = 1, /* Analog: Stream 0,1 = Video, 2,3 = Audio */ | ||
540 | StreamMode_TSIN = 2, /* Transport stream input (all) */ | ||
541 | StreamMode_HDTV = 4, /* HDTV: Maximum 1920x1080p30,1920x1080i60 | ||
542 | (only stream 0) */ | ||
543 | StreamMode_TSOUT = 8, /* Transport stream output (only stream 3) */ | ||
544 | }; | ||
545 | |||
546 | |||
547 | enum BufferExchangeFlags { | ||
548 | BEF_EVEN_FIELD = 0x00000001, | ||
549 | BEF_CONTINUATION = 0x00000002, | ||
550 | BEF_MORE_DATA = 0x00000004, | ||
551 | BEF_OVERFLOW = 0x00000008, | ||
552 | DF_SWAP32 = 0x00010000, | ||
553 | }; | ||
554 | |||
555 | typedef void *(IBufferExchange)(void *, void *, u32, u32, u32); | ||
556 | |||
557 | struct MICI_STREAMINFO { | ||
558 | IBufferExchange *pExchange; | ||
559 | IBufferExchange *pExchangeVBI; /* Secondary (VBI, ancillary) */ | ||
560 | u8 Stream; | ||
561 | u8 Flags; | ||
562 | u8 Mode; | ||
563 | u8 Reserved; | ||
564 | u16 nLinesVideo; | ||
565 | u16 nBytesPerLineVideo; | ||
566 | u16 nLinesVBI; | ||
567 | u16 nBytesPerLineVBI; | ||
568 | u32 CaptureLength; /* Used for audio and transport stream */ | ||
569 | }; | ||
570 | |||
571 | /****************************************************************************/ | ||
572 | /* STRUCTS ******************************************************************/ | ||
573 | /****************************************************************************/ | ||
574 | |||
575 | /* sound hardware definition */ | ||
576 | #define MIXER_ADDR_TVTUNER 0 | ||
577 | #define MIXER_ADDR_LAST 0 | ||
578 | |||
579 | struct ngene_channel; | ||
580 | |||
581 | /*struct sound chip*/ | ||
582 | |||
583 | struct mychip { | ||
584 | struct ngene_channel *chan; | ||
585 | struct snd_card *card; | ||
586 | struct pci_dev *pci; | ||
587 | struct snd_pcm_substream *substream; | ||
588 | struct snd_pcm *pcm; | ||
589 | unsigned long port; | ||
590 | int irq; | ||
591 | spinlock_t mixer_lock; | ||
592 | spinlock_t lock; | ||
593 | int mixer_volume[MIXER_ADDR_LAST + 1][2]; | ||
594 | int capture_source[MIXER_ADDR_LAST + 1][2]; | ||
595 | }; | ||
596 | |||
597 | #ifdef NGENE_V4L | ||
598 | struct ngene_overlay { | ||
599 | int tvnorm; | ||
600 | struct v4l2_rect w; | ||
601 | enum v4l2_field field; | ||
602 | struct v4l2_clip *clips; | ||
603 | int nclips; | ||
604 | int setup_ok; | ||
605 | }; | ||
606 | |||
607 | struct ngene_tvnorm { | ||
608 | int v4l2_id; | ||
609 | char *name; | ||
610 | u16 swidth, sheight; /* scaled standard width, height */ | ||
611 | int tuner_norm; | ||
612 | int soundstd; | ||
613 | }; | ||
614 | |||
615 | struct ngene_vopen { | ||
616 | struct ngene_channel *ch; | ||
617 | enum v4l2_priority prio; | ||
618 | int width; | ||
619 | int height; | ||
620 | int depth; | ||
621 | struct videobuf_queue vbuf_q; | ||
622 | struct videobuf_queue vbi; | ||
623 | int fourcc; | ||
624 | int picxcount; | ||
625 | int resources; | ||
626 | enum v4l2_buf_type type; | ||
627 | const struct ngene_format *fmt; | ||
628 | |||
629 | const struct ngene_format *ovfmt; | ||
630 | struct ngene_overlay ov; | ||
631 | }; | ||
632 | #endif | ||
633 | |||
634 | struct ngene_channel { | ||
635 | struct device device; | ||
636 | struct i2c_adapter i2c_adapter; | ||
637 | |||
638 | struct ngene *dev; | ||
639 | int number; | ||
640 | int type; | ||
641 | int mode; | ||
642 | bool has_adapter; | ||
643 | bool has_demux; | ||
644 | int demod_type; | ||
645 | int (*gate_ctrl)(struct dvb_frontend *, int); | ||
646 | |||
647 | struct dvb_frontend *fe; | ||
648 | struct dvb_frontend *fe2; | ||
649 | struct dmxdev dmxdev; | ||
650 | struct dvb_demux demux; | ||
651 | struct dvb_net dvbnet; | ||
652 | struct dmx_frontend hw_frontend; | ||
653 | struct dmx_frontend mem_frontend; | ||
654 | int users; | ||
655 | struct video_device *v4l_dev; | ||
656 | struct dvb_device *ci_dev; | ||
657 | struct tasklet_struct demux_tasklet; | ||
658 | |||
659 | struct SBufferHeader *nextBuffer; | ||
660 | enum KSSTATE State; | ||
661 | enum HWSTATE HWState; | ||
662 | u8 Stream; | ||
663 | u8 Flags; | ||
664 | u8 Mode; | ||
665 | IBufferExchange *pBufferExchange; | ||
666 | IBufferExchange *pBufferExchange2; | ||
667 | |||
668 | spinlock_t state_lock; | ||
669 | u16 nLines; | ||
670 | u16 nBytesPerLine; | ||
671 | u16 nVBILines; | ||
672 | u16 nBytesPerVBILine; | ||
673 | u16 itumode; | ||
674 | u32 Capture1Length; | ||
675 | u32 Capture2Length; | ||
676 | struct SRingBufferDescriptor RingBuffer; | ||
677 | struct SRingBufferDescriptor TSRingBuffer; | ||
678 | struct SRingBufferDescriptor TSIdleBuffer; | ||
679 | |||
680 | u32 DataFormatFlags; | ||
681 | |||
682 | int AudioDTOUpdated; | ||
683 | u32 AudioDTOValue; | ||
684 | |||
685 | int (*set_tone)(struct dvb_frontend *, fe_sec_tone_mode_t); | ||
686 | u8 lnbh; | ||
687 | |||
688 | /* stuff from analog driver */ | ||
689 | |||
690 | int minor; | ||
691 | struct mychip *mychip; | ||
692 | struct snd_card *soundcard; | ||
693 | u8 *evenbuffer; | ||
694 | u8 dma_on; | ||
695 | int soundstreamon; | ||
696 | int audiomute; | ||
697 | int soundbuffisallocated; | ||
698 | int sndbuffflag; | ||
699 | int tun_rdy; | ||
700 | int dec_rdy; | ||
701 | int tun_dec_rdy; | ||
702 | int lastbufferflag; | ||
703 | |||
704 | struct ngene_tvnorm *tvnorms; | ||
705 | int tvnorm_num; | ||
706 | int tvnorm; | ||
707 | |||
708 | #ifdef NGENE_V4L | ||
709 | int videousers; | ||
710 | struct v4l2_prio_state prio; | ||
711 | struct ngene_vopen init; | ||
712 | int resources; | ||
713 | struct v4l2_framebuffer fbuf; | ||
714 | struct ngene_buffer *screen; /* overlay */ | ||
715 | struct list_head capture; /* video capture queue */ | ||
716 | spinlock_t s_lock; | ||
717 | struct semaphore reslock; | ||
718 | #endif | ||
719 | |||
720 | int running; | ||
721 | }; | ||
722 | |||
723 | |||
724 | struct ngene_ci { | ||
725 | struct device device; | ||
726 | struct i2c_adapter i2c_adapter; | ||
727 | |||
728 | struct ngene *dev; | ||
729 | struct dvb_ca_en50221 *en; | ||
730 | }; | ||
731 | |||
732 | struct ngene; | ||
733 | |||
734 | typedef void (rx_cb_t)(struct ngene *, u32, u8); | ||
735 | typedef void (tx_cb_t)(struct ngene *, u32); | ||
736 | |||
737 | struct ngene { | ||
738 | int nr; | ||
739 | struct pci_dev *pci_dev; | ||
740 | unsigned char *iomem; | ||
741 | |||
742 | /*struct i2c_adapter i2c_adapter;*/ | ||
743 | |||
744 | u32 device_version; | ||
745 | u32 fw_interface_version; | ||
746 | u32 icounts; | ||
747 | bool msi_enabled; | ||
748 | bool cmd_timeout_workaround; | ||
749 | |||
750 | u8 *CmdDoneByte; | ||
751 | int BootFirmware; | ||
752 | void *OverflowBuffer; | ||
753 | dma_addr_t PAOverflowBuffer; | ||
754 | void *FWInterfaceBuffer; | ||
755 | dma_addr_t PAFWInterfaceBuffer; | ||
756 | u8 *ngenetohost; | ||
757 | u8 *hosttongene; | ||
758 | |||
759 | struct EVENT_BUFFER EventQueue[EVENT_QUEUE_SIZE]; | ||
760 | int EventQueueOverflowCount; | ||
761 | int EventQueueOverflowFlag; | ||
762 | struct tasklet_struct event_tasklet; | ||
763 | struct EVENT_BUFFER *EventBuffer; | ||
764 | int EventQueueWriteIndex; | ||
765 | int EventQueueReadIndex; | ||
766 | |||
767 | wait_queue_head_t cmd_wq; | ||
768 | int cmd_done; | ||
769 | struct semaphore cmd_mutex; | ||
770 | struct semaphore stream_mutex; | ||
771 | struct semaphore pll_mutex; | ||
772 | struct semaphore i2c_switch_mutex; | ||
773 | int i2c_current_channel; | ||
774 | int i2c_current_bus; | ||
775 | spinlock_t cmd_lock; | ||
776 | |||
777 | struct dvb_adapter adapter[MAX_STREAM]; | ||
778 | struct dvb_adapter *first_adapter; /* "one_adapter" modprobe opt */ | ||
779 | struct ngene_channel channel[MAX_STREAM]; | ||
780 | |||
781 | struct ngene_info *card_info; | ||
782 | |||
783 | tx_cb_t *TxEventNotify; | ||
784 | rx_cb_t *RxEventNotify; | ||
785 | int tx_busy; | ||
786 | wait_queue_head_t tx_wq; | ||
787 | wait_queue_head_t rx_wq; | ||
788 | #define UART_RBUF_LEN 4096 | ||
789 | u8 uart_rbuf[UART_RBUF_LEN]; | ||
790 | int uart_rp, uart_wp; | ||
791 | |||
792 | #define TS_FILLER 0x6f | ||
793 | |||
794 | u8 *tsout_buf; | ||
795 | #define TSOUT_BUF_SIZE (512*188*8) | ||
796 | struct dvb_ringbuffer tsout_rbuf; | ||
797 | |||
798 | u8 *tsin_buf; | ||
799 | #define TSIN_BUF_SIZE (512*188*8) | ||
800 | struct dvb_ringbuffer tsin_rbuf; | ||
801 | |||
802 | u8 *ain_buf; | ||
803 | #define AIN_BUF_SIZE (128*1024) | ||
804 | struct dvb_ringbuffer ain_rbuf; | ||
805 | |||
806 | |||
807 | u8 *vin_buf; | ||
808 | #define VIN_BUF_SIZE (4*1920*1080) | ||
809 | struct dvb_ringbuffer vin_rbuf; | ||
810 | |||
811 | unsigned long exp_val; | ||
812 | int prev_cmd; | ||
813 | |||
814 | struct ngene_ci ci; | ||
815 | }; | ||
816 | |||
817 | struct ngene_info { | ||
818 | int type; | ||
819 | #define NGENE_APP 0 | ||
820 | #define NGENE_TERRATEC 1 | ||
821 | #define NGENE_SIDEWINDER 2 | ||
822 | #define NGENE_RACER 3 | ||
823 | #define NGENE_VIPER 4 | ||
824 | #define NGENE_PYTHON 5 | ||
825 | #define NGENE_VBOX_V1 6 | ||
826 | #define NGENE_VBOX_V2 7 | ||
827 | |||
828 | int fw_version; | ||
829 | bool msi_supported; | ||
830 | char *name; | ||
831 | |||
832 | int io_type[MAX_STREAM]; | ||
833 | #define NGENE_IO_NONE 0 | ||
834 | #define NGENE_IO_TV 1 | ||
835 | #define NGENE_IO_HDTV 2 | ||
836 | #define NGENE_IO_TSIN 4 | ||
837 | #define NGENE_IO_TSOUT 8 | ||
838 | #define NGENE_IO_AIN 16 | ||
839 | |||
840 | void *fe_config[4]; | ||
841 | void *tuner_config[4]; | ||
842 | |||
843 | int (*demod_attach[4])(struct ngene_channel *); | ||
844 | int (*tuner_attach[4])(struct ngene_channel *); | ||
845 | |||
846 | u8 avf[4]; | ||
847 | u8 msp[4]; | ||
848 | u8 demoda[4]; | ||
849 | u8 lnb[4]; | ||
850 | int i2c_access; | ||
851 | u8 ntsc; | ||
852 | u8 tsf[4]; | ||
853 | u8 i2s[4]; | ||
854 | |||
855 | int (*gate_ctrl)(struct dvb_frontend *, int); | ||
856 | int (*switch_ctrl)(struct ngene_channel *, int, int); | ||
857 | }; | ||
858 | |||
859 | #ifdef NGENE_V4L | ||
860 | struct ngene_format { | ||
861 | char *name; | ||
862 | int fourcc; /* video4linux 2 */ | ||
863 | int btformat; /* BT848_COLOR_FMT_* */ | ||
864 | int format; | ||
865 | int btswap; /* BT848_COLOR_CTL_* */ | ||
866 | int depth; /* bit/pixel */ | ||
867 | int flags; | ||
868 | int hshift, vshift; /* for planar modes */ | ||
869 | int palette; | ||
870 | }; | ||
871 | |||
872 | #define RESOURCE_OVERLAY 1 | ||
873 | #define RESOURCE_VIDEO 2 | ||
874 | #define RESOURCE_VBI 4 | ||
875 | |||
876 | struct ngene_buffer { | ||
877 | /* common v4l buffer stuff -- must be first */ | ||
878 | struct videobuf_buffer vb; | ||
879 | |||
880 | /* ngene specific */ | ||
881 | const struct ngene_format *fmt; | ||
882 | int tvnorm; | ||
883 | int btformat; | ||
884 | int btswap; | ||
885 | }; | ||
886 | #endif | ||
887 | |||
888 | |||
889 | /* Provided by ngene-core.c */ | ||
890 | int __devinit ngene_probe(struct pci_dev *pci_dev, | ||
891 | const struct pci_device_id *id); | ||
892 | void __devexit ngene_remove(struct pci_dev *pdev); | ||
893 | void ngene_shutdown(struct pci_dev *pdev); | ||
894 | int ngene_command(struct ngene *dev, struct ngene_command *com); | ||
895 | int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level); | ||
896 | void set_transfer(struct ngene_channel *chan, int state); | ||
897 | void FillTSBuffer(void *Buffer, int Length, u32 Flags); | ||
898 | |||
899 | /* Provided by ngene-i2c.c */ | ||
900 | int ngene_i2c_init(struct ngene *dev, int dev_nr); | ||
901 | |||
902 | /* Provided by ngene-dvb.c */ | ||
903 | extern struct dvb_device ngene_dvbdev_ci; | ||
904 | void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); | ||
905 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); | ||
906 | int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed); | ||
907 | int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed); | ||
908 | int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, | ||
909 | int (*start_feed)(struct dvb_demux_feed *), | ||
910 | int (*stop_feed)(struct dvb_demux_feed *), | ||
911 | void *priv); | ||
912 | int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, | ||
913 | struct dvb_demux *dvbdemux, | ||
914 | struct dmx_frontend *hw_frontend, | ||
915 | struct dmx_frontend *mem_frontend, | ||
916 | struct dvb_adapter *dvb_adapter); | ||
917 | |||
918 | #endif | ||
919 | |||
920 | /* LocalWords: Endif | ||
921 | */ | ||
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig deleted file mode 100644 index 7d8e6e87bdbb..000000000000 --- a/drivers/media/dvb/pluto2/Kconfig +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | config DVB_PLUTO2 | ||
2 | tristate "Pluto2 cards" | ||
3 | depends on DVB_CORE && PCI && I2C | ||
4 | select I2C_ALGOBIT | ||
5 | select DVB_TDA1004X | ||
6 | help | ||
7 | Support for PCI cards based on the Pluto2 FPGA like the Satelco | ||
8 | Easywatch Mobile Terrestrial DVB-T Receiver. | ||
9 | |||
10 | Since these cards have no MPEG decoder onboard, they transmit | ||
11 | only compressed MPEG data over the PCI bus, so you need | ||
12 | an external software decoder to watch TV on your computer. | ||
13 | |||
14 | Say Y or M if you own such a device and want to use it. | ||
15 | |||
diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile deleted file mode 100644 index 524bf841f42b..000000000000 --- a/drivers/media/dvb/pluto2/Makefile +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | obj-$(CONFIG_DVB_PLUTO2) += pluto2.o | ||
2 | |||
3 | ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ | ||
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c deleted file mode 100644 index f148b19a206a..000000000000 --- a/drivers/media/dvb/pluto2/pluto2.c +++ /dev/null | |||
@@ -1,815 +0,0 @@ | |||
1 | /* | ||
2 | * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T] | ||
3 | * | ||
4 | * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org> | ||
5 | * | ||
6 | * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/ | ||
7 | * by Dany Salman <salmandany@yahoo.fr> | ||
8 | * Copyright (c) 2004 TDF | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/i2c-algo-bit.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/dma-mapping.h> | ||
34 | #include <linux/slab.h> | ||
35 | |||
36 | #include "demux.h" | ||
37 | #include "dmxdev.h" | ||
38 | #include "dvb_demux.h" | ||
39 | #include "dvb_frontend.h" | ||
40 | #include "dvb_net.h" | ||
41 | #include "dvbdev.h" | ||
42 | #include "tda1004x.h" | ||
43 | |||
44 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
45 | |||
46 | #define DRIVER_NAME "pluto2" | ||
47 | |||
48 | #define REG_PIDn(n) ((n) << 2) /* PID n pattern registers */ | ||
49 | #define REG_PCAR 0x0020 /* PC address register */ | ||
50 | #define REG_TSCR 0x0024 /* TS ctrl & status */ | ||
51 | #define REG_MISC 0x0028 /* miscellaneous */ | ||
52 | #define REG_MMAC 0x002c /* MSB MAC address */ | ||
53 | #define REG_IMAC 0x0030 /* ISB MAC address */ | ||
54 | #define REG_LMAC 0x0034 /* LSB MAC address */ | ||
55 | #define REG_SPID 0x0038 /* SPI data */ | ||
56 | #define REG_SLCS 0x003c /* serial links ctrl/status */ | ||
57 | |||
58 | #define PID0_NOFIL (0x0001 << 16) | ||
59 | #define PIDn_ENP (0x0001 << 15) | ||
60 | #define PID0_END (0x0001 << 14) | ||
61 | #define PID0_AFIL (0x0001 << 13) | ||
62 | #define PIDn_PID (0x1fff << 0) | ||
63 | |||
64 | #define TSCR_NBPACKETS (0x00ff << 24) | ||
65 | #define TSCR_DEM (0x0001 << 17) | ||
66 | #define TSCR_DE (0x0001 << 16) | ||
67 | #define TSCR_RSTN (0x0001 << 15) | ||
68 | #define TSCR_MSKO (0x0001 << 14) | ||
69 | #define TSCR_MSKA (0x0001 << 13) | ||
70 | #define TSCR_MSKL (0x0001 << 12) | ||
71 | #define TSCR_OVR (0x0001 << 11) | ||
72 | #define TSCR_AFUL (0x0001 << 10) | ||
73 | #define TSCR_LOCK (0x0001 << 9) | ||
74 | #define TSCR_IACK (0x0001 << 8) | ||
75 | #define TSCR_ADEF (0x007f << 0) | ||
76 | |||
77 | #define MISC_DVR (0x0fff << 4) | ||
78 | #define MISC_ALED (0x0001 << 3) | ||
79 | #define MISC_FRST (0x0001 << 2) | ||
80 | #define MISC_LED1 (0x0001 << 1) | ||
81 | #define MISC_LED0 (0x0001 << 0) | ||
82 | |||
83 | #define SPID_SPIDR (0x00ff << 0) | ||
84 | |||
85 | #define SLCS_SCL (0x0001 << 7) | ||
86 | #define SLCS_SDA (0x0001 << 6) | ||
87 | #define SLCS_CSN (0x0001 << 2) | ||
88 | #define SLCS_OVR (0x0001 << 1) | ||
89 | #define SLCS_SWC (0x0001 << 0) | ||
90 | |||
91 | #define TS_DMA_PACKETS (8) | ||
92 | #define TS_DMA_BYTES (188 * TS_DMA_PACKETS) | ||
93 | |||
94 | #define I2C_ADDR_TDA10046 0x10 | ||
95 | #define I2C_ADDR_TUA6034 0xc2 | ||
96 | #define NHWFILTERS 8 | ||
97 | |||
98 | struct pluto { | ||
99 | /* pci */ | ||
100 | struct pci_dev *pdev; | ||
101 | u8 __iomem *io_mem; | ||
102 | |||
103 | /* dvb */ | ||
104 | struct dmx_frontend hw_frontend; | ||
105 | struct dmx_frontend mem_frontend; | ||
106 | struct dmxdev dmxdev; | ||
107 | struct dvb_adapter dvb_adapter; | ||
108 | struct dvb_demux demux; | ||
109 | struct dvb_frontend *fe; | ||
110 | struct dvb_net dvbnet; | ||
111 | unsigned int full_ts_users; | ||
112 | unsigned int users; | ||
113 | |||
114 | /* i2c */ | ||
115 | struct i2c_algo_bit_data i2c_bit; | ||
116 | struct i2c_adapter i2c_adap; | ||
117 | unsigned int i2cbug; | ||
118 | |||
119 | /* irq */ | ||
120 | unsigned int overflow; | ||
121 | unsigned int dead; | ||
122 | |||
123 | /* dma */ | ||
124 | dma_addr_t dma_addr; | ||
125 | u8 dma_buf[TS_DMA_BYTES]; | ||
126 | u8 dummy[4096]; | ||
127 | }; | ||
128 | |||
129 | static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed) | ||
130 | { | ||
131 | return container_of(feed->demux, struct pluto, demux); | ||
132 | } | ||
133 | |||
134 | static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe) | ||
135 | { | ||
136 | return container_of(fe->dvb, struct pluto, dvb_adapter); | ||
137 | } | ||
138 | |||
139 | static inline u32 pluto_readreg(struct pluto *pluto, u32 reg) | ||
140 | { | ||
141 | return readl(&pluto->io_mem[reg]); | ||
142 | } | ||
143 | |||
144 | static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val) | ||
145 | { | ||
146 | writel(val, &pluto->io_mem[reg]); | ||
147 | } | ||
148 | |||
149 | static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits) | ||
150 | { | ||
151 | u32 val = readl(&pluto->io_mem[reg]); | ||
152 | val &= ~mask; | ||
153 | val |= bits; | ||
154 | writel(val, &pluto->io_mem[reg]); | ||
155 | } | ||
156 | |||
157 | static void pluto_write_tscr(struct pluto *pluto, u32 val) | ||
158 | { | ||
159 | /* set the number of packets */ | ||
160 | val &= ~TSCR_ADEF; | ||
161 | val |= TS_DMA_PACKETS / 2; | ||
162 | |||
163 | pluto_writereg(pluto, REG_TSCR, val); | ||
164 | } | ||
165 | |||
166 | static void pluto_setsda(void *data, int state) | ||
167 | { | ||
168 | struct pluto *pluto = data; | ||
169 | |||
170 | if (state) | ||
171 | pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA); | ||
172 | else | ||
173 | pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0); | ||
174 | } | ||
175 | |||
176 | static void pluto_setscl(void *data, int state) | ||
177 | { | ||
178 | struct pluto *pluto = data; | ||
179 | |||
180 | if (state) | ||
181 | pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL); | ||
182 | else | ||
183 | pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0); | ||
184 | |||
185 | /* try to detect i2c_inb() to workaround hardware bug: | ||
186 | * reset SDA to high after SCL has been set to low */ | ||
187 | if ((state) && (pluto->i2cbug == 0)) { | ||
188 | pluto->i2cbug = 1; | ||
189 | } else { | ||
190 | if ((!state) && (pluto->i2cbug == 1)) | ||
191 | pluto_setsda(pluto, 1); | ||
192 | pluto->i2cbug = 0; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | static int pluto_getsda(void *data) | ||
197 | { | ||
198 | struct pluto *pluto = data; | ||
199 | |||
200 | return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA; | ||
201 | } | ||
202 | |||
203 | static int pluto_getscl(void *data) | ||
204 | { | ||
205 | struct pluto *pluto = data; | ||
206 | |||
207 | return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL; | ||
208 | } | ||
209 | |||
210 | static void pluto_reset_frontend(struct pluto *pluto, int reenable) | ||
211 | { | ||
212 | u32 val = pluto_readreg(pluto, REG_MISC); | ||
213 | |||
214 | if (val & MISC_FRST) { | ||
215 | val &= ~MISC_FRST; | ||
216 | pluto_writereg(pluto, REG_MISC, val); | ||
217 | } | ||
218 | if (reenable) { | ||
219 | val |= MISC_FRST; | ||
220 | pluto_writereg(pluto, REG_MISC, val); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | static void pluto_reset_ts(struct pluto *pluto, int reenable) | ||
225 | { | ||
226 | u32 val = pluto_readreg(pluto, REG_TSCR); | ||
227 | |||
228 | if (val & TSCR_RSTN) { | ||
229 | val &= ~TSCR_RSTN; | ||
230 | pluto_write_tscr(pluto, val); | ||
231 | } | ||
232 | if (reenable) { | ||
233 | val |= TSCR_RSTN; | ||
234 | pluto_write_tscr(pluto, val); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | static void pluto_set_dma_addr(struct pluto *pluto) | ||
239 | { | ||
240 | pluto_writereg(pluto, REG_PCAR, pluto->dma_addr); | ||
241 | } | ||
242 | |||
243 | static int __devinit pluto_dma_map(struct pluto *pluto) | ||
244 | { | ||
245 | pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, | ||
246 | TS_DMA_BYTES, PCI_DMA_FROMDEVICE); | ||
247 | |||
248 | return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); | ||
249 | } | ||
250 | |||
251 | static void pluto_dma_unmap(struct pluto *pluto) | ||
252 | { | ||
253 | pci_unmap_single(pluto->pdev, pluto->dma_addr, | ||
254 | TS_DMA_BYTES, PCI_DMA_FROMDEVICE); | ||
255 | } | ||
256 | |||
257 | static int pluto_start_feed(struct dvb_demux_feed *f) | ||
258 | { | ||
259 | struct pluto *pluto = feed_to_pluto(f); | ||
260 | |||
261 | /* enable PID filtering */ | ||
262 | if (pluto->users++ == 0) | ||
263 | pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0); | ||
264 | |||
265 | if ((f->pid < 0x2000) && (f->index < NHWFILTERS)) | ||
266 | pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid); | ||
267 | else if (pluto->full_ts_users++ == 0) | ||
268 | pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int pluto_stop_feed(struct dvb_demux_feed *f) | ||
274 | { | ||
275 | struct pluto *pluto = feed_to_pluto(f); | ||
276 | |||
277 | /* disable PID filtering */ | ||
278 | if (--pluto->users == 0) | ||
279 | pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL); | ||
280 | |||
281 | if ((f->pid < 0x2000) && (f->index < NHWFILTERS)) | ||
282 | pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff); | ||
283 | else if (--pluto->full_ts_users == 0) | ||
284 | pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) | ||
290 | { | ||
291 | /* synchronize the DMA transfer with the CPU | ||
292 | * first so that we see updated contents. */ | ||
293 | pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr, | ||
294 | TS_DMA_BYTES, PCI_DMA_FROMDEVICE); | ||
295 | |||
296 | /* Workaround for broken hardware: | ||
297 | * [1] On startup NBPACKETS seems to contain an uninitialized value, | ||
298 | * but no packets have been transferred. | ||
299 | * [2] Sometimes (actually very often) NBPACKETS stays at zero | ||
300 | * although one packet has been transferred. | ||
301 | * [3] Sometimes (actually rarely), the card gets into an erroneous | ||
302 | * mode where it continuously generates interrupts, claiming it | ||
303 | * has received nbpackets>TS_DMA_PACKETS packets, but no packet | ||
304 | * has been transferred. Only a reset seems to solve this | ||
305 | */ | ||
306 | if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { | ||
307 | unsigned int i = 0; | ||
308 | while (pluto->dma_buf[i] == 0x47) | ||
309 | i += 188; | ||
310 | nbpackets = i / 188; | ||
311 | if (i == 0) { | ||
312 | pluto_reset_ts(pluto, 1); | ||
313 | dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n"); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); | ||
318 | |||
319 | /* clear the dma buffer. this is needed to be able to identify | ||
320 | * new valid ts packets above */ | ||
321 | memset(pluto->dma_buf, 0, nbpackets * 188); | ||
322 | |||
323 | /* reset the dma address */ | ||
324 | pluto_set_dma_addr(pluto); | ||
325 | |||
326 | /* sync the buffer and give it back to the card */ | ||
327 | pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr, | ||
328 | TS_DMA_BYTES, PCI_DMA_FROMDEVICE); | ||
329 | } | ||
330 | |||
331 | static irqreturn_t pluto_irq(int irq, void *dev_id) | ||
332 | { | ||
333 | struct pluto *pluto = dev_id; | ||
334 | u32 tscr; | ||
335 | |||
336 | /* check whether an interrupt occurred on this device */ | ||
337 | tscr = pluto_readreg(pluto, REG_TSCR); | ||
338 | if (!(tscr & (TSCR_DE | TSCR_OVR))) | ||
339 | return IRQ_NONE; | ||
340 | |||
341 | if (tscr == 0xffffffff) { | ||
342 | if (pluto->dead == 0) | ||
343 | dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n"); | ||
344 | /* It's dead Jim */ | ||
345 | pluto->dead = 1; | ||
346 | return IRQ_HANDLED; | ||
347 | } | ||
348 | |||
349 | /* dma end interrupt */ | ||
350 | if (tscr & TSCR_DE) { | ||
351 | pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24); | ||
352 | /* overflow interrupt */ | ||
353 | if (tscr & TSCR_OVR) | ||
354 | pluto->overflow++; | ||
355 | if (pluto->overflow) { | ||
356 | dev_err(&pluto->pdev->dev, "overflow irq (%d)\n", | ||
357 | pluto->overflow); | ||
358 | pluto_reset_ts(pluto, 1); | ||
359 | pluto->overflow = 0; | ||
360 | } | ||
361 | } else if (tscr & TSCR_OVR) { | ||
362 | pluto->overflow++; | ||
363 | } | ||
364 | |||
365 | /* ACK the interrupt */ | ||
366 | pluto_write_tscr(pluto, tscr | TSCR_IACK); | ||
367 | |||
368 | return IRQ_HANDLED; | ||
369 | } | ||
370 | |||
371 | static void __devinit pluto_enable_irqs(struct pluto *pluto) | ||
372 | { | ||
373 | u32 val = pluto_readreg(pluto, REG_TSCR); | ||
374 | |||
375 | /* disable AFUL and LOCK interrupts */ | ||
376 | val |= (TSCR_MSKA | TSCR_MSKL); | ||
377 | /* enable DMA and OVERFLOW interrupts */ | ||
378 | val &= ~(TSCR_DEM | TSCR_MSKO); | ||
379 | /* clear pending interrupts */ | ||
380 | val |= TSCR_IACK; | ||
381 | |||
382 | pluto_write_tscr(pluto, val); | ||
383 | } | ||
384 | |||
385 | static void pluto_disable_irqs(struct pluto *pluto) | ||
386 | { | ||
387 | u32 val = pluto_readreg(pluto, REG_TSCR); | ||
388 | |||
389 | /* disable all interrupts */ | ||
390 | val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL); | ||
391 | /* clear pending interrupts */ | ||
392 | val |= TSCR_IACK; | ||
393 | |||
394 | pluto_write_tscr(pluto, val); | ||
395 | } | ||
396 | |||
397 | static int __devinit pluto_hw_init(struct pluto *pluto) | ||
398 | { | ||
399 | pluto_reset_frontend(pluto, 1); | ||
400 | |||
401 | /* set automatic LED control by FPGA */ | ||
402 | pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED); | ||
403 | |||
404 | /* set data endianess */ | ||
405 | #ifdef __LITTLE_ENDIAN | ||
406 | pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END); | ||
407 | #else | ||
408 | pluto_rw(pluto, REG_PIDn(0), PID0_END, 0); | ||
409 | #endif | ||
410 | /* map DMA and set address */ | ||
411 | pluto_dma_map(pluto); | ||
412 | pluto_set_dma_addr(pluto); | ||
413 | |||
414 | /* enable interrupts */ | ||
415 | pluto_enable_irqs(pluto); | ||
416 | |||
417 | /* reset TS logic */ | ||
418 | pluto_reset_ts(pluto, 1); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static void pluto_hw_exit(struct pluto *pluto) | ||
424 | { | ||
425 | /* disable interrupts */ | ||
426 | pluto_disable_irqs(pluto); | ||
427 | |||
428 | pluto_reset_ts(pluto, 0); | ||
429 | |||
430 | /* LED: disable automatic control, enable yellow, disable green */ | ||
431 | pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1); | ||
432 | |||
433 | /* unmap DMA */ | ||
434 | pluto_dma_unmap(pluto); | ||
435 | |||
436 | pluto_reset_frontend(pluto, 0); | ||
437 | } | ||
438 | |||
439 | static inline u32 divide(u32 numerator, u32 denominator) | ||
440 | { | ||
441 | if (denominator == 0) | ||
442 | return ~0; | ||
443 | |||
444 | return DIV_ROUND_CLOSEST(numerator, denominator); | ||
445 | } | ||
446 | |||
447 | /* LG Innotek TDTE-E001P (Infineon TUA6034) */ | ||
448 | static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe) | ||
449 | { | ||
450 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
451 | struct pluto *pluto = frontend_to_pluto(fe); | ||
452 | struct i2c_msg msg; | ||
453 | int ret; | ||
454 | u8 buf[4]; | ||
455 | u32 div; | ||
456 | |||
457 | // Fref = 166.667 Hz | ||
458 | // Fref * 3 = 500.000 Hz | ||
459 | // IF = 36166667 | ||
460 | // IF / Fref = 217 | ||
461 | //div = divide(p->frequency + 36166667, 166667); | ||
462 | div = divide(p->frequency * 3, 500000) + 217; | ||
463 | buf[0] = (div >> 8) & 0x7f; | ||
464 | buf[1] = (div >> 0) & 0xff; | ||
465 | |||
466 | if (p->frequency < 611000000) | ||
467 | buf[2] = 0xb4; | ||
468 | else if (p->frequency < 811000000) | ||
469 | buf[2] = 0xbc; | ||
470 | else | ||
471 | buf[2] = 0xf4; | ||
472 | |||
473 | // VHF: 174-230 MHz | ||
474 | // center: 350 MHz | ||
475 | // UHF: 470-862 MHz | ||
476 | if (p->frequency < 350000000) | ||
477 | buf[3] = 0x02; | ||
478 | else | ||
479 | buf[3] = 0x04; | ||
480 | |||
481 | if (p->bandwidth_hz == 8000000) | ||
482 | buf[3] |= 0x08; | ||
483 | |||
484 | msg.addr = I2C_ADDR_TUA6034 >> 1; | ||
485 | msg.flags = 0; | ||
486 | msg.buf = buf; | ||
487 | msg.len = sizeof(buf); | ||
488 | |||
489 | if (fe->ops.i2c_gate_ctrl) | ||
490 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
491 | ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); | ||
492 | if (ret < 0) | ||
493 | return ret; | ||
494 | else if (ret == 0) | ||
495 | return -EREMOTEIO; | ||
496 | |||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | static int pluto2_request_firmware(struct dvb_frontend *fe, | ||
501 | const struct firmware **fw, char *name) | ||
502 | { | ||
503 | struct pluto *pluto = frontend_to_pluto(fe); | ||
504 | |||
505 | return request_firmware(fw, name, &pluto->pdev->dev); | ||
506 | } | ||
507 | |||
508 | static struct tda1004x_config pluto2_fe_config __devinitdata = { | ||
509 | .demod_address = I2C_ADDR_TDA10046 >> 1, | ||
510 | .invert = 1, | ||
511 | .invert_oclk = 0, | ||
512 | .xtal_freq = TDA10046_XTAL_16M, | ||
513 | .agc_config = TDA10046_AGC_DEFAULT, | ||
514 | .if_freq = TDA10046_FREQ_3617, | ||
515 | .request_firmware = pluto2_request_firmware, | ||
516 | }; | ||
517 | |||
518 | static int __devinit frontend_init(struct pluto *pluto) | ||
519 | { | ||
520 | int ret; | ||
521 | |||
522 | pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap); | ||
523 | if (!pluto->fe) { | ||
524 | dev_err(&pluto->pdev->dev, "could not attach frontend\n"); | ||
525 | return -ENODEV; | ||
526 | } | ||
527 | pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params; | ||
528 | |||
529 | ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); | ||
530 | if (ret < 0) { | ||
531 | if (pluto->fe->ops.release) | ||
532 | pluto->fe->ops.release(pluto->fe); | ||
533 | return ret; | ||
534 | } | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static void __devinit pluto_read_rev(struct pluto *pluto) | ||
540 | { | ||
541 | u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR; | ||
542 | dev_info(&pluto->pdev->dev, "board revision %d.%d\n", | ||
543 | (val >> 12) & 0x0f, (val >> 4) & 0xff); | ||
544 | } | ||
545 | |||
546 | static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac) | ||
547 | { | ||
548 | u32 val = pluto_readreg(pluto, REG_MMAC); | ||
549 | mac[0] = (val >> 8) & 0xff; | ||
550 | mac[1] = (val >> 0) & 0xff; | ||
551 | |||
552 | val = pluto_readreg(pluto, REG_IMAC); | ||
553 | mac[2] = (val >> 8) & 0xff; | ||
554 | mac[3] = (val >> 0) & 0xff; | ||
555 | |||
556 | val = pluto_readreg(pluto, REG_LMAC); | ||
557 | mac[4] = (val >> 8) & 0xff; | ||
558 | mac[5] = (val >> 0) & 0xff; | ||
559 | |||
560 | dev_info(&pluto->pdev->dev, "MAC %pM\n", mac); | ||
561 | } | ||
562 | |||
563 | static int __devinit pluto_read_serial(struct pluto *pluto) | ||
564 | { | ||
565 | struct pci_dev *pdev = pluto->pdev; | ||
566 | unsigned int i, j; | ||
567 | u8 __iomem *cis; | ||
568 | |||
569 | cis = pci_iomap(pdev, 1, 0); | ||
570 | if (!cis) | ||
571 | return -EIO; | ||
572 | |||
573 | dev_info(&pdev->dev, "S/N "); | ||
574 | |||
575 | for (i = 0xe0; i < 0x100; i += 4) { | ||
576 | u32 val = readl(&cis[i]); | ||
577 | for (j = 0; j < 32; j += 8) { | ||
578 | if ((val & 0xff) == 0xff) | ||
579 | goto out; | ||
580 | printk("%c", val & 0xff); | ||
581 | val >>= 8; | ||
582 | } | ||
583 | } | ||
584 | out: | ||
585 | printk("\n"); | ||
586 | pci_iounmap(pdev, cis); | ||
587 | |||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static int __devinit pluto2_probe(struct pci_dev *pdev, | ||
592 | const struct pci_device_id *ent) | ||
593 | { | ||
594 | struct pluto *pluto; | ||
595 | struct dvb_adapter *dvb_adapter; | ||
596 | struct dvb_demux *dvbdemux; | ||
597 | struct dmx_demux *dmx; | ||
598 | int ret = -ENOMEM; | ||
599 | |||
600 | pluto = kzalloc(sizeof(struct pluto), GFP_KERNEL); | ||
601 | if (!pluto) | ||
602 | goto out; | ||
603 | |||
604 | pluto->pdev = pdev; | ||
605 | |||
606 | ret = pci_enable_device(pdev); | ||
607 | if (ret < 0) | ||
608 | goto err_kfree; | ||
609 | |||
610 | /* enable interrupts */ | ||
611 | pci_write_config_dword(pdev, 0x6c, 0x8000); | ||
612 | |||
613 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
614 | if (ret < 0) | ||
615 | goto err_pci_disable_device; | ||
616 | |||
617 | pci_set_master(pdev); | ||
618 | |||
619 | ret = pci_request_regions(pdev, DRIVER_NAME); | ||
620 | if (ret < 0) | ||
621 | goto err_pci_disable_device; | ||
622 | |||
623 | pluto->io_mem = pci_iomap(pdev, 0, 0x40); | ||
624 | if (!pluto->io_mem) { | ||
625 | ret = -EIO; | ||
626 | goto err_pci_release_regions; | ||
627 | } | ||
628 | |||
629 | pci_set_drvdata(pdev, pluto); | ||
630 | |||
631 | ret = request_irq(pdev->irq, pluto_irq, IRQF_SHARED, DRIVER_NAME, pluto); | ||
632 | if (ret < 0) | ||
633 | goto err_pci_iounmap; | ||
634 | |||
635 | ret = pluto_hw_init(pluto); | ||
636 | if (ret < 0) | ||
637 | goto err_free_irq; | ||
638 | |||
639 | /* i2c */ | ||
640 | i2c_set_adapdata(&pluto->i2c_adap, pluto); | ||
641 | strcpy(pluto->i2c_adap.name, DRIVER_NAME); | ||
642 | pluto->i2c_adap.owner = THIS_MODULE; | ||
643 | pluto->i2c_adap.dev.parent = &pdev->dev; | ||
644 | pluto->i2c_adap.algo_data = &pluto->i2c_bit; | ||
645 | pluto->i2c_bit.data = pluto; | ||
646 | pluto->i2c_bit.setsda = pluto_setsda; | ||
647 | pluto->i2c_bit.setscl = pluto_setscl; | ||
648 | pluto->i2c_bit.getsda = pluto_getsda; | ||
649 | pluto->i2c_bit.getscl = pluto_getscl; | ||
650 | pluto->i2c_bit.udelay = 10; | ||
651 | pluto->i2c_bit.timeout = 10; | ||
652 | |||
653 | /* Raise SCL and SDA */ | ||
654 | pluto_setsda(pluto, 1); | ||
655 | pluto_setscl(pluto, 1); | ||
656 | |||
657 | ret = i2c_bit_add_bus(&pluto->i2c_adap); | ||
658 | if (ret < 0) | ||
659 | goto err_pluto_hw_exit; | ||
660 | |||
661 | /* dvb */ | ||
662 | ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, | ||
663 | THIS_MODULE, &pdev->dev, adapter_nr); | ||
664 | if (ret < 0) | ||
665 | goto err_i2c_del_adapter; | ||
666 | |||
667 | dvb_adapter = &pluto->dvb_adapter; | ||
668 | |||
669 | pluto_read_rev(pluto); | ||
670 | pluto_read_serial(pluto); | ||
671 | pluto_read_mac(pluto, dvb_adapter->proposed_mac); | ||
672 | |||
673 | dvbdemux = &pluto->demux; | ||
674 | dvbdemux->filternum = 256; | ||
675 | dvbdemux->feednum = 256; | ||
676 | dvbdemux->start_feed = pluto_start_feed; | ||
677 | dvbdemux->stop_feed = pluto_stop_feed; | ||
678 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | | ||
679 | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); | ||
680 | ret = dvb_dmx_init(dvbdemux); | ||
681 | if (ret < 0) | ||
682 | goto err_dvb_unregister_adapter; | ||
683 | |||
684 | dmx = &dvbdemux->dmx; | ||
685 | |||
686 | pluto->hw_frontend.source = DMX_FRONTEND_0; | ||
687 | pluto->mem_frontend.source = DMX_MEMORY_FE; | ||
688 | pluto->dmxdev.filternum = NHWFILTERS; | ||
689 | pluto->dmxdev.demux = dmx; | ||
690 | |||
691 | ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter); | ||
692 | if (ret < 0) | ||
693 | goto err_dvb_dmx_release; | ||
694 | |||
695 | ret = dmx->add_frontend(dmx, &pluto->hw_frontend); | ||
696 | if (ret < 0) | ||
697 | goto err_dvb_dmxdev_release; | ||
698 | |||
699 | ret = dmx->add_frontend(dmx, &pluto->mem_frontend); | ||
700 | if (ret < 0) | ||
701 | goto err_remove_hw_frontend; | ||
702 | |||
703 | ret = dmx->connect_frontend(dmx, &pluto->hw_frontend); | ||
704 | if (ret < 0) | ||
705 | goto err_remove_mem_frontend; | ||
706 | |||
707 | ret = frontend_init(pluto); | ||
708 | if (ret < 0) | ||
709 | goto err_disconnect_frontend; | ||
710 | |||
711 | dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx); | ||
712 | out: | ||
713 | return ret; | ||
714 | |||
715 | err_disconnect_frontend: | ||
716 | dmx->disconnect_frontend(dmx); | ||
717 | err_remove_mem_frontend: | ||
718 | dmx->remove_frontend(dmx, &pluto->mem_frontend); | ||
719 | err_remove_hw_frontend: | ||
720 | dmx->remove_frontend(dmx, &pluto->hw_frontend); | ||
721 | err_dvb_dmxdev_release: | ||
722 | dvb_dmxdev_release(&pluto->dmxdev); | ||
723 | err_dvb_dmx_release: | ||
724 | dvb_dmx_release(dvbdemux); | ||
725 | err_dvb_unregister_adapter: | ||
726 | dvb_unregister_adapter(dvb_adapter); | ||
727 | err_i2c_del_adapter: | ||
728 | i2c_del_adapter(&pluto->i2c_adap); | ||
729 | err_pluto_hw_exit: | ||
730 | pluto_hw_exit(pluto); | ||
731 | err_free_irq: | ||
732 | free_irq(pdev->irq, pluto); | ||
733 | err_pci_iounmap: | ||
734 | pci_iounmap(pdev, pluto->io_mem); | ||
735 | err_pci_release_regions: | ||
736 | pci_release_regions(pdev); | ||
737 | err_pci_disable_device: | ||
738 | pci_disable_device(pdev); | ||
739 | err_kfree: | ||
740 | pci_set_drvdata(pdev, NULL); | ||
741 | kfree(pluto); | ||
742 | goto out; | ||
743 | } | ||
744 | |||
745 | static void __devexit pluto2_remove(struct pci_dev *pdev) | ||
746 | { | ||
747 | struct pluto *pluto = pci_get_drvdata(pdev); | ||
748 | struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter; | ||
749 | struct dvb_demux *dvbdemux = &pluto->demux; | ||
750 | struct dmx_demux *dmx = &dvbdemux->dmx; | ||
751 | |||
752 | dmx->close(dmx); | ||
753 | dvb_net_release(&pluto->dvbnet); | ||
754 | if (pluto->fe) | ||
755 | dvb_unregister_frontend(pluto->fe); | ||
756 | |||
757 | dmx->disconnect_frontend(dmx); | ||
758 | dmx->remove_frontend(dmx, &pluto->mem_frontend); | ||
759 | dmx->remove_frontend(dmx, &pluto->hw_frontend); | ||
760 | dvb_dmxdev_release(&pluto->dmxdev); | ||
761 | dvb_dmx_release(dvbdemux); | ||
762 | dvb_unregister_adapter(dvb_adapter); | ||
763 | i2c_del_adapter(&pluto->i2c_adap); | ||
764 | pluto_hw_exit(pluto); | ||
765 | free_irq(pdev->irq, pluto); | ||
766 | pci_iounmap(pdev, pluto->io_mem); | ||
767 | pci_release_regions(pdev); | ||
768 | pci_disable_device(pdev); | ||
769 | pci_set_drvdata(pdev, NULL); | ||
770 | kfree(pluto); | ||
771 | } | ||
772 | |||
773 | #ifndef PCI_VENDOR_ID_SCM | ||
774 | #define PCI_VENDOR_ID_SCM 0x0432 | ||
775 | #endif | ||
776 | #ifndef PCI_DEVICE_ID_PLUTO2 | ||
777 | #define PCI_DEVICE_ID_PLUTO2 0x0001 | ||
778 | #endif | ||
779 | |||
780 | static struct pci_device_id pluto2_id_table[] __devinitdata = { | ||
781 | { | ||
782 | .vendor = PCI_VENDOR_ID_SCM, | ||
783 | .device = PCI_DEVICE_ID_PLUTO2, | ||
784 | .subvendor = PCI_ANY_ID, | ||
785 | .subdevice = PCI_ANY_ID, | ||
786 | }, { | ||
787 | /* empty */ | ||
788 | }, | ||
789 | }; | ||
790 | |||
791 | MODULE_DEVICE_TABLE(pci, pluto2_id_table); | ||
792 | |||
793 | static struct pci_driver pluto2_driver = { | ||
794 | .name = DRIVER_NAME, | ||
795 | .id_table = pluto2_id_table, | ||
796 | .probe = pluto2_probe, | ||
797 | .remove = __devexit_p(pluto2_remove), | ||
798 | }; | ||
799 | |||
800 | static int __init pluto2_init(void) | ||
801 | { | ||
802 | return pci_register_driver(&pluto2_driver); | ||
803 | } | ||
804 | |||
805 | static void __exit pluto2_exit(void) | ||
806 | { | ||
807 | pci_unregister_driver(&pluto2_driver); | ||
808 | } | ||
809 | |||
810 | module_init(pluto2_init); | ||
811 | module_exit(pluto2_exit); | ||
812 | |||
813 | MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); | ||
814 | MODULE_DESCRIPTION("Pluto2 driver"); | ||
815 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/pt1/Kconfig b/drivers/media/dvb/pt1/Kconfig deleted file mode 100644 index 24501d5bf70d..000000000000 --- a/drivers/media/dvb/pt1/Kconfig +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | config DVB_PT1 | ||
2 | tristate "PT1 cards" | ||
3 | depends on DVB_CORE && PCI && I2C | ||
4 | help | ||
5 | Support for Earthsoft PT1 PCI cards. | ||
6 | |||
7 | Since these cards have no MPEG decoder onboard, they transmit | ||
8 | only compressed MPEG data over the PCI bus, so you need | ||
9 | an external software decoder to watch TV on your computer. | ||
10 | |||
11 | Say Y or M if you own such a device and want to use it. | ||
12 | |||
diff --git a/drivers/media/dvb/pt1/Makefile b/drivers/media/dvb/pt1/Makefile deleted file mode 100644 index 98e391295afe..000000000000 --- a/drivers/media/dvb/pt1/Makefile +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o | ||
2 | |||
3 | obj-$(CONFIG_DVB_PT1) += earth-pt1.o | ||
4 | |||
5 | ccflags-y += -Idrivers/media/dvb-core -Idrivers/media/dvb-frontends | ||
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c deleted file mode 100644 index 15b35c4725f1..000000000000 --- a/drivers/media/dvb/pt1/pt1.c +++ /dev/null | |||
@@ -1,1246 +0,0 @@ | |||
1 | /* | ||
2 | * driver for Earthsoft PT1/PT2 | ||
3 | * | ||
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | ||
5 | * | ||
6 | * based on pt1dvr - http://pt1dvr.sourceforge.jp/ | ||
7 | * by Tomoaki Ishikawa <tomy@users.sourceforge.jp> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/kthread.h> | ||
30 | #include <linux/freezer.h> | ||
31 | #include <linux/ratelimit.h> | ||
32 | |||
33 | #include "dvbdev.h" | ||
34 | #include "dvb_demux.h" | ||
35 | #include "dmxdev.h" | ||
36 | #include "dvb_net.h" | ||
37 | #include "dvb_frontend.h" | ||
38 | |||
39 | #include "va1j5jf8007t.h" | ||
40 | #include "va1j5jf8007s.h" | ||
41 | |||
42 | #define DRIVER_NAME "earth-pt1" | ||
43 | |||
44 | #define PT1_PAGE_SHIFT 12 | ||
45 | #define PT1_PAGE_SIZE (1 << PT1_PAGE_SHIFT) | ||
46 | #define PT1_NR_UPACKETS 1024 | ||
47 | #define PT1_NR_BUFS 511 | ||
48 | |||
49 | struct pt1_buffer_page { | ||
50 | __le32 upackets[PT1_NR_UPACKETS]; | ||
51 | }; | ||
52 | |||
53 | struct pt1_table_page { | ||
54 | __le32 next_pfn; | ||
55 | __le32 buf_pfns[PT1_NR_BUFS]; | ||
56 | }; | ||
57 | |||
58 | struct pt1_buffer { | ||
59 | struct pt1_buffer_page *page; | ||
60 | dma_addr_t addr; | ||
61 | }; | ||
62 | |||
63 | struct pt1_table { | ||
64 | struct pt1_table_page *page; | ||
65 | dma_addr_t addr; | ||
66 | struct pt1_buffer bufs[PT1_NR_BUFS]; | ||
67 | }; | ||
68 | |||
69 | #define PT1_NR_ADAPS 4 | ||
70 | |||
71 | struct pt1_adapter; | ||
72 | |||
73 | struct pt1 { | ||
74 | struct pci_dev *pdev; | ||
75 | void __iomem *regs; | ||
76 | struct i2c_adapter i2c_adap; | ||
77 | int i2c_running; | ||
78 | struct pt1_adapter *adaps[PT1_NR_ADAPS]; | ||
79 | struct pt1_table *tables; | ||
80 | struct task_struct *kthread; | ||
81 | int table_index; | ||
82 | int buf_index; | ||
83 | |||
84 | struct mutex lock; | ||
85 | int power; | ||
86 | int reset; | ||
87 | }; | ||
88 | |||
89 | struct pt1_adapter { | ||
90 | struct pt1 *pt1; | ||
91 | int index; | ||
92 | |||
93 | u8 *buf; | ||
94 | int upacket_count; | ||
95 | int packet_count; | ||
96 | int st_count; | ||
97 | |||
98 | struct dvb_adapter adap; | ||
99 | struct dvb_demux demux; | ||
100 | int users; | ||
101 | struct dmxdev dmxdev; | ||
102 | struct dvb_frontend *fe; | ||
103 | int (*orig_set_voltage)(struct dvb_frontend *fe, | ||
104 | fe_sec_voltage_t voltage); | ||
105 | int (*orig_sleep)(struct dvb_frontend *fe); | ||
106 | int (*orig_init)(struct dvb_frontend *fe); | ||
107 | |||
108 | fe_sec_voltage_t voltage; | ||
109 | int sleep; | ||
110 | }; | ||
111 | |||
112 | #define pt1_printk(level, pt1, format, arg...) \ | ||
113 | dev_printk(level, &(pt1)->pdev->dev, format, ##arg) | ||
114 | |||
115 | static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data) | ||
116 | { | ||
117 | writel(data, pt1->regs + reg * 4); | ||
118 | } | ||
119 | |||
120 | static u32 pt1_read_reg(struct pt1 *pt1, int reg) | ||
121 | { | ||
122 | return readl(pt1->regs + reg * 4); | ||
123 | } | ||
124 | |||
125 | static int pt1_nr_tables = 8; | ||
126 | module_param_named(nr_tables, pt1_nr_tables, int, 0); | ||
127 | |||
128 | static void pt1_increment_table_count(struct pt1 *pt1) | ||
129 | { | ||
130 | pt1_write_reg(pt1, 0, 0x00000020); | ||
131 | } | ||
132 | |||
133 | static void pt1_init_table_count(struct pt1 *pt1) | ||
134 | { | ||
135 | pt1_write_reg(pt1, 0, 0x00000010); | ||
136 | } | ||
137 | |||
138 | static void pt1_register_tables(struct pt1 *pt1, u32 first_pfn) | ||
139 | { | ||
140 | pt1_write_reg(pt1, 5, first_pfn); | ||
141 | pt1_write_reg(pt1, 0, 0x0c000040); | ||
142 | } | ||
143 | |||
144 | static void pt1_unregister_tables(struct pt1 *pt1) | ||
145 | { | ||
146 | pt1_write_reg(pt1, 0, 0x08080000); | ||
147 | } | ||
148 | |||
149 | static int pt1_sync(struct pt1 *pt1) | ||
150 | { | ||
151 | int i; | ||
152 | for (i = 0; i < 57; i++) { | ||
153 | if (pt1_read_reg(pt1, 0) & 0x20000000) | ||
154 | return 0; | ||
155 | pt1_write_reg(pt1, 0, 0x00000008); | ||
156 | } | ||
157 | pt1_printk(KERN_ERR, pt1, "could not sync\n"); | ||
158 | return -EIO; | ||
159 | } | ||
160 | |||
161 | static u64 pt1_identify(struct pt1 *pt1) | ||
162 | { | ||
163 | int i; | ||
164 | u64 id; | ||
165 | id = 0; | ||
166 | for (i = 0; i < 57; i++) { | ||
167 | id |= (u64)(pt1_read_reg(pt1, 0) >> 30 & 1) << i; | ||
168 | pt1_write_reg(pt1, 0, 0x00000008); | ||
169 | } | ||
170 | return id; | ||
171 | } | ||
172 | |||
173 | static int pt1_unlock(struct pt1 *pt1) | ||
174 | { | ||
175 | int i; | ||
176 | pt1_write_reg(pt1, 0, 0x00000008); | ||
177 | for (i = 0; i < 3; i++) { | ||
178 | if (pt1_read_reg(pt1, 0) & 0x80000000) | ||
179 | return 0; | ||
180 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
181 | } | ||
182 | pt1_printk(KERN_ERR, pt1, "could not unlock\n"); | ||
183 | return -EIO; | ||
184 | } | ||
185 | |||
186 | static int pt1_reset_pci(struct pt1 *pt1) | ||
187 | { | ||
188 | int i; | ||
189 | pt1_write_reg(pt1, 0, 0x01010000); | ||
190 | pt1_write_reg(pt1, 0, 0x01000000); | ||
191 | for (i = 0; i < 10; i++) { | ||
192 | if (pt1_read_reg(pt1, 0) & 0x00000001) | ||
193 | return 0; | ||
194 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
195 | } | ||
196 | pt1_printk(KERN_ERR, pt1, "could not reset PCI\n"); | ||
197 | return -EIO; | ||
198 | } | ||
199 | |||
200 | static int pt1_reset_ram(struct pt1 *pt1) | ||
201 | { | ||
202 | int i; | ||
203 | pt1_write_reg(pt1, 0, 0x02020000); | ||
204 | pt1_write_reg(pt1, 0, 0x02000000); | ||
205 | for (i = 0; i < 10; i++) { | ||
206 | if (pt1_read_reg(pt1, 0) & 0x00000002) | ||
207 | return 0; | ||
208 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
209 | } | ||
210 | pt1_printk(KERN_ERR, pt1, "could not reset RAM\n"); | ||
211 | return -EIO; | ||
212 | } | ||
213 | |||
214 | static int pt1_do_enable_ram(struct pt1 *pt1) | ||
215 | { | ||
216 | int i, j; | ||
217 | u32 status; | ||
218 | status = pt1_read_reg(pt1, 0) & 0x00000004; | ||
219 | pt1_write_reg(pt1, 0, 0x00000002); | ||
220 | for (i = 0; i < 10; i++) { | ||
221 | for (j = 0; j < 1024; j++) { | ||
222 | if ((pt1_read_reg(pt1, 0) & 0x00000004) != status) | ||
223 | return 0; | ||
224 | } | ||
225 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
226 | } | ||
227 | pt1_printk(KERN_ERR, pt1, "could not enable RAM\n"); | ||
228 | return -EIO; | ||
229 | } | ||
230 | |||
231 | static int pt1_enable_ram(struct pt1 *pt1) | ||
232 | { | ||
233 | int i, ret; | ||
234 | int phase; | ||
235 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
236 | phase = pt1->pdev->device == 0x211a ? 128 : 166; | ||
237 | for (i = 0; i < phase; i++) { | ||
238 | ret = pt1_do_enable_ram(pt1); | ||
239 | if (ret < 0) | ||
240 | return ret; | ||
241 | } | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static void pt1_disable_ram(struct pt1 *pt1) | ||
246 | { | ||
247 | pt1_write_reg(pt1, 0, 0x0b0b0000); | ||
248 | } | ||
249 | |||
250 | static void pt1_set_stream(struct pt1 *pt1, int index, int enabled) | ||
251 | { | ||
252 | pt1_write_reg(pt1, 2, 1 << (index + 8) | enabled << index); | ||
253 | } | ||
254 | |||
255 | static void pt1_init_streams(struct pt1 *pt1) | ||
256 | { | ||
257 | int i; | ||
258 | for (i = 0; i < PT1_NR_ADAPS; i++) | ||
259 | pt1_set_stream(pt1, i, 0); | ||
260 | } | ||
261 | |||
262 | static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page) | ||
263 | { | ||
264 | u32 upacket; | ||
265 | int i; | ||
266 | int index; | ||
267 | struct pt1_adapter *adap; | ||
268 | int offset; | ||
269 | u8 *buf; | ||
270 | int sc; | ||
271 | |||
272 | if (!page->upackets[PT1_NR_UPACKETS - 1]) | ||
273 | return 0; | ||
274 | |||
275 | for (i = 0; i < PT1_NR_UPACKETS; i++) { | ||
276 | upacket = le32_to_cpu(page->upackets[i]); | ||
277 | index = (upacket >> 29) - 1; | ||
278 | if (index < 0 || index >= PT1_NR_ADAPS) | ||
279 | continue; | ||
280 | |||
281 | adap = pt1->adaps[index]; | ||
282 | if (upacket >> 25 & 1) | ||
283 | adap->upacket_count = 0; | ||
284 | else if (!adap->upacket_count) | ||
285 | continue; | ||
286 | |||
287 | if (upacket >> 24 & 1) | ||
288 | printk_ratelimited(KERN_INFO "earth-pt1: device " | ||
289 | "buffer overflowing. table[%d] buf[%d]\n", | ||
290 | pt1->table_index, pt1->buf_index); | ||
291 | sc = upacket >> 26 & 0x7; | ||
292 | if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7)) | ||
293 | printk_ratelimited(KERN_INFO "earth-pt1: data loss" | ||
294 | " in streamID(adapter)[%d]\n", index); | ||
295 | adap->st_count = sc; | ||
296 | |||
297 | buf = adap->buf; | ||
298 | offset = adap->packet_count * 188 + adap->upacket_count * 3; | ||
299 | buf[offset] = upacket >> 16; | ||
300 | buf[offset + 1] = upacket >> 8; | ||
301 | if (adap->upacket_count != 62) | ||
302 | buf[offset + 2] = upacket; | ||
303 | |||
304 | if (++adap->upacket_count >= 63) { | ||
305 | adap->upacket_count = 0; | ||
306 | if (++adap->packet_count >= 21) { | ||
307 | dvb_dmx_swfilter_packets(&adap->demux, buf, 21); | ||
308 | adap->packet_count = 0; | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | page->upackets[PT1_NR_UPACKETS - 1] = 0; | ||
314 | return 1; | ||
315 | } | ||
316 | |||
317 | static int pt1_thread(void *data) | ||
318 | { | ||
319 | struct pt1 *pt1; | ||
320 | struct pt1_buffer_page *page; | ||
321 | |||
322 | pt1 = data; | ||
323 | set_freezable(); | ||
324 | |||
325 | while (!kthread_should_stop()) { | ||
326 | try_to_freeze(); | ||
327 | |||
328 | page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page; | ||
329 | if (!pt1_filter(pt1, page)) { | ||
330 | schedule_timeout_interruptible((HZ + 999) / 1000); | ||
331 | continue; | ||
332 | } | ||
333 | |||
334 | if (++pt1->buf_index >= PT1_NR_BUFS) { | ||
335 | pt1_increment_table_count(pt1); | ||
336 | pt1->buf_index = 0; | ||
337 | if (++pt1->table_index >= pt1_nr_tables) | ||
338 | pt1->table_index = 0; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static void pt1_free_page(struct pt1 *pt1, void *page, dma_addr_t addr) | ||
346 | { | ||
347 | dma_free_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, page, addr); | ||
348 | } | ||
349 | |||
350 | static void *pt1_alloc_page(struct pt1 *pt1, dma_addr_t *addrp, u32 *pfnp) | ||
351 | { | ||
352 | void *page; | ||
353 | dma_addr_t addr; | ||
354 | |||
355 | page = dma_alloc_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, &addr, | ||
356 | GFP_KERNEL); | ||
357 | if (page == NULL) | ||
358 | return NULL; | ||
359 | |||
360 | BUG_ON(addr & (PT1_PAGE_SIZE - 1)); | ||
361 | BUG_ON(addr >> PT1_PAGE_SHIFT >> 31 >> 1); | ||
362 | |||
363 | *addrp = addr; | ||
364 | *pfnp = addr >> PT1_PAGE_SHIFT; | ||
365 | return page; | ||
366 | } | ||
367 | |||
368 | static void pt1_cleanup_buffer(struct pt1 *pt1, struct pt1_buffer *buf) | ||
369 | { | ||
370 | pt1_free_page(pt1, buf->page, buf->addr); | ||
371 | } | ||
372 | |||
373 | static int | ||
374 | pt1_init_buffer(struct pt1 *pt1, struct pt1_buffer *buf, u32 *pfnp) | ||
375 | { | ||
376 | struct pt1_buffer_page *page; | ||
377 | dma_addr_t addr; | ||
378 | |||
379 | page = pt1_alloc_page(pt1, &addr, pfnp); | ||
380 | if (page == NULL) | ||
381 | return -ENOMEM; | ||
382 | |||
383 | page->upackets[PT1_NR_UPACKETS - 1] = 0; | ||
384 | |||
385 | buf->page = page; | ||
386 | buf->addr = addr; | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static void pt1_cleanup_table(struct pt1 *pt1, struct pt1_table *table) | ||
391 | { | ||
392 | int i; | ||
393 | |||
394 | for (i = 0; i < PT1_NR_BUFS; i++) | ||
395 | pt1_cleanup_buffer(pt1, &table->bufs[i]); | ||
396 | |||
397 | pt1_free_page(pt1, table->page, table->addr); | ||
398 | } | ||
399 | |||
400 | static int | ||
401 | pt1_init_table(struct pt1 *pt1, struct pt1_table *table, u32 *pfnp) | ||
402 | { | ||
403 | struct pt1_table_page *page; | ||
404 | dma_addr_t addr; | ||
405 | int i, ret; | ||
406 | u32 buf_pfn; | ||
407 | |||
408 | page = pt1_alloc_page(pt1, &addr, pfnp); | ||
409 | if (page == NULL) | ||
410 | return -ENOMEM; | ||
411 | |||
412 | for (i = 0; i < PT1_NR_BUFS; i++) { | ||
413 | ret = pt1_init_buffer(pt1, &table->bufs[i], &buf_pfn); | ||
414 | if (ret < 0) | ||
415 | goto err; | ||
416 | |||
417 | page->buf_pfns[i] = cpu_to_le32(buf_pfn); | ||
418 | } | ||
419 | |||
420 | pt1_increment_table_count(pt1); | ||
421 | table->page = page; | ||
422 | table->addr = addr; | ||
423 | return 0; | ||
424 | |||
425 | err: | ||
426 | while (i--) | ||
427 | pt1_cleanup_buffer(pt1, &table->bufs[i]); | ||
428 | |||
429 | pt1_free_page(pt1, page, addr); | ||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | static void pt1_cleanup_tables(struct pt1 *pt1) | ||
434 | { | ||
435 | struct pt1_table *tables; | ||
436 | int i; | ||
437 | |||
438 | tables = pt1->tables; | ||
439 | pt1_unregister_tables(pt1); | ||
440 | |||
441 | for (i = 0; i < pt1_nr_tables; i++) | ||
442 | pt1_cleanup_table(pt1, &tables[i]); | ||
443 | |||
444 | vfree(tables); | ||
445 | } | ||
446 | |||
447 | static int pt1_init_tables(struct pt1 *pt1) | ||
448 | { | ||
449 | struct pt1_table *tables; | ||
450 | int i, ret; | ||
451 | u32 first_pfn, pfn; | ||
452 | |||
453 | tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables); | ||
454 | if (tables == NULL) | ||
455 | return -ENOMEM; | ||
456 | |||
457 | pt1_init_table_count(pt1); | ||
458 | |||
459 | i = 0; | ||
460 | if (pt1_nr_tables) { | ||
461 | ret = pt1_init_table(pt1, &tables[0], &first_pfn); | ||
462 | if (ret) | ||
463 | goto err; | ||
464 | i++; | ||
465 | } | ||
466 | |||
467 | while (i < pt1_nr_tables) { | ||
468 | ret = pt1_init_table(pt1, &tables[i], &pfn); | ||
469 | if (ret) | ||
470 | goto err; | ||
471 | tables[i - 1].page->next_pfn = cpu_to_le32(pfn); | ||
472 | i++; | ||
473 | } | ||
474 | |||
475 | tables[pt1_nr_tables - 1].page->next_pfn = cpu_to_le32(first_pfn); | ||
476 | |||
477 | pt1_register_tables(pt1, first_pfn); | ||
478 | pt1->tables = tables; | ||
479 | return 0; | ||
480 | |||
481 | err: | ||
482 | while (i--) | ||
483 | pt1_cleanup_table(pt1, &tables[i]); | ||
484 | |||
485 | vfree(tables); | ||
486 | return ret; | ||
487 | } | ||
488 | |||
489 | static int pt1_start_polling(struct pt1 *pt1) | ||
490 | { | ||
491 | int ret = 0; | ||
492 | |||
493 | mutex_lock(&pt1->lock); | ||
494 | if (!pt1->kthread) { | ||
495 | pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1"); | ||
496 | if (IS_ERR(pt1->kthread)) { | ||
497 | ret = PTR_ERR(pt1->kthread); | ||
498 | pt1->kthread = NULL; | ||
499 | } | ||
500 | } | ||
501 | mutex_unlock(&pt1->lock); | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | static int pt1_start_feed(struct dvb_demux_feed *feed) | ||
506 | { | ||
507 | struct pt1_adapter *adap; | ||
508 | adap = container_of(feed->demux, struct pt1_adapter, demux); | ||
509 | if (!adap->users++) { | ||
510 | int ret; | ||
511 | |||
512 | ret = pt1_start_polling(adap->pt1); | ||
513 | if (ret) | ||
514 | return ret; | ||
515 | pt1_set_stream(adap->pt1, adap->index, 1); | ||
516 | } | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static void pt1_stop_polling(struct pt1 *pt1) | ||
521 | { | ||
522 | int i, count; | ||
523 | |||
524 | mutex_lock(&pt1->lock); | ||
525 | for (i = 0, count = 0; i < PT1_NR_ADAPS; i++) | ||
526 | count += pt1->adaps[i]->users; | ||
527 | |||
528 | if (count == 0 && pt1->kthread) { | ||
529 | kthread_stop(pt1->kthread); | ||
530 | pt1->kthread = NULL; | ||
531 | } | ||
532 | mutex_unlock(&pt1->lock); | ||
533 | } | ||
534 | |||
535 | static int pt1_stop_feed(struct dvb_demux_feed *feed) | ||
536 | { | ||
537 | struct pt1_adapter *adap; | ||
538 | adap = container_of(feed->demux, struct pt1_adapter, demux); | ||
539 | if (!--adap->users) { | ||
540 | pt1_set_stream(adap->pt1, adap->index, 0); | ||
541 | pt1_stop_polling(adap->pt1); | ||
542 | } | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static void | ||
547 | pt1_update_power(struct pt1 *pt1) | ||
548 | { | ||
549 | int bits; | ||
550 | int i; | ||
551 | struct pt1_adapter *adap; | ||
552 | static const int sleep_bits[] = { | ||
553 | 1 << 4, | ||
554 | 1 << 6 | 1 << 7, | ||
555 | 1 << 5, | ||
556 | 1 << 6 | 1 << 8, | ||
557 | }; | ||
558 | |||
559 | bits = pt1->power | !pt1->reset << 3; | ||
560 | mutex_lock(&pt1->lock); | ||
561 | for (i = 0; i < PT1_NR_ADAPS; i++) { | ||
562 | adap = pt1->adaps[i]; | ||
563 | switch (adap->voltage) { | ||
564 | case SEC_VOLTAGE_13: /* actually 11V */ | ||
565 | bits |= 1 << 1; | ||
566 | break; | ||
567 | case SEC_VOLTAGE_18: /* actually 15V */ | ||
568 | bits |= 1 << 1 | 1 << 2; | ||
569 | break; | ||
570 | default: | ||
571 | break; | ||
572 | } | ||
573 | |||
574 | /* XXX: The bits should be changed depending on adap->sleep. */ | ||
575 | bits |= sleep_bits[i]; | ||
576 | } | ||
577 | pt1_write_reg(pt1, 1, bits); | ||
578 | mutex_unlock(&pt1->lock); | ||
579 | } | ||
580 | |||
581 | static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
582 | { | ||
583 | struct pt1_adapter *adap; | ||
584 | |||
585 | adap = container_of(fe->dvb, struct pt1_adapter, adap); | ||
586 | adap->voltage = voltage; | ||
587 | pt1_update_power(adap->pt1); | ||
588 | |||
589 | if (adap->orig_set_voltage) | ||
590 | return adap->orig_set_voltage(fe, voltage); | ||
591 | else | ||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static int pt1_sleep(struct dvb_frontend *fe) | ||
596 | { | ||
597 | struct pt1_adapter *adap; | ||
598 | |||
599 | adap = container_of(fe->dvb, struct pt1_adapter, adap); | ||
600 | adap->sleep = 1; | ||
601 | pt1_update_power(adap->pt1); | ||
602 | |||
603 | if (adap->orig_sleep) | ||
604 | return adap->orig_sleep(fe); | ||
605 | else | ||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | static int pt1_wakeup(struct dvb_frontend *fe) | ||
610 | { | ||
611 | struct pt1_adapter *adap; | ||
612 | |||
613 | adap = container_of(fe->dvb, struct pt1_adapter, adap); | ||
614 | adap->sleep = 0; | ||
615 | pt1_update_power(adap->pt1); | ||
616 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
617 | |||
618 | if (adap->orig_init) | ||
619 | return adap->orig_init(fe); | ||
620 | else | ||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | static void pt1_free_adapter(struct pt1_adapter *adap) | ||
625 | { | ||
626 | adap->demux.dmx.close(&adap->demux.dmx); | ||
627 | dvb_dmxdev_release(&adap->dmxdev); | ||
628 | dvb_dmx_release(&adap->demux); | ||
629 | dvb_unregister_adapter(&adap->adap); | ||
630 | free_page((unsigned long)adap->buf); | ||
631 | kfree(adap); | ||
632 | } | ||
633 | |||
634 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
635 | |||
636 | static struct pt1_adapter * | ||
637 | pt1_alloc_adapter(struct pt1 *pt1) | ||
638 | { | ||
639 | struct pt1_adapter *adap; | ||
640 | void *buf; | ||
641 | struct dvb_adapter *dvb_adap; | ||
642 | struct dvb_demux *demux; | ||
643 | struct dmxdev *dmxdev; | ||
644 | int ret; | ||
645 | |||
646 | adap = kzalloc(sizeof(struct pt1_adapter), GFP_KERNEL); | ||
647 | if (!adap) { | ||
648 | ret = -ENOMEM; | ||
649 | goto err; | ||
650 | } | ||
651 | |||
652 | adap->pt1 = pt1; | ||
653 | |||
654 | adap->voltage = SEC_VOLTAGE_OFF; | ||
655 | adap->sleep = 1; | ||
656 | |||
657 | buf = (u8 *)__get_free_page(GFP_KERNEL); | ||
658 | if (!buf) { | ||
659 | ret = -ENOMEM; | ||
660 | goto err_kfree; | ||
661 | } | ||
662 | |||
663 | adap->buf = buf; | ||
664 | adap->upacket_count = 0; | ||
665 | adap->packet_count = 0; | ||
666 | adap->st_count = -1; | ||
667 | |||
668 | dvb_adap = &adap->adap; | ||
669 | dvb_adap->priv = adap; | ||
670 | ret = dvb_register_adapter(dvb_adap, DRIVER_NAME, THIS_MODULE, | ||
671 | &pt1->pdev->dev, adapter_nr); | ||
672 | if (ret < 0) | ||
673 | goto err_free_page; | ||
674 | |||
675 | demux = &adap->demux; | ||
676 | demux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; | ||
677 | demux->priv = adap; | ||
678 | demux->feednum = 256; | ||
679 | demux->filternum = 256; | ||
680 | demux->start_feed = pt1_start_feed; | ||
681 | demux->stop_feed = pt1_stop_feed; | ||
682 | demux->write_to_decoder = NULL; | ||
683 | ret = dvb_dmx_init(demux); | ||
684 | if (ret < 0) | ||
685 | goto err_unregister_adapter; | ||
686 | |||
687 | dmxdev = &adap->dmxdev; | ||
688 | dmxdev->filternum = 256; | ||
689 | dmxdev->demux = &demux->dmx; | ||
690 | dmxdev->capabilities = 0; | ||
691 | ret = dvb_dmxdev_init(dmxdev, dvb_adap); | ||
692 | if (ret < 0) | ||
693 | goto err_dmx_release; | ||
694 | |||
695 | return adap; | ||
696 | |||
697 | err_dmx_release: | ||
698 | dvb_dmx_release(demux); | ||
699 | err_unregister_adapter: | ||
700 | dvb_unregister_adapter(dvb_adap); | ||
701 | err_free_page: | ||
702 | free_page((unsigned long)buf); | ||
703 | err_kfree: | ||
704 | kfree(adap); | ||
705 | err: | ||
706 | return ERR_PTR(ret); | ||
707 | } | ||
708 | |||
709 | static void pt1_cleanup_adapters(struct pt1 *pt1) | ||
710 | { | ||
711 | int i; | ||
712 | for (i = 0; i < PT1_NR_ADAPS; i++) | ||
713 | pt1_free_adapter(pt1->adaps[i]); | ||
714 | } | ||
715 | |||
716 | static int pt1_init_adapters(struct pt1 *pt1) | ||
717 | { | ||
718 | int i; | ||
719 | struct pt1_adapter *adap; | ||
720 | int ret; | ||
721 | |||
722 | for (i = 0; i < PT1_NR_ADAPS; i++) { | ||
723 | adap = pt1_alloc_adapter(pt1); | ||
724 | if (IS_ERR(adap)) { | ||
725 | ret = PTR_ERR(adap); | ||
726 | goto err; | ||
727 | } | ||
728 | |||
729 | adap->index = i; | ||
730 | pt1->adaps[i] = adap; | ||
731 | } | ||
732 | return 0; | ||
733 | |||
734 | err: | ||
735 | while (i--) | ||
736 | pt1_free_adapter(pt1->adaps[i]); | ||
737 | |||
738 | return ret; | ||
739 | } | ||
740 | |||
741 | static void pt1_cleanup_frontend(struct pt1_adapter *adap) | ||
742 | { | ||
743 | dvb_unregister_frontend(adap->fe); | ||
744 | } | ||
745 | |||
746 | static int pt1_init_frontend(struct pt1_adapter *adap, struct dvb_frontend *fe) | ||
747 | { | ||
748 | int ret; | ||
749 | |||
750 | adap->orig_set_voltage = fe->ops.set_voltage; | ||
751 | adap->orig_sleep = fe->ops.sleep; | ||
752 | adap->orig_init = fe->ops.init; | ||
753 | fe->ops.set_voltage = pt1_set_voltage; | ||
754 | fe->ops.sleep = pt1_sleep; | ||
755 | fe->ops.init = pt1_wakeup; | ||
756 | |||
757 | ret = dvb_register_frontend(&adap->adap, fe); | ||
758 | if (ret < 0) | ||
759 | return ret; | ||
760 | |||
761 | adap->fe = fe; | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static void pt1_cleanup_frontends(struct pt1 *pt1) | ||
766 | { | ||
767 | int i; | ||
768 | for (i = 0; i < PT1_NR_ADAPS; i++) | ||
769 | pt1_cleanup_frontend(pt1->adaps[i]); | ||
770 | } | ||
771 | |||
772 | struct pt1_config { | ||
773 | struct va1j5jf8007s_config va1j5jf8007s_config; | ||
774 | struct va1j5jf8007t_config va1j5jf8007t_config; | ||
775 | }; | ||
776 | |||
777 | static const struct pt1_config pt1_configs[2] = { | ||
778 | { | ||
779 | { | ||
780 | .demod_address = 0x1b, | ||
781 | .frequency = VA1J5JF8007S_20MHZ, | ||
782 | }, | ||
783 | { | ||
784 | .demod_address = 0x1a, | ||
785 | .frequency = VA1J5JF8007T_20MHZ, | ||
786 | }, | ||
787 | }, { | ||
788 | { | ||
789 | .demod_address = 0x19, | ||
790 | .frequency = VA1J5JF8007S_20MHZ, | ||
791 | }, | ||
792 | { | ||
793 | .demod_address = 0x18, | ||
794 | .frequency = VA1J5JF8007T_20MHZ, | ||
795 | }, | ||
796 | }, | ||
797 | }; | ||
798 | |||
799 | static const struct pt1_config pt2_configs[2] = { | ||
800 | { | ||
801 | { | ||
802 | .demod_address = 0x1b, | ||
803 | .frequency = VA1J5JF8007S_25MHZ, | ||
804 | }, | ||
805 | { | ||
806 | .demod_address = 0x1a, | ||
807 | .frequency = VA1J5JF8007T_25MHZ, | ||
808 | }, | ||
809 | }, { | ||
810 | { | ||
811 | .demod_address = 0x19, | ||
812 | .frequency = VA1J5JF8007S_25MHZ, | ||
813 | }, | ||
814 | { | ||
815 | .demod_address = 0x18, | ||
816 | .frequency = VA1J5JF8007T_25MHZ, | ||
817 | }, | ||
818 | }, | ||
819 | }; | ||
820 | |||
821 | static int pt1_init_frontends(struct pt1 *pt1) | ||
822 | { | ||
823 | int i, j; | ||
824 | struct i2c_adapter *i2c_adap; | ||
825 | const struct pt1_config *configs, *config; | ||
826 | struct dvb_frontend *fe[4]; | ||
827 | int ret; | ||
828 | |||
829 | i = 0; | ||
830 | j = 0; | ||
831 | |||
832 | i2c_adap = &pt1->i2c_adap; | ||
833 | configs = pt1->pdev->device == 0x211a ? pt1_configs : pt2_configs; | ||
834 | do { | ||
835 | config = &configs[i / 2]; | ||
836 | |||
837 | fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config, | ||
838 | i2c_adap); | ||
839 | if (!fe[i]) { | ||
840 | ret = -ENODEV; /* This does not sound nice... */ | ||
841 | goto err; | ||
842 | } | ||
843 | i++; | ||
844 | |||
845 | fe[i] = va1j5jf8007t_attach(&config->va1j5jf8007t_config, | ||
846 | i2c_adap); | ||
847 | if (!fe[i]) { | ||
848 | ret = -ENODEV; | ||
849 | goto err; | ||
850 | } | ||
851 | i++; | ||
852 | |||
853 | ret = va1j5jf8007s_prepare(fe[i - 2]); | ||
854 | if (ret < 0) | ||
855 | goto err; | ||
856 | |||
857 | ret = va1j5jf8007t_prepare(fe[i - 1]); | ||
858 | if (ret < 0) | ||
859 | goto err; | ||
860 | |||
861 | } while (i < 4); | ||
862 | |||
863 | do { | ||
864 | ret = pt1_init_frontend(pt1->adaps[j], fe[j]); | ||
865 | if (ret < 0) | ||
866 | goto err; | ||
867 | } while (++j < 4); | ||
868 | |||
869 | return 0; | ||
870 | |||
871 | err: | ||
872 | while (i-- > j) | ||
873 | fe[i]->ops.release(fe[i]); | ||
874 | |||
875 | while (j--) | ||
876 | dvb_unregister_frontend(fe[j]); | ||
877 | |||
878 | return ret; | ||
879 | } | ||
880 | |||
881 | static void pt1_i2c_emit(struct pt1 *pt1, int addr, int busy, int read_enable, | ||
882 | int clock, int data, int next_addr) | ||
883 | { | ||
884 | pt1_write_reg(pt1, 4, addr << 18 | busy << 13 | read_enable << 12 | | ||
885 | !clock << 11 | !data << 10 | next_addr); | ||
886 | } | ||
887 | |||
888 | static void pt1_i2c_write_bit(struct pt1 *pt1, int addr, int *addrp, int data) | ||
889 | { | ||
890 | pt1_i2c_emit(pt1, addr, 1, 0, 0, data, addr + 1); | ||
891 | pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, data, addr + 2); | ||
892 | pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, data, addr + 3); | ||
893 | *addrp = addr + 3; | ||
894 | } | ||
895 | |||
896 | static void pt1_i2c_read_bit(struct pt1 *pt1, int addr, int *addrp) | ||
897 | { | ||
898 | pt1_i2c_emit(pt1, addr, 1, 0, 0, 1, addr + 1); | ||
899 | pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 1, addr + 2); | ||
900 | pt1_i2c_emit(pt1, addr + 2, 1, 1, 1, 1, addr + 3); | ||
901 | pt1_i2c_emit(pt1, addr + 3, 1, 0, 0, 1, addr + 4); | ||
902 | *addrp = addr + 4; | ||
903 | } | ||
904 | |||
905 | static void pt1_i2c_write_byte(struct pt1 *pt1, int addr, int *addrp, int data) | ||
906 | { | ||
907 | int i; | ||
908 | for (i = 0; i < 8; i++) | ||
909 | pt1_i2c_write_bit(pt1, addr, &addr, data >> (7 - i) & 1); | ||
910 | pt1_i2c_write_bit(pt1, addr, &addr, 1); | ||
911 | *addrp = addr; | ||
912 | } | ||
913 | |||
914 | static void pt1_i2c_read_byte(struct pt1 *pt1, int addr, int *addrp, int last) | ||
915 | { | ||
916 | int i; | ||
917 | for (i = 0; i < 8; i++) | ||
918 | pt1_i2c_read_bit(pt1, addr, &addr); | ||
919 | pt1_i2c_write_bit(pt1, addr, &addr, last); | ||
920 | *addrp = addr; | ||
921 | } | ||
922 | |||
923 | static void pt1_i2c_prepare(struct pt1 *pt1, int addr, int *addrp) | ||
924 | { | ||
925 | pt1_i2c_emit(pt1, addr, 1, 0, 1, 1, addr + 1); | ||
926 | pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2); | ||
927 | pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, 0, addr + 3); | ||
928 | *addrp = addr + 3; | ||
929 | } | ||
930 | |||
931 | static void | ||
932 | pt1_i2c_write_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg) | ||
933 | { | ||
934 | int i; | ||
935 | pt1_i2c_prepare(pt1, addr, &addr); | ||
936 | pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1); | ||
937 | for (i = 0; i < msg->len; i++) | ||
938 | pt1_i2c_write_byte(pt1, addr, &addr, msg->buf[i]); | ||
939 | *addrp = addr; | ||
940 | } | ||
941 | |||
942 | static void | ||
943 | pt1_i2c_read_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg) | ||
944 | { | ||
945 | int i; | ||
946 | pt1_i2c_prepare(pt1, addr, &addr); | ||
947 | pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1 | 1); | ||
948 | for (i = 0; i < msg->len; i++) | ||
949 | pt1_i2c_read_byte(pt1, addr, &addr, i == msg->len - 1); | ||
950 | *addrp = addr; | ||
951 | } | ||
952 | |||
953 | static int pt1_i2c_end(struct pt1 *pt1, int addr) | ||
954 | { | ||
955 | pt1_i2c_emit(pt1, addr, 1, 0, 0, 0, addr + 1); | ||
956 | pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2); | ||
957 | pt1_i2c_emit(pt1, addr + 2, 1, 0, 1, 1, 0); | ||
958 | |||
959 | pt1_write_reg(pt1, 0, 0x00000004); | ||
960 | do { | ||
961 | if (signal_pending(current)) | ||
962 | return -EINTR; | ||
963 | schedule_timeout_interruptible((HZ + 999) / 1000); | ||
964 | } while (pt1_read_reg(pt1, 0) & 0x00000080); | ||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | static void pt1_i2c_begin(struct pt1 *pt1, int *addrp) | ||
969 | { | ||
970 | int addr; | ||
971 | addr = 0; | ||
972 | |||
973 | pt1_i2c_emit(pt1, addr, 0, 0, 1, 1, addr /* itself */); | ||
974 | addr = addr + 1; | ||
975 | |||
976 | if (!pt1->i2c_running) { | ||
977 | pt1_i2c_emit(pt1, addr, 1, 0, 1, 1, addr + 1); | ||
978 | pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2); | ||
979 | addr = addr + 2; | ||
980 | pt1->i2c_running = 1; | ||
981 | } | ||
982 | *addrp = addr; | ||
983 | } | ||
984 | |||
985 | static int pt1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | ||
986 | { | ||
987 | struct pt1 *pt1; | ||
988 | int i; | ||
989 | struct i2c_msg *msg, *next_msg; | ||
990 | int addr, ret; | ||
991 | u16 len; | ||
992 | u32 word; | ||
993 | |||
994 | pt1 = i2c_get_adapdata(adap); | ||
995 | |||
996 | for (i = 0; i < num; i++) { | ||
997 | msg = &msgs[i]; | ||
998 | if (msg->flags & I2C_M_RD) | ||
999 | return -ENOTSUPP; | ||
1000 | |||
1001 | if (i + 1 < num) | ||
1002 | next_msg = &msgs[i + 1]; | ||
1003 | else | ||
1004 | next_msg = NULL; | ||
1005 | |||
1006 | if (next_msg && next_msg->flags & I2C_M_RD) { | ||
1007 | i++; | ||
1008 | |||
1009 | len = next_msg->len; | ||
1010 | if (len > 4) | ||
1011 | return -ENOTSUPP; | ||
1012 | |||
1013 | pt1_i2c_begin(pt1, &addr); | ||
1014 | pt1_i2c_write_msg(pt1, addr, &addr, msg); | ||
1015 | pt1_i2c_read_msg(pt1, addr, &addr, next_msg); | ||
1016 | ret = pt1_i2c_end(pt1, addr); | ||
1017 | if (ret < 0) | ||
1018 | return ret; | ||
1019 | |||
1020 | word = pt1_read_reg(pt1, 2); | ||
1021 | while (len--) { | ||
1022 | next_msg->buf[len] = word; | ||
1023 | word >>= 8; | ||
1024 | } | ||
1025 | } else { | ||
1026 | pt1_i2c_begin(pt1, &addr); | ||
1027 | pt1_i2c_write_msg(pt1, addr, &addr, msg); | ||
1028 | ret = pt1_i2c_end(pt1, addr); | ||
1029 | if (ret < 0) | ||
1030 | return ret; | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | return num; | ||
1035 | } | ||
1036 | |||
1037 | static u32 pt1_i2c_func(struct i2c_adapter *adap) | ||
1038 | { | ||
1039 | return I2C_FUNC_I2C; | ||
1040 | } | ||
1041 | |||
1042 | static const struct i2c_algorithm pt1_i2c_algo = { | ||
1043 | .master_xfer = pt1_i2c_xfer, | ||
1044 | .functionality = pt1_i2c_func, | ||
1045 | }; | ||
1046 | |||
1047 | static void pt1_i2c_wait(struct pt1 *pt1) | ||
1048 | { | ||
1049 | int i; | ||
1050 | for (i = 0; i < 128; i++) | ||
1051 | pt1_i2c_emit(pt1, 0, 0, 0, 1, 1, 0); | ||
1052 | } | ||
1053 | |||
1054 | static void pt1_i2c_init(struct pt1 *pt1) | ||
1055 | { | ||
1056 | int i; | ||
1057 | for (i = 0; i < 1024; i++) | ||
1058 | pt1_i2c_emit(pt1, i, 0, 0, 1, 1, 0); | ||
1059 | } | ||
1060 | |||
1061 | static void __devexit pt1_remove(struct pci_dev *pdev) | ||
1062 | { | ||
1063 | struct pt1 *pt1; | ||
1064 | void __iomem *regs; | ||
1065 | |||
1066 | pt1 = pci_get_drvdata(pdev); | ||
1067 | regs = pt1->regs; | ||
1068 | |||
1069 | if (pt1->kthread) | ||
1070 | kthread_stop(pt1->kthread); | ||
1071 | pt1_cleanup_tables(pt1); | ||
1072 | pt1_cleanup_frontends(pt1); | ||
1073 | pt1_disable_ram(pt1); | ||
1074 | pt1->power = 0; | ||
1075 | pt1->reset = 1; | ||
1076 | pt1_update_power(pt1); | ||
1077 | pt1_cleanup_adapters(pt1); | ||
1078 | i2c_del_adapter(&pt1->i2c_adap); | ||
1079 | pci_set_drvdata(pdev, NULL); | ||
1080 | kfree(pt1); | ||
1081 | pci_iounmap(pdev, regs); | ||
1082 | pci_release_regions(pdev); | ||
1083 | pci_disable_device(pdev); | ||
1084 | } | ||
1085 | |||
1086 | static int __devinit | ||
1087 | pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
1088 | { | ||
1089 | int ret; | ||
1090 | void __iomem *regs; | ||
1091 | struct pt1 *pt1; | ||
1092 | struct i2c_adapter *i2c_adap; | ||
1093 | |||
1094 | ret = pci_enable_device(pdev); | ||
1095 | if (ret < 0) | ||
1096 | goto err; | ||
1097 | |||
1098 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
1099 | if (ret < 0) | ||
1100 | goto err_pci_disable_device; | ||
1101 | |||
1102 | pci_set_master(pdev); | ||
1103 | |||
1104 | ret = pci_request_regions(pdev, DRIVER_NAME); | ||
1105 | if (ret < 0) | ||
1106 | goto err_pci_disable_device; | ||
1107 | |||
1108 | regs = pci_iomap(pdev, 0, 0); | ||
1109 | if (!regs) { | ||
1110 | ret = -EIO; | ||
1111 | goto err_pci_release_regions; | ||
1112 | } | ||
1113 | |||
1114 | pt1 = kzalloc(sizeof(struct pt1), GFP_KERNEL); | ||
1115 | if (!pt1) { | ||
1116 | ret = -ENOMEM; | ||
1117 | goto err_pci_iounmap; | ||
1118 | } | ||
1119 | |||
1120 | mutex_init(&pt1->lock); | ||
1121 | pt1->pdev = pdev; | ||
1122 | pt1->regs = regs; | ||
1123 | pci_set_drvdata(pdev, pt1); | ||
1124 | |||
1125 | ret = pt1_init_adapters(pt1); | ||
1126 | if (ret < 0) | ||
1127 | goto err_kfree; | ||
1128 | |||
1129 | mutex_init(&pt1->lock); | ||
1130 | |||
1131 | pt1->power = 0; | ||
1132 | pt1->reset = 1; | ||
1133 | pt1_update_power(pt1); | ||
1134 | |||
1135 | i2c_adap = &pt1->i2c_adap; | ||
1136 | i2c_adap->algo = &pt1_i2c_algo; | ||
1137 | i2c_adap->algo_data = NULL; | ||
1138 | i2c_adap->dev.parent = &pdev->dev; | ||
1139 | strcpy(i2c_adap->name, DRIVER_NAME); | ||
1140 | i2c_set_adapdata(i2c_adap, pt1); | ||
1141 | ret = i2c_add_adapter(i2c_adap); | ||
1142 | if (ret < 0) | ||
1143 | goto err_pt1_cleanup_adapters; | ||
1144 | |||
1145 | pt1_i2c_init(pt1); | ||
1146 | pt1_i2c_wait(pt1); | ||
1147 | |||
1148 | ret = pt1_sync(pt1); | ||
1149 | if (ret < 0) | ||
1150 | goto err_i2c_del_adapter; | ||
1151 | |||
1152 | pt1_identify(pt1); | ||
1153 | |||
1154 | ret = pt1_unlock(pt1); | ||
1155 | if (ret < 0) | ||
1156 | goto err_i2c_del_adapter; | ||
1157 | |||
1158 | ret = pt1_reset_pci(pt1); | ||
1159 | if (ret < 0) | ||
1160 | goto err_i2c_del_adapter; | ||
1161 | |||
1162 | ret = pt1_reset_ram(pt1); | ||
1163 | if (ret < 0) | ||
1164 | goto err_i2c_del_adapter; | ||
1165 | |||
1166 | ret = pt1_enable_ram(pt1); | ||
1167 | if (ret < 0) | ||
1168 | goto err_i2c_del_adapter; | ||
1169 | |||
1170 | pt1_init_streams(pt1); | ||
1171 | |||
1172 | pt1->power = 1; | ||
1173 | pt1_update_power(pt1); | ||
1174 | schedule_timeout_uninterruptible((HZ + 49) / 50); | ||
1175 | |||
1176 | pt1->reset = 0; | ||
1177 | pt1_update_power(pt1); | ||
1178 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
1179 | |||
1180 | ret = pt1_init_frontends(pt1); | ||
1181 | if (ret < 0) | ||
1182 | goto err_pt1_disable_ram; | ||
1183 | |||
1184 | ret = pt1_init_tables(pt1); | ||
1185 | if (ret < 0) | ||
1186 | goto err_pt1_cleanup_frontends; | ||
1187 | |||
1188 | return 0; | ||
1189 | |||
1190 | err_pt1_cleanup_frontends: | ||
1191 | pt1_cleanup_frontends(pt1); | ||
1192 | err_pt1_disable_ram: | ||
1193 | pt1_disable_ram(pt1); | ||
1194 | pt1->power = 0; | ||
1195 | pt1->reset = 1; | ||
1196 | pt1_update_power(pt1); | ||
1197 | err_i2c_del_adapter: | ||
1198 | i2c_del_adapter(i2c_adap); | ||
1199 | err_pt1_cleanup_adapters: | ||
1200 | pt1_cleanup_adapters(pt1); | ||
1201 | err_kfree: | ||
1202 | pci_set_drvdata(pdev, NULL); | ||
1203 | kfree(pt1); | ||
1204 | err_pci_iounmap: | ||
1205 | pci_iounmap(pdev, regs); | ||
1206 | err_pci_release_regions: | ||
1207 | pci_release_regions(pdev); | ||
1208 | err_pci_disable_device: | ||
1209 | pci_disable_device(pdev); | ||
1210 | err: | ||
1211 | return ret; | ||
1212 | |||
1213 | } | ||
1214 | |||
1215 | static struct pci_device_id pt1_id_table[] = { | ||
1216 | { PCI_DEVICE(0x10ee, 0x211a) }, | ||
1217 | { PCI_DEVICE(0x10ee, 0x222a) }, | ||
1218 | { }, | ||
1219 | }; | ||
1220 | MODULE_DEVICE_TABLE(pci, pt1_id_table); | ||
1221 | |||
1222 | static struct pci_driver pt1_driver = { | ||
1223 | .name = DRIVER_NAME, | ||
1224 | .probe = pt1_probe, | ||
1225 | .remove = __devexit_p(pt1_remove), | ||
1226 | .id_table = pt1_id_table, | ||
1227 | }; | ||
1228 | |||
1229 | |||
1230 | static int __init pt1_init(void) | ||
1231 | { | ||
1232 | return pci_register_driver(&pt1_driver); | ||
1233 | } | ||
1234 | |||
1235 | |||
1236 | static void __exit pt1_cleanup(void) | ||
1237 | { | ||
1238 | pci_unregister_driver(&pt1_driver); | ||
1239 | } | ||
1240 | |||
1241 | module_init(pt1_init); | ||
1242 | module_exit(pt1_cleanup); | ||
1243 | |||
1244 | MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>"); | ||
1245 | MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver"); | ||
1246 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c deleted file mode 100644 index d980dfb21e5e..000000000000 --- a/drivers/media/dvb/pt1/va1j5jf8007s.c +++ /dev/null | |||
@@ -1,735 +0,0 @@ | |||
1 | /* | ||
2 | * ISDB-S driver for VA1J5JF8007/VA1J5JF8011 | ||
3 | * | ||
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | ||
5 | * | ||
6 | * based on pt1dvr - http://pt1dvr.sourceforge.jp/ | ||
7 | * by Tomoaki Ishikawa <tomy@users.sourceforge.jp> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "va1j5jf8007s.h" | ||
30 | |||
31 | enum va1j5jf8007s_tune_state { | ||
32 | VA1J5JF8007S_IDLE, | ||
33 | VA1J5JF8007S_SET_FREQUENCY_1, | ||
34 | VA1J5JF8007S_SET_FREQUENCY_2, | ||
35 | VA1J5JF8007S_SET_FREQUENCY_3, | ||
36 | VA1J5JF8007S_CHECK_FREQUENCY, | ||
37 | VA1J5JF8007S_SET_MODULATION, | ||
38 | VA1J5JF8007S_CHECK_MODULATION, | ||
39 | VA1J5JF8007S_SET_TS_ID, | ||
40 | VA1J5JF8007S_CHECK_TS_ID, | ||
41 | VA1J5JF8007S_TRACK, | ||
42 | }; | ||
43 | |||
44 | struct va1j5jf8007s_state { | ||
45 | const struct va1j5jf8007s_config *config; | ||
46 | struct i2c_adapter *adap; | ||
47 | struct dvb_frontend fe; | ||
48 | enum va1j5jf8007s_tune_state tune_state; | ||
49 | }; | ||
50 | |||
51 | static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
52 | { | ||
53 | struct va1j5jf8007s_state *state; | ||
54 | u8 addr; | ||
55 | int i; | ||
56 | u8 write_buf[1], read_buf[1]; | ||
57 | struct i2c_msg msgs[2]; | ||
58 | s32 word, x1, x2, x3, x4, x5, y; | ||
59 | |||
60 | state = fe->demodulator_priv; | ||
61 | addr = state->config->demod_address; | ||
62 | |||
63 | word = 0; | ||
64 | for (i = 0; i < 2; i++) { | ||
65 | write_buf[0] = 0xbc + i; | ||
66 | |||
67 | msgs[0].addr = addr; | ||
68 | msgs[0].flags = 0; | ||
69 | msgs[0].len = sizeof(write_buf); | ||
70 | msgs[0].buf = write_buf; | ||
71 | |||
72 | msgs[1].addr = addr; | ||
73 | msgs[1].flags = I2C_M_RD; | ||
74 | msgs[1].len = sizeof(read_buf); | ||
75 | msgs[1].buf = read_buf; | ||
76 | |||
77 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
78 | return -EREMOTEIO; | ||
79 | |||
80 | word <<= 8; | ||
81 | word |= read_buf[0]; | ||
82 | } | ||
83 | |||
84 | word -= 3000; | ||
85 | if (word < 0) | ||
86 | word = 0; | ||
87 | |||
88 | x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000); | ||
89 | x2 = (s64)x1 * x1 >> 31; | ||
90 | x3 = (s64)x2 * x1 >> 31; | ||
91 | x4 = (s64)x2 * x2 >> 31; | ||
92 | x5 = (s64)x4 * x1 >> 31; | ||
93 | |||
94 | y = (58857ll << 23) / 1000; | ||
95 | y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30; | ||
96 | y += (s64)x2 * ((88977ll << 24) / 1000) >> 28; | ||
97 | y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27; | ||
98 | y += (s64)x4 * ((14341ll << 27) / 1000) >> 27; | ||
99 | y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28; | ||
100 | |||
101 | *snr = y < 0 ? 0 : y >> 15; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe) | ||
106 | { | ||
107 | return DVBFE_ALGO_HW; | ||
108 | } | ||
109 | |||
110 | static int | ||
111 | va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
112 | { | ||
113 | struct va1j5jf8007s_state *state; | ||
114 | |||
115 | state = fe->demodulator_priv; | ||
116 | |||
117 | switch (state->tune_state) { | ||
118 | case VA1J5JF8007S_IDLE: | ||
119 | case VA1J5JF8007S_SET_FREQUENCY_1: | ||
120 | case VA1J5JF8007S_SET_FREQUENCY_2: | ||
121 | case VA1J5JF8007S_SET_FREQUENCY_3: | ||
122 | case VA1J5JF8007S_CHECK_FREQUENCY: | ||
123 | *status = 0; | ||
124 | return 0; | ||
125 | |||
126 | |||
127 | case VA1J5JF8007S_SET_MODULATION: | ||
128 | case VA1J5JF8007S_CHECK_MODULATION: | ||
129 | *status |= FE_HAS_SIGNAL; | ||
130 | return 0; | ||
131 | |||
132 | case VA1J5JF8007S_SET_TS_ID: | ||
133 | case VA1J5JF8007S_CHECK_TS_ID: | ||
134 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; | ||
135 | return 0; | ||
136 | |||
137 | case VA1J5JF8007S_TRACK: | ||
138 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK; | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | BUG(); | ||
143 | } | ||
144 | |||
145 | struct va1j5jf8007s_cb_map { | ||
146 | u32 frequency; | ||
147 | u8 cb; | ||
148 | }; | ||
149 | |||
150 | static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = { | ||
151 | { 986000, 0xb2 }, | ||
152 | { 1072000, 0xd2 }, | ||
153 | { 1154000, 0xe2 }, | ||
154 | { 1291000, 0x20 }, | ||
155 | { 1447000, 0x40 }, | ||
156 | { 1615000, 0x60 }, | ||
157 | { 1791000, 0x80 }, | ||
158 | { 1972000, 0xa0 }, | ||
159 | }; | ||
160 | |||
161 | static u8 va1j5jf8007s_lookup_cb(u32 frequency) | ||
162 | { | ||
163 | int i; | ||
164 | const struct va1j5jf8007s_cb_map *map; | ||
165 | |||
166 | for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) { | ||
167 | map = &va1j5jf8007s_cb_maps[i]; | ||
168 | if (frequency < map->frequency) | ||
169 | return map->cb; | ||
170 | } | ||
171 | return 0xc0; | ||
172 | } | ||
173 | |||
174 | static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state) | ||
175 | { | ||
176 | u32 frequency; | ||
177 | u16 word; | ||
178 | u8 buf[6]; | ||
179 | struct i2c_msg msg; | ||
180 | |||
181 | frequency = state->fe.dtv_property_cache.frequency; | ||
182 | |||
183 | word = (frequency + 500) / 1000; | ||
184 | if (frequency < 1072000) | ||
185 | word = (word << 1 & ~0x1f) | (word & 0x0f); | ||
186 | |||
187 | buf[0] = 0xfe; | ||
188 | buf[1] = 0xc0; | ||
189 | buf[2] = 0x40 | word >> 8; | ||
190 | buf[3] = word; | ||
191 | buf[4] = 0xe0; | ||
192 | buf[5] = va1j5jf8007s_lookup_cb(frequency); | ||
193 | |||
194 | msg.addr = state->config->demod_address; | ||
195 | msg.flags = 0; | ||
196 | msg.len = sizeof(buf); | ||
197 | msg.buf = buf; | ||
198 | |||
199 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
200 | return -EREMOTEIO; | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state) | ||
206 | { | ||
207 | u8 buf[3]; | ||
208 | struct i2c_msg msg; | ||
209 | |||
210 | buf[0] = 0xfe; | ||
211 | buf[1] = 0xc0; | ||
212 | buf[2] = 0xe4; | ||
213 | |||
214 | msg.addr = state->config->demod_address; | ||
215 | msg.flags = 0; | ||
216 | msg.len = sizeof(buf); | ||
217 | msg.buf = buf; | ||
218 | |||
219 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
220 | return -EREMOTEIO; | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state) | ||
226 | { | ||
227 | u32 frequency; | ||
228 | u8 buf[4]; | ||
229 | struct i2c_msg msg; | ||
230 | |||
231 | frequency = state->fe.dtv_property_cache.frequency; | ||
232 | |||
233 | buf[0] = 0xfe; | ||
234 | buf[1] = 0xc0; | ||
235 | buf[2] = 0xf4; | ||
236 | buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4; | ||
237 | |||
238 | msg.addr = state->config->demod_address; | ||
239 | msg.flags = 0; | ||
240 | msg.len = sizeof(buf); | ||
241 | msg.buf = buf; | ||
242 | |||
243 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
244 | return -EREMOTEIO; | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int | ||
250 | va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock) | ||
251 | { | ||
252 | u8 addr; | ||
253 | u8 write_buf[2], read_buf[1]; | ||
254 | struct i2c_msg msgs[2]; | ||
255 | |||
256 | addr = state->config->demod_address; | ||
257 | |||
258 | write_buf[0] = 0xfe; | ||
259 | write_buf[1] = 0xc1; | ||
260 | |||
261 | msgs[0].addr = addr; | ||
262 | msgs[0].flags = 0; | ||
263 | msgs[0].len = sizeof(write_buf); | ||
264 | msgs[0].buf = write_buf; | ||
265 | |||
266 | msgs[1].addr = addr; | ||
267 | msgs[1].flags = I2C_M_RD; | ||
268 | msgs[1].len = sizeof(read_buf); | ||
269 | msgs[1].buf = read_buf; | ||
270 | |||
271 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
272 | return -EREMOTEIO; | ||
273 | |||
274 | *lock = read_buf[0] & 0x40; | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state) | ||
279 | { | ||
280 | u8 buf[2]; | ||
281 | struct i2c_msg msg; | ||
282 | |||
283 | buf[0] = 0x03; | ||
284 | buf[1] = 0x01; | ||
285 | |||
286 | msg.addr = state->config->demod_address; | ||
287 | msg.flags = 0; | ||
288 | msg.len = sizeof(buf); | ||
289 | msg.buf = buf; | ||
290 | |||
291 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
292 | return -EREMOTEIO; | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int | ||
298 | va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock) | ||
299 | { | ||
300 | u8 addr; | ||
301 | u8 write_buf[1], read_buf[1]; | ||
302 | struct i2c_msg msgs[2]; | ||
303 | |||
304 | addr = state->config->demod_address; | ||
305 | |||
306 | write_buf[0] = 0xc3; | ||
307 | |||
308 | msgs[0].addr = addr; | ||
309 | msgs[0].flags = 0; | ||
310 | msgs[0].len = sizeof(write_buf); | ||
311 | msgs[0].buf = write_buf; | ||
312 | |||
313 | msgs[1].addr = addr; | ||
314 | msgs[1].flags = I2C_M_RD; | ||
315 | msgs[1].len = sizeof(read_buf); | ||
316 | msgs[1].buf = read_buf; | ||
317 | |||
318 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
319 | return -EREMOTEIO; | ||
320 | |||
321 | *lock = !(read_buf[0] & 0x10); | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int | ||
326 | va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state) | ||
327 | { | ||
328 | u32 ts_id; | ||
329 | u8 buf[3]; | ||
330 | struct i2c_msg msg; | ||
331 | |||
332 | ts_id = state->fe.dtv_property_cache.isdbs_ts_id; | ||
333 | if (!ts_id) | ||
334 | return 0; | ||
335 | |||
336 | buf[0] = 0x8f; | ||
337 | buf[1] = ts_id >> 8; | ||
338 | buf[2] = ts_id; | ||
339 | |||
340 | msg.addr = state->config->demod_address; | ||
341 | msg.flags = 0; | ||
342 | msg.len = sizeof(buf); | ||
343 | msg.buf = buf; | ||
344 | |||
345 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
346 | return -EREMOTEIO; | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int | ||
352 | va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock) | ||
353 | { | ||
354 | u8 addr; | ||
355 | u8 write_buf[1], read_buf[2]; | ||
356 | struct i2c_msg msgs[2]; | ||
357 | u32 ts_id; | ||
358 | |||
359 | ts_id = state->fe.dtv_property_cache.isdbs_ts_id; | ||
360 | if (!ts_id) { | ||
361 | *lock = 1; | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | addr = state->config->demod_address; | ||
366 | |||
367 | write_buf[0] = 0xe6; | ||
368 | |||
369 | msgs[0].addr = addr; | ||
370 | msgs[0].flags = 0; | ||
371 | msgs[0].len = sizeof(write_buf); | ||
372 | msgs[0].buf = write_buf; | ||
373 | |||
374 | msgs[1].addr = addr; | ||
375 | msgs[1].flags = I2C_M_RD; | ||
376 | msgs[1].len = sizeof(read_buf); | ||
377 | msgs[1].buf = read_buf; | ||
378 | |||
379 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
380 | return -EREMOTEIO; | ||
381 | |||
382 | *lock = (read_buf[0] << 8 | read_buf[1]) == ts_id; | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static int | ||
387 | va1j5jf8007s_tune(struct dvb_frontend *fe, | ||
388 | bool re_tune, | ||
389 | unsigned int mode_flags, unsigned int *delay, | ||
390 | fe_status_t *status) | ||
391 | { | ||
392 | struct va1j5jf8007s_state *state; | ||
393 | int ret; | ||
394 | int lock = 0; | ||
395 | |||
396 | state = fe->demodulator_priv; | ||
397 | |||
398 | if (re_tune) | ||
399 | state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1; | ||
400 | |||
401 | switch (state->tune_state) { | ||
402 | case VA1J5JF8007S_IDLE: | ||
403 | *delay = 3 * HZ; | ||
404 | *status = 0; | ||
405 | return 0; | ||
406 | |||
407 | case VA1J5JF8007S_SET_FREQUENCY_1: | ||
408 | ret = va1j5jf8007s_set_frequency_1(state); | ||
409 | if (ret < 0) | ||
410 | return ret; | ||
411 | |||
412 | state->tune_state = VA1J5JF8007S_SET_FREQUENCY_2; | ||
413 | *delay = 0; | ||
414 | *status = 0; | ||
415 | return 0; | ||
416 | |||
417 | case VA1J5JF8007S_SET_FREQUENCY_2: | ||
418 | ret = va1j5jf8007s_set_frequency_2(state); | ||
419 | if (ret < 0) | ||
420 | return ret; | ||
421 | |||
422 | state->tune_state = VA1J5JF8007S_SET_FREQUENCY_3; | ||
423 | *delay = (HZ + 99) / 100; | ||
424 | *status = 0; | ||
425 | return 0; | ||
426 | |||
427 | case VA1J5JF8007S_SET_FREQUENCY_3: | ||
428 | ret = va1j5jf8007s_set_frequency_3(state); | ||
429 | if (ret < 0) | ||
430 | return ret; | ||
431 | |||
432 | state->tune_state = VA1J5JF8007S_CHECK_FREQUENCY; | ||
433 | *delay = 0; | ||
434 | *status = 0; | ||
435 | return 0; | ||
436 | |||
437 | case VA1J5JF8007S_CHECK_FREQUENCY: | ||
438 | ret = va1j5jf8007s_check_frequency(state, &lock); | ||
439 | if (ret < 0) | ||
440 | return ret; | ||
441 | |||
442 | if (!lock) { | ||
443 | *delay = (HZ + 999) / 1000; | ||
444 | *status = 0; | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | state->tune_state = VA1J5JF8007S_SET_MODULATION; | ||
449 | *delay = 0; | ||
450 | *status = FE_HAS_SIGNAL; | ||
451 | return 0; | ||
452 | |||
453 | case VA1J5JF8007S_SET_MODULATION: | ||
454 | ret = va1j5jf8007s_set_modulation(state); | ||
455 | if (ret < 0) | ||
456 | return ret; | ||
457 | |||
458 | state->tune_state = VA1J5JF8007S_CHECK_MODULATION; | ||
459 | *delay = 0; | ||
460 | *status = FE_HAS_SIGNAL; | ||
461 | return 0; | ||
462 | |||
463 | case VA1J5JF8007S_CHECK_MODULATION: | ||
464 | ret = va1j5jf8007s_check_modulation(state, &lock); | ||
465 | if (ret < 0) | ||
466 | return ret; | ||
467 | |||
468 | if (!lock) { | ||
469 | *delay = (HZ + 49) / 50; | ||
470 | *status = FE_HAS_SIGNAL; | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | state->tune_state = VA1J5JF8007S_SET_TS_ID; | ||
475 | *delay = 0; | ||
476 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; | ||
477 | return 0; | ||
478 | |||
479 | case VA1J5JF8007S_SET_TS_ID: | ||
480 | ret = va1j5jf8007s_set_ts_id(state); | ||
481 | if (ret < 0) | ||
482 | return ret; | ||
483 | |||
484 | state->tune_state = VA1J5JF8007S_CHECK_TS_ID; | ||
485 | return 0; | ||
486 | |||
487 | case VA1J5JF8007S_CHECK_TS_ID: | ||
488 | ret = va1j5jf8007s_check_ts_id(state, &lock); | ||
489 | if (ret < 0) | ||
490 | return ret; | ||
491 | |||
492 | if (!lock) { | ||
493 | *delay = (HZ + 99) / 100; | ||
494 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | state->tune_state = VA1J5JF8007S_TRACK; | ||
499 | /* fall through */ | ||
500 | |||
501 | case VA1J5JF8007S_TRACK: | ||
502 | *delay = 3 * HZ; | ||
503 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK; | ||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | BUG(); | ||
508 | } | ||
509 | |||
510 | static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state) | ||
511 | { | ||
512 | u8 buf[4]; | ||
513 | struct i2c_msg msg; | ||
514 | |||
515 | buf[0] = 0xfe; | ||
516 | buf[1] = 0xc0; | ||
517 | buf[2] = 0xf0; | ||
518 | buf[3] = 0x04; | ||
519 | |||
520 | msg.addr = state->config->demod_address; | ||
521 | msg.flags = 0; | ||
522 | msg.len = sizeof(buf); | ||
523 | msg.buf = buf; | ||
524 | |||
525 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
526 | return -EREMOTEIO; | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep) | ||
532 | { | ||
533 | u8 buf[2]; | ||
534 | struct i2c_msg msg; | ||
535 | |||
536 | buf[0] = 0x17; | ||
537 | buf[1] = sleep ? 0x01 : 0x00; | ||
538 | |||
539 | msg.addr = state->config->demod_address; | ||
540 | msg.flags = 0; | ||
541 | msg.len = sizeof(buf); | ||
542 | msg.buf = buf; | ||
543 | |||
544 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
545 | return -EREMOTEIO; | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int va1j5jf8007s_sleep(struct dvb_frontend *fe) | ||
551 | { | ||
552 | struct va1j5jf8007s_state *state; | ||
553 | int ret; | ||
554 | |||
555 | state = fe->demodulator_priv; | ||
556 | |||
557 | ret = va1j5jf8007s_init_frequency(state); | ||
558 | if (ret < 0) | ||
559 | return ret; | ||
560 | |||
561 | return va1j5jf8007s_set_sleep(state, 1); | ||
562 | } | ||
563 | |||
564 | static int va1j5jf8007s_init(struct dvb_frontend *fe) | ||
565 | { | ||
566 | struct va1j5jf8007s_state *state; | ||
567 | |||
568 | state = fe->demodulator_priv; | ||
569 | state->tune_state = VA1J5JF8007S_IDLE; | ||
570 | |||
571 | return va1j5jf8007s_set_sleep(state, 0); | ||
572 | } | ||
573 | |||
574 | static void va1j5jf8007s_release(struct dvb_frontend *fe) | ||
575 | { | ||
576 | struct va1j5jf8007s_state *state; | ||
577 | state = fe->demodulator_priv; | ||
578 | kfree(state); | ||
579 | } | ||
580 | |||
581 | static struct dvb_frontend_ops va1j5jf8007s_ops = { | ||
582 | .delsys = { SYS_ISDBS }, | ||
583 | .info = { | ||
584 | .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S", | ||
585 | .frequency_min = 950000, | ||
586 | .frequency_max = 2150000, | ||
587 | .frequency_stepsize = 1000, | ||
588 | .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | | ||
589 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
590 | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, | ||
591 | }, | ||
592 | |||
593 | .read_snr = va1j5jf8007s_read_snr, | ||
594 | .get_frontend_algo = va1j5jf8007s_get_frontend_algo, | ||
595 | .read_status = va1j5jf8007s_read_status, | ||
596 | .tune = va1j5jf8007s_tune, | ||
597 | .sleep = va1j5jf8007s_sleep, | ||
598 | .init = va1j5jf8007s_init, | ||
599 | .release = va1j5jf8007s_release, | ||
600 | }; | ||
601 | |||
602 | static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state) | ||
603 | { | ||
604 | u8 addr; | ||
605 | u8 write_buf[1], read_buf[1]; | ||
606 | struct i2c_msg msgs[2]; | ||
607 | |||
608 | addr = state->config->demod_address; | ||
609 | |||
610 | write_buf[0] = 0x07; | ||
611 | |||
612 | msgs[0].addr = addr; | ||
613 | msgs[0].flags = 0; | ||
614 | msgs[0].len = sizeof(write_buf); | ||
615 | msgs[0].buf = write_buf; | ||
616 | |||
617 | msgs[1].addr = addr; | ||
618 | msgs[1].flags = I2C_M_RD; | ||
619 | msgs[1].len = sizeof(read_buf); | ||
620 | msgs[1].buf = read_buf; | ||
621 | |||
622 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
623 | return -EREMOTEIO; | ||
624 | |||
625 | if (read_buf[0] != 0x41) | ||
626 | return -EIO; | ||
627 | |||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static const u8 va1j5jf8007s_20mhz_prepare_bufs[][2] = { | ||
632 | {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, | ||
633 | {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, | ||
634 | {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, | ||
635 | {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0}, | ||
636 | }; | ||
637 | |||
638 | static const u8 va1j5jf8007s_25mhz_prepare_bufs[][2] = { | ||
639 | {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a}, | ||
640 | {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89}, | ||
641 | {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04}, | ||
642 | {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0}, | ||
643 | }; | ||
644 | |||
645 | static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state) | ||
646 | { | ||
647 | const u8 (*bufs)[2]; | ||
648 | int size; | ||
649 | u8 addr; | ||
650 | u8 buf[2]; | ||
651 | struct i2c_msg msg; | ||
652 | int i; | ||
653 | |||
654 | switch (state->config->frequency) { | ||
655 | case VA1J5JF8007S_20MHZ: | ||
656 | bufs = va1j5jf8007s_20mhz_prepare_bufs; | ||
657 | size = ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs); | ||
658 | break; | ||
659 | case VA1J5JF8007S_25MHZ: | ||
660 | bufs = va1j5jf8007s_25mhz_prepare_bufs; | ||
661 | size = ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs); | ||
662 | break; | ||
663 | default: | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | |||
667 | addr = state->config->demod_address; | ||
668 | |||
669 | msg.addr = addr; | ||
670 | msg.flags = 0; | ||
671 | msg.len = 2; | ||
672 | msg.buf = buf; | ||
673 | for (i = 0; i < size; i++) { | ||
674 | memcpy(buf, bufs[i], sizeof(buf)); | ||
675 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
676 | return -EREMOTEIO; | ||
677 | } | ||
678 | |||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | /* must be called after va1j5jf8007t_attach */ | ||
683 | int va1j5jf8007s_prepare(struct dvb_frontend *fe) | ||
684 | { | ||
685 | struct va1j5jf8007s_state *state; | ||
686 | int ret; | ||
687 | |||
688 | state = fe->demodulator_priv; | ||
689 | |||
690 | ret = va1j5jf8007s_prepare_1(state); | ||
691 | if (ret < 0) | ||
692 | return ret; | ||
693 | |||
694 | ret = va1j5jf8007s_prepare_2(state); | ||
695 | if (ret < 0) | ||
696 | return ret; | ||
697 | |||
698 | return va1j5jf8007s_init_frequency(state); | ||
699 | } | ||
700 | |||
701 | struct dvb_frontend * | ||
702 | va1j5jf8007s_attach(const struct va1j5jf8007s_config *config, | ||
703 | struct i2c_adapter *adap) | ||
704 | { | ||
705 | struct va1j5jf8007s_state *state; | ||
706 | struct dvb_frontend *fe; | ||
707 | u8 buf[2]; | ||
708 | struct i2c_msg msg; | ||
709 | |||
710 | state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL); | ||
711 | if (!state) | ||
712 | return NULL; | ||
713 | |||
714 | state->config = config; | ||
715 | state->adap = adap; | ||
716 | |||
717 | fe = &state->fe; | ||
718 | memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops)); | ||
719 | fe->demodulator_priv = state; | ||
720 | |||
721 | buf[0] = 0x01; | ||
722 | buf[1] = 0x80; | ||
723 | |||
724 | msg.addr = state->config->demod_address; | ||
725 | msg.flags = 0; | ||
726 | msg.len = sizeof(buf); | ||
727 | msg.buf = buf; | ||
728 | |||
729 | if (i2c_transfer(state->adap, &msg, 1) != 1) { | ||
730 | kfree(state); | ||
731 | return NULL; | ||
732 | } | ||
733 | |||
734 | return fe; | ||
735 | } | ||
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/dvb/pt1/va1j5jf8007s.h deleted file mode 100644 index b7d6f05a0e02..000000000000 --- a/drivers/media/dvb/pt1/va1j5jf8007s.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * ISDB-S driver for VA1J5JF8007/VA1J5JF8011 | ||
3 | * | ||
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | ||
5 | * | ||
6 | * based on pt1dvr - http://pt1dvr.sourceforge.jp/ | ||
7 | * by Tomoaki Ishikawa <tomy@users.sourceforge.jp> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef VA1J5JF8007S_H | ||
25 | #define VA1J5JF8007S_H | ||
26 | |||
27 | enum va1j5jf8007s_frequency { | ||
28 | VA1J5JF8007S_20MHZ, | ||
29 | VA1J5JF8007S_25MHZ, | ||
30 | }; | ||
31 | |||
32 | struct va1j5jf8007s_config { | ||
33 | u8 demod_address; | ||
34 | enum va1j5jf8007s_frequency frequency; | ||
35 | }; | ||
36 | |||
37 | struct i2c_adapter; | ||
38 | |||
39 | struct dvb_frontend * | ||
40 | va1j5jf8007s_attach(const struct va1j5jf8007s_config *config, | ||
41 | struct i2c_adapter *adap); | ||
42 | |||
43 | /* must be called after va1j5jf8007t_attach */ | ||
44 | int va1j5jf8007s_prepare(struct dvb_frontend *fe); | ||
45 | |||
46 | #endif | ||
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c deleted file mode 100644 index 2db15159d514..000000000000 --- a/drivers/media/dvb/pt1/va1j5jf8007t.c +++ /dev/null | |||
@@ -1,536 +0,0 @@ | |||
1 | /* | ||
2 | * ISDB-T driver for VA1J5JF8007/VA1J5JF8011 | ||
3 | * | ||
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | ||
5 | * | ||
6 | * based on pt1dvr - http://pt1dvr.sourceforge.jp/ | ||
7 | * by Tomoaki Ishikawa <tomy@users.sourceforge.jp> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_math.h" | ||
30 | #include "va1j5jf8007t.h" | ||
31 | |||
32 | enum va1j5jf8007t_tune_state { | ||
33 | VA1J5JF8007T_IDLE, | ||
34 | VA1J5JF8007T_SET_FREQUENCY, | ||
35 | VA1J5JF8007T_CHECK_FREQUENCY, | ||
36 | VA1J5JF8007T_SET_MODULATION, | ||
37 | VA1J5JF8007T_CHECK_MODULATION, | ||
38 | VA1J5JF8007T_TRACK, | ||
39 | VA1J5JF8007T_ABORT, | ||
40 | }; | ||
41 | |||
42 | struct va1j5jf8007t_state { | ||
43 | const struct va1j5jf8007t_config *config; | ||
44 | struct i2c_adapter *adap; | ||
45 | struct dvb_frontend fe; | ||
46 | enum va1j5jf8007t_tune_state tune_state; | ||
47 | }; | ||
48 | |||
49 | static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
50 | { | ||
51 | struct va1j5jf8007t_state *state; | ||
52 | u8 addr; | ||
53 | int i; | ||
54 | u8 write_buf[1], read_buf[1]; | ||
55 | struct i2c_msg msgs[2]; | ||
56 | s32 word, x, y; | ||
57 | |||
58 | state = fe->demodulator_priv; | ||
59 | addr = state->config->demod_address; | ||
60 | |||
61 | word = 0; | ||
62 | for (i = 0; i < 3; i++) { | ||
63 | write_buf[0] = 0x8b + i; | ||
64 | |||
65 | msgs[0].addr = addr; | ||
66 | msgs[0].flags = 0; | ||
67 | msgs[0].len = sizeof(write_buf); | ||
68 | msgs[0].buf = write_buf; | ||
69 | |||
70 | msgs[1].addr = addr; | ||
71 | msgs[1].flags = I2C_M_RD; | ||
72 | msgs[1].len = sizeof(read_buf); | ||
73 | msgs[1].buf = read_buf; | ||
74 | |||
75 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
76 | return -EREMOTEIO; | ||
77 | |||
78 | word <<= 8; | ||
79 | word |= read_buf[0]; | ||
80 | } | ||
81 | |||
82 | if (!word) | ||
83 | return -EIO; | ||
84 | |||
85 | x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24)); | ||
86 | y = (24ll << 46) / 1000000; | ||
87 | y = ((s64)y * x >> 30) - (16ll << 40) / 10000; | ||
88 | y = ((s64)y * x >> 29) + (398ll << 35) / 10000; | ||
89 | y = ((s64)y * x >> 30) + (5491ll << 29) / 10000; | ||
90 | y = ((s64)y * x >> 30) + (30965ll << 23) / 10000; | ||
91 | *snr = y >> 15; | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe) | ||
96 | { | ||
97 | return DVBFE_ALGO_HW; | ||
98 | } | ||
99 | |||
100 | static int | ||
101 | va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
102 | { | ||
103 | struct va1j5jf8007t_state *state; | ||
104 | |||
105 | state = fe->demodulator_priv; | ||
106 | |||
107 | switch (state->tune_state) { | ||
108 | case VA1J5JF8007T_IDLE: | ||
109 | case VA1J5JF8007T_SET_FREQUENCY: | ||
110 | case VA1J5JF8007T_CHECK_FREQUENCY: | ||
111 | *status = 0; | ||
112 | return 0; | ||
113 | |||
114 | |||
115 | case VA1J5JF8007T_SET_MODULATION: | ||
116 | case VA1J5JF8007T_CHECK_MODULATION: | ||
117 | case VA1J5JF8007T_ABORT: | ||
118 | *status |= FE_HAS_SIGNAL; | ||
119 | return 0; | ||
120 | |||
121 | case VA1J5JF8007T_TRACK: | ||
122 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK; | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | BUG(); | ||
127 | } | ||
128 | |||
129 | struct va1j5jf8007t_cb_map { | ||
130 | u32 frequency; | ||
131 | u8 cb; | ||
132 | }; | ||
133 | |||
134 | static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = { | ||
135 | { 90000000, 0x80 }, | ||
136 | { 140000000, 0x81 }, | ||
137 | { 170000000, 0xa1 }, | ||
138 | { 220000000, 0x62 }, | ||
139 | { 330000000, 0xa2 }, | ||
140 | { 402000000, 0xe2 }, | ||
141 | { 450000000, 0x64 }, | ||
142 | { 550000000, 0x84 }, | ||
143 | { 600000000, 0xa4 }, | ||
144 | { 700000000, 0xc4 }, | ||
145 | }; | ||
146 | |||
147 | static u8 va1j5jf8007t_lookup_cb(u32 frequency) | ||
148 | { | ||
149 | int i; | ||
150 | const struct va1j5jf8007t_cb_map *map; | ||
151 | |||
152 | for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) { | ||
153 | map = &va1j5jf8007t_cb_maps[i]; | ||
154 | if (frequency < map->frequency) | ||
155 | return map->cb; | ||
156 | } | ||
157 | return 0xe4; | ||
158 | } | ||
159 | |||
160 | static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state) | ||
161 | { | ||
162 | u32 frequency; | ||
163 | u16 word; | ||
164 | u8 buf[6]; | ||
165 | struct i2c_msg msg; | ||
166 | |||
167 | frequency = state->fe.dtv_property_cache.frequency; | ||
168 | |||
169 | word = (frequency + 71428) / 142857 + 399; | ||
170 | buf[0] = 0xfe; | ||
171 | buf[1] = 0xc2; | ||
172 | buf[2] = word >> 8; | ||
173 | buf[3] = word; | ||
174 | buf[4] = 0x80; | ||
175 | buf[5] = va1j5jf8007t_lookup_cb(frequency); | ||
176 | |||
177 | msg.addr = state->config->demod_address; | ||
178 | msg.flags = 0; | ||
179 | msg.len = sizeof(buf); | ||
180 | msg.buf = buf; | ||
181 | |||
182 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
183 | return -EREMOTEIO; | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int | ||
189 | va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock) | ||
190 | { | ||
191 | u8 addr; | ||
192 | u8 write_buf[2], read_buf[1]; | ||
193 | struct i2c_msg msgs[2]; | ||
194 | |||
195 | addr = state->config->demod_address; | ||
196 | |||
197 | write_buf[0] = 0xfe; | ||
198 | write_buf[1] = 0xc3; | ||
199 | |||
200 | msgs[0].addr = addr; | ||
201 | msgs[0].flags = 0; | ||
202 | msgs[0].len = sizeof(write_buf); | ||
203 | msgs[0].buf = write_buf; | ||
204 | |||
205 | msgs[1].addr = addr; | ||
206 | msgs[1].flags = I2C_M_RD; | ||
207 | msgs[1].len = sizeof(read_buf); | ||
208 | msgs[1].buf = read_buf; | ||
209 | |||
210 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
211 | return -EREMOTEIO; | ||
212 | |||
213 | *lock = read_buf[0] & 0x40; | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state) | ||
218 | { | ||
219 | u8 buf[2]; | ||
220 | struct i2c_msg msg; | ||
221 | |||
222 | buf[0] = 0x01; | ||
223 | buf[1] = 0x40; | ||
224 | |||
225 | msg.addr = state->config->demod_address; | ||
226 | msg.flags = 0; | ||
227 | msg.len = sizeof(buf); | ||
228 | msg.buf = buf; | ||
229 | |||
230 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
231 | return -EREMOTEIO; | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state, | ||
237 | int *lock, int *retry) | ||
238 | { | ||
239 | u8 addr; | ||
240 | u8 write_buf[1], read_buf[1]; | ||
241 | struct i2c_msg msgs[2]; | ||
242 | |||
243 | addr = state->config->demod_address; | ||
244 | |||
245 | write_buf[0] = 0x80; | ||
246 | |||
247 | msgs[0].addr = addr; | ||
248 | msgs[0].flags = 0; | ||
249 | msgs[0].len = sizeof(write_buf); | ||
250 | msgs[0].buf = write_buf; | ||
251 | |||
252 | msgs[1].addr = addr; | ||
253 | msgs[1].flags = I2C_M_RD; | ||
254 | msgs[1].len = sizeof(read_buf); | ||
255 | msgs[1].buf = read_buf; | ||
256 | |||
257 | if (i2c_transfer(state->adap, msgs, 2) != 2) | ||
258 | return -EREMOTEIO; | ||
259 | |||
260 | *lock = !(read_buf[0] & 0x10); | ||
261 | *retry = read_buf[0] & 0x80; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int | ||
266 | va1j5jf8007t_tune(struct dvb_frontend *fe, | ||
267 | bool re_tune, | ||
268 | unsigned int mode_flags, unsigned int *delay, | ||
269 | fe_status_t *status) | ||
270 | { | ||
271 | struct va1j5jf8007t_state *state; | ||
272 | int ret; | ||
273 | int lock = 0, retry = 0; | ||
274 | |||
275 | state = fe->demodulator_priv; | ||
276 | |||
277 | if (re_tune) | ||
278 | state->tune_state = VA1J5JF8007T_SET_FREQUENCY; | ||
279 | |||
280 | switch (state->tune_state) { | ||
281 | case VA1J5JF8007T_IDLE: | ||
282 | *delay = 3 * HZ; | ||
283 | *status = 0; | ||
284 | return 0; | ||
285 | |||
286 | case VA1J5JF8007T_SET_FREQUENCY: | ||
287 | ret = va1j5jf8007t_set_frequency(state); | ||
288 | if (ret < 0) | ||
289 | return ret; | ||
290 | |||
291 | state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY; | ||
292 | *delay = 0; | ||
293 | *status = 0; | ||
294 | return 0; | ||
295 | |||
296 | case VA1J5JF8007T_CHECK_FREQUENCY: | ||
297 | ret = va1j5jf8007t_check_frequency(state, &lock); | ||
298 | if (ret < 0) | ||
299 | return ret; | ||
300 | |||
301 | if (!lock) { | ||
302 | *delay = (HZ + 999) / 1000; | ||
303 | *status = 0; | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | state->tune_state = VA1J5JF8007T_SET_MODULATION; | ||
308 | *delay = 0; | ||
309 | *status = FE_HAS_SIGNAL; | ||
310 | return 0; | ||
311 | |||
312 | case VA1J5JF8007T_SET_MODULATION: | ||
313 | ret = va1j5jf8007t_set_modulation(state); | ||
314 | if (ret < 0) | ||
315 | return ret; | ||
316 | |||
317 | state->tune_state = VA1J5JF8007T_CHECK_MODULATION; | ||
318 | *delay = 0; | ||
319 | *status = FE_HAS_SIGNAL; | ||
320 | return 0; | ||
321 | |||
322 | case VA1J5JF8007T_CHECK_MODULATION: | ||
323 | ret = va1j5jf8007t_check_modulation(state, &lock, &retry); | ||
324 | if (ret < 0) | ||
325 | return ret; | ||
326 | |||
327 | if (!lock) { | ||
328 | if (!retry) { | ||
329 | state->tune_state = VA1J5JF8007T_ABORT; | ||
330 | *delay = 3 * HZ; | ||
331 | *status = FE_HAS_SIGNAL; | ||
332 | return 0; | ||
333 | } | ||
334 | *delay = (HZ + 999) / 1000; | ||
335 | *status = FE_HAS_SIGNAL; | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | state->tune_state = VA1J5JF8007T_TRACK; | ||
340 | /* fall through */ | ||
341 | |||
342 | case VA1J5JF8007T_TRACK: | ||
343 | *delay = 3 * HZ; | ||
344 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK; | ||
345 | return 0; | ||
346 | |||
347 | case VA1J5JF8007T_ABORT: | ||
348 | *delay = 3 * HZ; | ||
349 | *status = FE_HAS_SIGNAL; | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | BUG(); | ||
354 | } | ||
355 | |||
356 | static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state) | ||
357 | { | ||
358 | u8 buf[7]; | ||
359 | struct i2c_msg msg; | ||
360 | |||
361 | buf[0] = 0xfe; | ||
362 | buf[1] = 0xc2; | ||
363 | buf[2] = 0x01; | ||
364 | buf[3] = 0x8f; | ||
365 | buf[4] = 0xc1; | ||
366 | buf[5] = 0x80; | ||
367 | buf[6] = 0x80; | ||
368 | |||
369 | msg.addr = state->config->demod_address; | ||
370 | msg.flags = 0; | ||
371 | msg.len = sizeof(buf); | ||
372 | msg.buf = buf; | ||
373 | |||
374 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
375 | return -EREMOTEIO; | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep) | ||
381 | { | ||
382 | u8 buf[2]; | ||
383 | struct i2c_msg msg; | ||
384 | |||
385 | buf[0] = 0x03; | ||
386 | buf[1] = sleep ? 0x90 : 0x80; | ||
387 | |||
388 | msg.addr = state->config->demod_address; | ||
389 | msg.flags = 0; | ||
390 | msg.len = sizeof(buf); | ||
391 | msg.buf = buf; | ||
392 | |||
393 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
394 | return -EREMOTEIO; | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int va1j5jf8007t_sleep(struct dvb_frontend *fe) | ||
400 | { | ||
401 | struct va1j5jf8007t_state *state; | ||
402 | int ret; | ||
403 | |||
404 | state = fe->demodulator_priv; | ||
405 | |||
406 | ret = va1j5jf8007t_init_frequency(state); | ||
407 | if (ret < 0) | ||
408 | return ret; | ||
409 | |||
410 | return va1j5jf8007t_set_sleep(state, 1); | ||
411 | } | ||
412 | |||
413 | static int va1j5jf8007t_init(struct dvb_frontend *fe) | ||
414 | { | ||
415 | struct va1j5jf8007t_state *state; | ||
416 | |||
417 | state = fe->demodulator_priv; | ||
418 | state->tune_state = VA1J5JF8007T_IDLE; | ||
419 | |||
420 | return va1j5jf8007t_set_sleep(state, 0); | ||
421 | } | ||
422 | |||
423 | static void va1j5jf8007t_release(struct dvb_frontend *fe) | ||
424 | { | ||
425 | struct va1j5jf8007t_state *state; | ||
426 | state = fe->demodulator_priv; | ||
427 | kfree(state); | ||
428 | } | ||
429 | |||
430 | static struct dvb_frontend_ops va1j5jf8007t_ops = { | ||
431 | .delsys = { SYS_ISDBT }, | ||
432 | .info = { | ||
433 | .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T", | ||
434 | .frequency_min = 90000000, | ||
435 | .frequency_max = 770000000, | ||
436 | .frequency_stepsize = 142857, | ||
437 | .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | | ||
438 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
439 | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, | ||
440 | }, | ||
441 | |||
442 | .read_snr = va1j5jf8007t_read_snr, | ||
443 | .get_frontend_algo = va1j5jf8007t_get_frontend_algo, | ||
444 | .read_status = va1j5jf8007t_read_status, | ||
445 | .tune = va1j5jf8007t_tune, | ||
446 | .sleep = va1j5jf8007t_sleep, | ||
447 | .init = va1j5jf8007t_init, | ||
448 | .release = va1j5jf8007t_release, | ||
449 | }; | ||
450 | |||
451 | static const u8 va1j5jf8007t_20mhz_prepare_bufs[][2] = { | ||
452 | {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, | ||
453 | {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00}, | ||
454 | {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03}, | ||
455 | {0xef, 0x01} | ||
456 | }; | ||
457 | |||
458 | static const u8 va1j5jf8007t_25mhz_prepare_bufs[][2] = { | ||
459 | {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83}, | ||
460 | {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c}, | ||
461 | {0x77, 0x03}, {0xef, 0x01} | ||
462 | }; | ||
463 | |||
464 | int va1j5jf8007t_prepare(struct dvb_frontend *fe) | ||
465 | { | ||
466 | struct va1j5jf8007t_state *state; | ||
467 | const u8 (*bufs)[2]; | ||
468 | int size; | ||
469 | u8 buf[2]; | ||
470 | struct i2c_msg msg; | ||
471 | int i; | ||
472 | |||
473 | state = fe->demodulator_priv; | ||
474 | |||
475 | switch (state->config->frequency) { | ||
476 | case VA1J5JF8007T_20MHZ: | ||
477 | bufs = va1j5jf8007t_20mhz_prepare_bufs; | ||
478 | size = ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs); | ||
479 | break; | ||
480 | case VA1J5JF8007T_25MHZ: | ||
481 | bufs = va1j5jf8007t_25mhz_prepare_bufs; | ||
482 | size = ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs); | ||
483 | break; | ||
484 | default: | ||
485 | return -EINVAL; | ||
486 | } | ||
487 | |||
488 | msg.addr = state->config->demod_address; | ||
489 | msg.flags = 0; | ||
490 | msg.len = sizeof(buf); | ||
491 | msg.buf = buf; | ||
492 | |||
493 | for (i = 0; i < size; i++) { | ||
494 | memcpy(buf, bufs[i], sizeof(buf)); | ||
495 | if (i2c_transfer(state->adap, &msg, 1) != 1) | ||
496 | return -EREMOTEIO; | ||
497 | } | ||
498 | |||
499 | return va1j5jf8007t_init_frequency(state); | ||
500 | } | ||
501 | |||
502 | struct dvb_frontend * | ||
503 | va1j5jf8007t_attach(const struct va1j5jf8007t_config *config, | ||
504 | struct i2c_adapter *adap) | ||
505 | { | ||
506 | struct va1j5jf8007t_state *state; | ||
507 | struct dvb_frontend *fe; | ||
508 | u8 buf[2]; | ||
509 | struct i2c_msg msg; | ||
510 | |||
511 | state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL); | ||
512 | if (!state) | ||
513 | return NULL; | ||
514 | |||
515 | state->config = config; | ||
516 | state->adap = adap; | ||
517 | |||
518 | fe = &state->fe; | ||
519 | memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops)); | ||
520 | fe->demodulator_priv = state; | ||
521 | |||
522 | buf[0] = 0x01; | ||
523 | buf[1] = 0x80; | ||
524 | |||
525 | msg.addr = state->config->demod_address; | ||
526 | msg.flags = 0; | ||
527 | msg.len = sizeof(buf); | ||
528 | msg.buf = buf; | ||
529 | |||
530 | if (i2c_transfer(state->adap, &msg, 1) != 1) { | ||
531 | kfree(state); | ||
532 | return NULL; | ||
533 | } | ||
534 | |||
535 | return fe; | ||
536 | } | ||
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/dvb/pt1/va1j5jf8007t.h deleted file mode 100644 index 2903be519ef5..000000000000 --- a/drivers/media/dvb/pt1/va1j5jf8007t.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * ISDB-T driver for VA1J5JF8007/VA1J5JF8011 | ||
3 | * | ||
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | ||
5 | * | ||
6 | * based on pt1dvr - http://pt1dvr.sourceforge.jp/ | ||
7 | * by Tomoaki Ishikawa <tomy@users.sourceforge.jp> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef VA1J5JF8007T_H | ||
25 | #define VA1J5JF8007T_H | ||
26 | |||
27 | enum va1j5jf8007t_frequency { | ||
28 | VA1J5JF8007T_20MHZ, | ||
29 | VA1J5JF8007T_25MHZ, | ||
30 | }; | ||
31 | |||
32 | struct va1j5jf8007t_config { | ||
33 | u8 demod_address; | ||
34 | enum va1j5jf8007t_frequency frequency; | ||
35 | }; | ||
36 | |||
37 | struct i2c_adapter; | ||
38 | |||
39 | struct dvb_frontend * | ||
40 | va1j5jf8007t_attach(const struct va1j5jf8007t_config *config, | ||
41 | struct i2c_adapter *adap); | ||
42 | |||
43 | /* must be called after va1j5jf8007s_attach */ | ||
44 | int va1j5jf8007t_prepare(struct dvb_frontend *fe); | ||
45 | |||
46 | #endif | ||
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig deleted file mode 100644 index 9d83ced69dd6..000000000000 --- a/drivers/media/dvb/ttpci/Kconfig +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | config TTPCI_EEPROM | ||
2 | tristate | ||
3 | depends on I2C | ||
4 | default n | ||
5 | |||
6 | config DVB_AV7110 | ||
7 | tristate "AV7110 cards" | ||
8 | depends on DVB_CORE && PCI && I2C | ||
9 | select TTPCI_EEPROM | ||
10 | select VIDEO_SAA7146_VV | ||
11 | depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV | ||
12 | select DVB_VES1820 if !DVB_FE_CUSTOMISE | ||
13 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE | ||
14 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
15 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE | ||
16 | select DVB_SP8870 if !DVB_FE_CUSTOMISE | ||
17 | select DVB_STV0297 if !DVB_FE_CUSTOMISE | ||
18 | select DVB_L64781 if !DVB_FE_CUSTOMISE | ||
19 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
20 | help | ||
21 | Support for SAA7146 and AV7110 based DVB cards as produced | ||
22 | by Fujitsu-Siemens, Technotrend, Hauppauge and others. | ||
23 | |||
24 | This driver only supports the fullfeatured cards with | ||
25 | onboard MPEG2 decoder. | ||
26 | |||
27 | This driver needs an external firmware. Please use the script | ||
28 | "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to | ||
29 | download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
30 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
31 | |||
32 | Alternatively, you can download the file and use the kernel's | ||
33 | EXTRA_FIRMWARE configuration option to build it into your | ||
34 | kernel image by adding the filename to the EXTRA_FIRMWARE | ||
35 | configuration option string. | ||
36 | |||
37 | Say Y if you own such a card and want to use it. | ||
38 | |||
39 | config DVB_AV7110_OSD | ||
40 | bool "AV7110 OSD support" | ||
41 | depends on DVB_AV7110 | ||
42 | default y if DVB_AV7110=y || DVB_AV7110=m | ||
43 | help | ||
44 | The AV7110 firmware provides some code to generate an OnScreenDisplay | ||
45 | on the video output. This is kind of nonstandard and not guaranteed to | ||
46 | be maintained. | ||
47 | |||
48 | Anyway, some popular DVB software like VDR uses this OSD to render | ||
49 | its menus, so say Y if you want to use this software. | ||
50 | |||
51 | All other people say N. | ||
52 | |||
53 | config DVB_BUDGET_CORE | ||
54 | tristate "SAA7146 DVB cards (aka Budget, Nova-PCI)" | ||
55 | depends on DVB_CORE && PCI && I2C | ||
56 | select VIDEO_SAA7146 | ||
57 | select TTPCI_EEPROM | ||
58 | help | ||
59 | Support for simple SAA7146 based DVB cards | ||
60 | (so called Budget- or Nova-PCI cards) without onboard | ||
61 | MPEG2 decoder. | ||
62 | |||
63 | config DVB_BUDGET | ||
64 | tristate "Budget cards" | ||
65 | depends on DVB_BUDGET_CORE && I2C | ||
66 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
67 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE | ||
68 | select DVB_VES1820 if !DVB_FE_CUSTOMISE | ||
69 | select DVB_L64781 if !DVB_FE_CUSTOMISE | ||
70 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE | ||
71 | select DVB_S5H1420 if !DVB_FE_CUSTOMISE | ||
72 | select DVB_TDA10086 if !DVB_FE_CUSTOMISE | ||
73 | select DVB_TDA826X if !DVB_FE_CUSTOMISE | ||
74 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
75 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | ||
76 | select DVB_ISL6423 if !DVB_FE_CUSTOMISE | ||
77 | select DVB_STV090x if !DVB_FE_CUSTOMISE | ||
78 | select DVB_STV6110x if !DVB_FE_CUSTOMISE | ||
79 | help | ||
80 | Support for simple SAA7146 based DVB cards (so called Budget- | ||
81 | or Nova-PCI cards) without onboard MPEG2 decoder, and without | ||
82 | analog inputs or an onboard Common Interface connector. | ||
83 | |||
84 | Say Y if you own such a card and want to use it. | ||
85 | |||
86 | To compile this driver as a module, choose M here: the | ||
87 | module will be called budget. | ||
88 | |||
89 | config DVB_BUDGET_CI | ||
90 | tristate "Budget cards with onboard CI connector" | ||
91 | depends on DVB_BUDGET_CORE && I2C | ||
92 | select DVB_STV0297 if !DVB_FE_CUSTOMISE | ||
93 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
94 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | ||
95 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||
96 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
97 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
98 | select DVB_STV0288 if !DVB_FE_CUSTOMISE | ||
99 | select DVB_STB6000 if !DVB_FE_CUSTOMISE | ||
100 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
101 | select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE | ||
102 | depends on RC_CORE | ||
103 | help | ||
104 | Support for simple SAA7146 based DVB cards | ||
105 | (so called Budget- or Nova-PCI cards) without onboard | ||
106 | MPEG2 decoder, but with onboard Common Interface connector. | ||
107 | |||
108 | Note: The Common Interface is not yet supported by this driver | ||
109 | due to lack of information from the vendor. | ||
110 | |||
111 | Say Y if you own such a card and want to use it. | ||
112 | |||
113 | To compile this driver as a module, choose M here: the | ||
114 | module will be called budget-ci. | ||
115 | |||
116 | config DVB_BUDGET_AV | ||
117 | tristate "Budget cards with analog video inputs" | ||
118 | depends on DVB_BUDGET_CORE && I2C | ||
119 | select VIDEO_SAA7146_VV | ||
120 | depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV | ||
121 | select DVB_PLL if !DVB_FE_CUSTOMISE | ||
122 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
123 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | ||
124 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | ||
125 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
126 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||
127 | select DVB_TDA8261 if !DVB_FE_CUSTOMISE | ||
128 | select DVB_TUA6100 if !DVB_FE_CUSTOMISE | ||
129 | help | ||
130 | Support for simple SAA7146 based DVB cards | ||
131 | (so called Budget- or Nova-PCI cards) without onboard | ||
132 | MPEG2 decoder, but with one or more analog video inputs. | ||
133 | |||
134 | Say Y if you own such a card and want to use it. | ||
135 | |||
136 | To compile this driver as a module, choose M here: the | ||
137 | module will be called budget-av. | ||
138 | |||
139 | config DVB_BUDGET_PATCH | ||
140 | tristate "AV7110 cards with Budget Patch" | ||
141 | depends on DVB_BUDGET_CORE && I2C | ||
142 | depends on DVB_AV7110 | ||
143 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
144 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE | ||
145 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE | ||
146 | help | ||
147 | Support for Budget Patch (full TS) modification on | ||
148 | SAA7146+AV7110 based cards (DVB-S cards). This | ||
149 | driver doesn't use onboard MPEG2 decoder. The | ||
150 | card is driven in Budget-only mode. Card is | ||
151 | required to have loaded firmware to tune properly. | ||
152 | Firmware can be loaded by insertion and removal of | ||
153 | standard AV7110 driver prior to loading this | ||
154 | driver. | ||
155 | |||
156 | Say Y if you own such a card and want to use it. | ||
157 | |||
158 | To compile this driver as a module, choose M here: the | ||
159 | module will be called budget-patch. | ||
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile deleted file mode 100644 index 22a235f3cc48..000000000000 --- a/drivers/media/dvb/ttpci/Makefile +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the kernel SAA7146 FULL TS DVB device driver | ||
3 | # and the AV7110 DVB device driver | ||
4 | # | ||
5 | |||
6 | dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o | ||
7 | |||
8 | ifdef CONFIG_INPUT_EVDEV | ||
9 | dvb-ttpci-objs += av7110_ir.o | ||
10 | endif | ||
11 | |||
12 | obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o | ||
13 | obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o | ||
14 | obj-$(CONFIG_DVB_BUDGET) += budget.o | ||
15 | obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o | ||
16 | obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o | ||
17 | obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o | ||
18 | obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o | ||
19 | |||
20 | ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ | ||
21 | ccflags-y += -Idrivers/media/common/tuners | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c deleted file mode 100644 index 4bd8bd56befc..000000000000 --- a/drivers/media/dvb/ttpci/av7110.c +++ /dev/null | |||
@@ -1,2939 +0,0 @@ | |||
1 | /* | ||
2 | * driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB) | ||
3 | * av7110.c: initialization and demux stuff | ||
4 | * | ||
5 | * Copyright (C) 1999-2002 Ralph Metzler | ||
6 | * & Marcus Metzler for convergence integrated media GmbH | ||
7 | * | ||
8 | * originally based on code by: | ||
9 | * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
26 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
27 | * | ||
28 | * | ||
29 | * the project's page is at http://www.linuxtv.org/ | ||
30 | */ | ||
31 | |||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/kmod.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/fs.h> | ||
37 | #include <linux/timer.h> | ||
38 | #include <linux/poll.h> | ||
39 | |||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/sched.h> | ||
42 | #include <linux/types.h> | ||
43 | #include <linux/fcntl.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/string.h> | ||
46 | #include <linux/pci.h> | ||
47 | #include <linux/vmalloc.h> | ||
48 | #include <linux/firmware.h> | ||
49 | #include <linux/crc32.h> | ||
50 | #include <linux/i2c.h> | ||
51 | #include <linux/kthread.h> | ||
52 | #include <linux/slab.h> | ||
53 | #include <asm/unaligned.h> | ||
54 | #include <asm/byteorder.h> | ||
55 | |||
56 | |||
57 | #include <linux/dvb/frontend.h> | ||
58 | |||
59 | #include "dvb_frontend.h" | ||
60 | |||
61 | #include "ttpci-eeprom.h" | ||
62 | #include "av7110.h" | ||
63 | #include "av7110_hw.h" | ||
64 | #include "av7110_av.h" | ||
65 | #include "av7110_ca.h" | ||
66 | #include "av7110_ipack.h" | ||
67 | |||
68 | #include "bsbe1.h" | ||
69 | #include "lnbp21.h" | ||
70 | #include "bsru6.h" | ||
71 | |||
72 | #define TS_WIDTH 376 | ||
73 | #define TS_HEIGHT 512 | ||
74 | #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) | ||
75 | #define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE) | ||
76 | |||
77 | |||
78 | int av7110_debug; | ||
79 | |||
80 | static int vidmode = CVBS_RGB_OUT; | ||
81 | static int pids_off; | ||
82 | static int adac = DVB_ADAC_TI; | ||
83 | static int hw_sections; | ||
84 | static int rgb_on; | ||
85 | static int volume = 255; | ||
86 | static int budgetpatch; | ||
87 | static int wss_cfg_4_3 = 0x4008; | ||
88 | static int wss_cfg_16_9 = 0x0007; | ||
89 | static int tv_standard; | ||
90 | static int full_ts; | ||
91 | |||
92 | module_param_named(debug, av7110_debug, int, 0644); | ||
93 | MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); | ||
94 | module_param(vidmode, int, 0444); | ||
95 | MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC"); | ||
96 | module_param(pids_off, int, 0444); | ||
97 | MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed"); | ||
98 | module_param(adac, int, 0444); | ||
99 | MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)"); | ||
100 | module_param(hw_sections, int, 0444); | ||
101 | MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware"); | ||
102 | module_param(rgb_on, int, 0444); | ||
103 | MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control" | ||
104 | " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB"); | ||
105 | module_param(volume, int, 0444); | ||
106 | MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); | ||
107 | module_param(budgetpatch, int, 0444); | ||
108 | MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); | ||
109 | module_param(full_ts, int, 0444); | ||
110 | MODULE_PARM_DESC(full_ts, "enable code for full-ts hardware modification: 0 disable (default), 1 enable"); | ||
111 | module_param(wss_cfg_4_3, int, 0444); | ||
112 | MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data"); | ||
113 | module_param(wss_cfg_16_9, int, 0444); | ||
114 | MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data"); | ||
115 | module_param(tv_standard, int, 0444); | ||
116 | MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC"); | ||
117 | |||
118 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
119 | |||
120 | static void restart_feeds(struct av7110 *av7110); | ||
121 | static int budget_start_feed(struct dvb_demux_feed *feed); | ||
122 | static int budget_stop_feed(struct dvb_demux_feed *feed); | ||
123 | |||
124 | static int av7110_num; | ||
125 | |||
126 | #define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \ | ||
127 | {\ | ||
128 | if (fe_func != NULL) { \ | ||
129 | av7110_copy = fe_func; \ | ||
130 | fe_func = av7110_func; \ | ||
131 | } \ | ||
132 | } | ||
133 | |||
134 | |||
135 | static void init_av7110_av(struct av7110 *av7110) | ||
136 | { | ||
137 | int ret; | ||
138 | struct saa7146_dev *dev = av7110->dev; | ||
139 | |||
140 | /* set internal volume control to maximum */ | ||
141 | av7110->adac_type = DVB_ADAC_TI; | ||
142 | ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); | ||
143 | if (ret < 0) | ||
144 | printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); | ||
145 | |||
146 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, | ||
147 | 1, (u16) av7110->display_ar); | ||
148 | if (ret < 0) | ||
149 | printk("dvb-ttpci: unable to set aspect ratio\n"); | ||
150 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, | ||
151 | 1, av7110->display_panscan); | ||
152 | if (ret < 0) | ||
153 | printk("dvb-ttpci: unable to set pan scan\n"); | ||
154 | |||
155 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3); | ||
156 | if (ret < 0) | ||
157 | printk("dvb-ttpci: unable to configure 4:3 wss\n"); | ||
158 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9); | ||
159 | if (ret < 0) | ||
160 | printk("dvb-ttpci: unable to configure 16:9 wss\n"); | ||
161 | |||
162 | ret = av7710_set_video_mode(av7110, vidmode); | ||
163 | if (ret < 0) | ||
164 | printk("dvb-ttpci:cannot set video mode:%d\n",ret); | ||
165 | |||
166 | /* handle different card types */ | ||
167 | /* remaining inits according to card and frontend type */ | ||
168 | av7110->analog_tuner_flags = 0; | ||
169 | av7110->current_input = 0; | ||
170 | if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) | ||
171 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on | ||
172 | if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { | ||
173 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", | ||
174 | av7110->dvb_adapter.num); | ||
175 | av7110->adac_type = DVB_ADAC_CRYSTAL; | ||
176 | i2c_writereg(av7110, 0x20, 0x01, 0xd2); | ||
177 | i2c_writereg(av7110, 0x20, 0x02, 0x49); | ||
178 | i2c_writereg(av7110, 0x20, 0x03, 0x00); | ||
179 | i2c_writereg(av7110, 0x20, 0x04, 0x00); | ||
180 | |||
181 | /** | ||
182 | * some special handling for the Siemens DVB-C cards... | ||
183 | */ | ||
184 | } else if (0 == av7110_init_analog_module(av7110)) { | ||
185 | /* done. */ | ||
186 | } | ||
187 | else if (dev->pci->subsystem_vendor == 0x110a) { | ||
188 | printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n", | ||
189 | av7110->dvb_adapter.num); | ||
190 | av7110->adac_type = DVB_ADAC_NONE; | ||
191 | } | ||
192 | else { | ||
193 | av7110->adac_type = adac; | ||
194 | printk("dvb-ttpci: adac type set to %d @ card %d\n", | ||
195 | av7110->adac_type, av7110->dvb_adapter.num); | ||
196 | } | ||
197 | |||
198 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) { | ||
199 | // switch DVB SCART on | ||
200 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); | ||
201 | if (ret < 0) | ||
202 | printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret); | ||
203 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); | ||
204 | if (ret < 0) | ||
205 | printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret); | ||
206 | if (rgb_on && | ||
207 | ((av7110->dev->pci->subsystem_vendor == 0x110a) || | ||
208 | (av7110->dev->pci->subsystem_vendor == 0x13c2)) && | ||
209 | (av7110->dev->pci->subsystem_device == 0x0000)) { | ||
210 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 | ||
211 | //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8 | ||
212 | } | ||
213 | } | ||
214 | |||
215 | if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e) | ||
216 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on | ||
217 | |||
218 | ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); | ||
219 | if (ret < 0) | ||
220 | printk("dvb-ttpci:cannot set volume :%d\n",ret); | ||
221 | } | ||
222 | |||
223 | static void recover_arm(struct av7110 *av7110) | ||
224 | { | ||
225 | dprintk(4, "%p\n",av7110); | ||
226 | |||
227 | av7110_bootarm(av7110); | ||
228 | msleep(100); | ||
229 | |||
230 | init_av7110_av(av7110); | ||
231 | |||
232 | /* card-specific recovery */ | ||
233 | if (av7110->recover) | ||
234 | av7110->recover(av7110); | ||
235 | |||
236 | restart_feeds(av7110); | ||
237 | |||
238 | #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) | ||
239 | av7110_check_ir_config(av7110, true); | ||
240 | #endif | ||
241 | } | ||
242 | |||
243 | static void av7110_arm_sync(struct av7110 *av7110) | ||
244 | { | ||
245 | if (av7110->arm_thread) | ||
246 | kthread_stop(av7110->arm_thread); | ||
247 | |||
248 | av7110->arm_thread = NULL; | ||
249 | } | ||
250 | |||
251 | static int arm_thread(void *data) | ||
252 | { | ||
253 | struct av7110 *av7110 = data; | ||
254 | u16 newloops = 0; | ||
255 | int timeout; | ||
256 | |||
257 | dprintk(4, "%p\n",av7110); | ||
258 | |||
259 | for (;;) { | ||
260 | timeout = wait_event_interruptible_timeout(av7110->arm_wait, | ||
261 | kthread_should_stop(), 5 * HZ); | ||
262 | |||
263 | if (-ERESTARTSYS == timeout || kthread_should_stop()) { | ||
264 | /* got signal or told to quit*/ | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | if (!av7110->arm_ready) | ||
269 | continue; | ||
270 | |||
271 | #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) | ||
272 | av7110_check_ir_config(av7110, false); | ||
273 | #endif | ||
274 | |||
275 | if (mutex_lock_interruptible(&av7110->dcomlock)) | ||
276 | break; | ||
277 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); | ||
278 | mutex_unlock(&av7110->dcomlock); | ||
279 | |||
280 | if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { | ||
281 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", | ||
282 | av7110->dvb_adapter.num); | ||
283 | |||
284 | recover_arm(av7110); | ||
285 | |||
286 | if (mutex_lock_interruptible(&av7110->dcomlock)) | ||
287 | break; | ||
288 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; | ||
289 | mutex_unlock(&av7110->dcomlock); | ||
290 | } | ||
291 | av7110->arm_loops = newloops; | ||
292 | av7110->arm_errors = 0; | ||
293 | } | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | |||
299 | /**************************************************************************** | ||
300 | * IRQ handling | ||
301 | ****************************************************************************/ | ||
302 | |||
303 | static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len, | ||
304 | u8 *buffer2, size_t buffer2_len, | ||
305 | struct dvb_demux_filter *dvbdmxfilter, | ||
306 | enum dmx_success success, | ||
307 | struct av7110 *av7110) | ||
308 | { | ||
309 | if (!dvbdmxfilter->feed->demux->dmx.frontend) | ||
310 | return 0; | ||
311 | if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE) | ||
312 | return 0; | ||
313 | |||
314 | switch (dvbdmxfilter->type) { | ||
315 | case DMX_TYPE_SEC: | ||
316 | if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len) | ||
317 | return 0; | ||
318 | if (dvbdmxfilter->doneq) { | ||
319 | struct dmx_section_filter *filter = &dvbdmxfilter->filter; | ||
320 | int i; | ||
321 | u8 xor, neq = 0; | ||
322 | |||
323 | for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) { | ||
324 | xor = filter->filter_value[i] ^ buffer1[i]; | ||
325 | neq |= dvbdmxfilter->maskandnotmode[i] & xor; | ||
326 | } | ||
327 | if (!neq) | ||
328 | return 0; | ||
329 | } | ||
330 | return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, | ||
331 | buffer2, buffer2_len, | ||
332 | &dvbdmxfilter->filter, | ||
333 | DMX_OK); | ||
334 | case DMX_TYPE_TS: | ||
335 | if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) | ||
336 | return 0; | ||
337 | if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) | ||
338 | return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, | ||
339 | buffer2, buffer2_len, | ||
340 | &dvbdmxfilter->feed->feed.ts, | ||
341 | DMX_OK); | ||
342 | else | ||
343 | av7110_p2t_write(buffer1, buffer1_len, | ||
344 | dvbdmxfilter->feed->pid, | ||
345 | &av7110->p2t_filter[dvbdmxfilter->index]); | ||
346 | default: | ||
347 | return 0; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | |||
352 | //#define DEBUG_TIMING | ||
353 | static inline void print_time(char *s) | ||
354 | { | ||
355 | #ifdef DEBUG_TIMING | ||
356 | struct timeval tv; | ||
357 | do_gettimeofday(&tv); | ||
358 | printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec); | ||
359 | #endif | ||
360 | } | ||
361 | |||
362 | #define DEBI_READ 0 | ||
363 | #define DEBI_WRITE 1 | ||
364 | static inline void start_debi_dma(struct av7110 *av7110, int dir, | ||
365 | unsigned long addr, unsigned int len) | ||
366 | { | ||
367 | dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len); | ||
368 | if (saa7146_wait_for_debi_done(av7110->dev, 0)) { | ||
369 | printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__); | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */ | ||
374 | SAA7146_IER_ENABLE(av7110->dev, MASK_19); | ||
375 | if (len < 5) | ||
376 | len = 5; /* we want a real DEBI DMA */ | ||
377 | if (dir == DEBI_WRITE) | ||
378 | iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3); | ||
379 | else | ||
380 | irdebi(av7110, DEBISWAB, addr, 0, len); | ||
381 | } | ||
382 | |||
383 | static void debiirq(unsigned long cookie) | ||
384 | { | ||
385 | struct av7110 *av7110 = (struct av7110 *)cookie; | ||
386 | int type = av7110->debitype; | ||
387 | int handle = (type >> 8) & 0x1f; | ||
388 | unsigned int xfer = 0; | ||
389 | |||
390 | print_time("debi"); | ||
391 | dprintk(4, "type 0x%04x\n", type); | ||
392 | |||
393 | if (type == -1) { | ||
394 | printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", | ||
395 | jiffies, saa7146_read(av7110->dev, PSR), | ||
396 | saa7146_read(av7110->dev, SSR)); | ||
397 | goto debi_done; | ||
398 | } | ||
399 | av7110->debitype = -1; | ||
400 | |||
401 | switch (type & 0xff) { | ||
402 | |||
403 | case DATA_TS_RECORD: | ||
404 | dvb_dmx_swfilter_packets(&av7110->demux, | ||
405 | (const u8 *) av7110->debi_virt, | ||
406 | av7110->debilen / 188); | ||
407 | xfer = RX_BUFF; | ||
408 | break; | ||
409 | |||
410 | case DATA_PES_RECORD: | ||
411 | if (av7110->demux.recording) | ||
412 | av7110_record_cb(&av7110->p2t[handle], | ||
413 | (u8 *) av7110->debi_virt, | ||
414 | av7110->debilen); | ||
415 | xfer = RX_BUFF; | ||
416 | break; | ||
417 | |||
418 | case DATA_IPMPE: | ||
419 | case DATA_FSECTION: | ||
420 | case DATA_PIPING: | ||
421 | if (av7110->handle2filter[handle]) | ||
422 | DvbDmxFilterCallback((u8 *)av7110->debi_virt, | ||
423 | av7110->debilen, NULL, 0, | ||
424 | av7110->handle2filter[handle], | ||
425 | DMX_OK, av7110); | ||
426 | xfer = RX_BUFF; | ||
427 | break; | ||
428 | |||
429 | case DATA_CI_GET: | ||
430 | { | ||
431 | u8 *data = av7110->debi_virt; | ||
432 | |||
433 | if ((data[0] < 2) && data[2] == 0xff) { | ||
434 | int flags = 0; | ||
435 | if (data[5] > 0) | ||
436 | flags |= CA_CI_MODULE_PRESENT; | ||
437 | if (data[5] > 5) | ||
438 | flags |= CA_CI_MODULE_READY; | ||
439 | av7110->ci_slot[data[0]].flags = flags; | ||
440 | } else | ||
441 | ci_get_data(&av7110->ci_rbuffer, | ||
442 | av7110->debi_virt, | ||
443 | av7110->debilen); | ||
444 | xfer = RX_BUFF; | ||
445 | break; | ||
446 | } | ||
447 | |||
448 | case DATA_COMMON_INTERFACE: | ||
449 | CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen); | ||
450 | #if 0 | ||
451 | { | ||
452 | int i; | ||
453 | |||
454 | printk("av7110%d: ", av7110->num); | ||
455 | printk("%02x ", *(u8 *)av7110->debi_virt); | ||
456 | printk("%02x ", *(1+(u8 *)av7110->debi_virt)); | ||
457 | for (i = 2; i < av7110->debilen; i++) | ||
458 | printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt))); | ||
459 | for (i = 2; i < av7110->debilen; i++) | ||
460 | printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt))); | ||
461 | |||
462 | printk("\n"); | ||
463 | } | ||
464 | #endif | ||
465 | xfer = RX_BUFF; | ||
466 | break; | ||
467 | |||
468 | case DATA_DEBUG_MESSAGE: | ||
469 | ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0; | ||
470 | printk("%s\n", (s8 *) av7110->debi_virt); | ||
471 | xfer = RX_BUFF; | ||
472 | break; | ||
473 | |||
474 | case DATA_CI_PUT: | ||
475 | dprintk(4, "debi DATA_CI_PUT\n"); | ||
476 | case DATA_MPEG_PLAY: | ||
477 | dprintk(4, "debi DATA_MPEG_PLAY\n"); | ||
478 | case DATA_BMP_LOAD: | ||
479 | dprintk(4, "debi DATA_BMP_LOAD\n"); | ||
480 | xfer = TX_BUFF; | ||
481 | break; | ||
482 | default: | ||
483 | break; | ||
484 | } | ||
485 | debi_done: | ||
486 | spin_lock(&av7110->debilock); | ||
487 | if (xfer) | ||
488 | iwdebi(av7110, DEBINOSWAP, xfer, 0, 2); | ||
489 | ARM_ClearMailBox(av7110); | ||
490 | spin_unlock(&av7110->debilock); | ||
491 | } | ||
492 | |||
493 | /* irq from av7110 firmware writing the mailbox register in the DPRAM */ | ||
494 | static void gpioirq(unsigned long cookie) | ||
495 | { | ||
496 | struct av7110 *av7110 = (struct av7110 *)cookie; | ||
497 | u32 rxbuf, txbuf; | ||
498 | int len; | ||
499 | |||
500 | if (av7110->debitype != -1) | ||
501 | /* we shouldn't get any irq while a debi xfer is running */ | ||
502 | printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", | ||
503 | jiffies, saa7146_read(av7110->dev, PSR), | ||
504 | saa7146_read(av7110->dev, SSR)); | ||
505 | |||
506 | if (saa7146_wait_for_debi_done(av7110->dev, 0)) { | ||
507 | printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__); | ||
508 | BUG(); /* maybe we should try resetting the debi? */ | ||
509 | } | ||
510 | |||
511 | spin_lock(&av7110->debilock); | ||
512 | ARM_ClearIrq(av7110); | ||
513 | |||
514 | /* see what the av7110 wants */ | ||
515 | av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2); | ||
516 | av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); | ||
517 | rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | ||
518 | txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); | ||
519 | len = (av7110->debilen + 3) & ~3; | ||
520 | |||
521 | print_time("gpio"); | ||
522 | dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen); | ||
523 | |||
524 | switch (av7110->debitype & 0xff) { | ||
525 | |||
526 | case DATA_TS_PLAY: | ||
527 | case DATA_PES_PLAY: | ||
528 | break; | ||
529 | |||
530 | case DATA_MPEG_VIDEO_EVENT: | ||
531 | { | ||
532 | u32 h_ar; | ||
533 | struct video_event event; | ||
534 | |||
535 | av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2); | ||
536 | h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2); | ||
537 | |||
538 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); | ||
539 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | ||
540 | |||
541 | av7110->video_size.h = h_ar & 0xfff; | ||
542 | |||
543 | event.type = VIDEO_EVENT_SIZE_CHANGED; | ||
544 | event.u.size.w = av7110->video_size.w; | ||
545 | event.u.size.h = av7110->video_size.h; | ||
546 | switch ((h_ar >> 12) & 0xf) | ||
547 | { | ||
548 | case 3: | ||
549 | av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9; | ||
550 | event.u.size.aspect_ratio = VIDEO_FORMAT_16_9; | ||
551 | av7110->videostate.video_format = VIDEO_FORMAT_16_9; | ||
552 | break; | ||
553 | case 4: | ||
554 | av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1; | ||
555 | event.u.size.aspect_ratio = VIDEO_FORMAT_221_1; | ||
556 | av7110->videostate.video_format = VIDEO_FORMAT_221_1; | ||
557 | break; | ||
558 | default: | ||
559 | av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3; | ||
560 | event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; | ||
561 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; | ||
562 | } | ||
563 | |||
564 | dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", | ||
565 | av7110->video_size.w, av7110->video_size.h, | ||
566 | av7110->video_size.aspect_ratio); | ||
567 | |||
568 | dvb_video_add_event(av7110, &event); | ||
569 | break; | ||
570 | } | ||
571 | |||
572 | case DATA_CI_PUT: | ||
573 | { | ||
574 | int avail; | ||
575 | struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer; | ||
576 | |||
577 | avail = dvb_ringbuffer_avail(cibuf); | ||
578 | if (avail <= 2) { | ||
579 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); | ||
580 | iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); | ||
581 | iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); | ||
582 | break; | ||
583 | } | ||
584 | len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8; | ||
585 | len |= DVB_RINGBUFFER_PEEK(cibuf, 1); | ||
586 | if (avail < len + 2) { | ||
587 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); | ||
588 | iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); | ||
589 | iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); | ||
590 | break; | ||
591 | } | ||
592 | DVB_RINGBUFFER_SKIP(cibuf, 2); | ||
593 | |||
594 | dvb_ringbuffer_read(cibuf, av7110->debi_virt, len); | ||
595 | |||
596 | iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); | ||
597 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); | ||
598 | dprintk(8, "DMA: CI\n"); | ||
599 | start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len); | ||
600 | spin_unlock(&av7110->debilock); | ||
601 | wake_up(&cibuf->queue); | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | case DATA_MPEG_PLAY: | ||
606 | if (!av7110->playing) { | ||
607 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); | ||
608 | iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); | ||
609 | iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); | ||
610 | break; | ||
611 | } | ||
612 | len = 0; | ||
613 | if (av7110->debitype & 0x100) { | ||
614 | spin_lock(&av7110->aout.lock); | ||
615 | len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048); | ||
616 | spin_unlock(&av7110->aout.lock); | ||
617 | } | ||
618 | if (len <= 0 && (av7110->debitype & 0x200) | ||
619 | &&av7110->videostate.play_state != VIDEO_FREEZED) { | ||
620 | spin_lock(&av7110->avout.lock); | ||
621 | len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048); | ||
622 | spin_unlock(&av7110->avout.lock); | ||
623 | } | ||
624 | if (len <= 0) { | ||
625 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); | ||
626 | iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); | ||
627 | iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); | ||
628 | break; | ||
629 | } | ||
630 | dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len); | ||
631 | iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); | ||
632 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); | ||
633 | dprintk(8, "DMA: MPEG_PLAY\n"); | ||
634 | start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len); | ||
635 | spin_unlock(&av7110->debilock); | ||
636 | return; | ||
637 | |||
638 | case DATA_BMP_LOAD: | ||
639 | len = av7110->debilen; | ||
640 | dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len); | ||
641 | if (!len) { | ||
642 | av7110->bmp_state = BMP_LOADED; | ||
643 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); | ||
644 | iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); | ||
645 | iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); | ||
646 | wake_up(&av7110->bmpq); | ||
647 | dprintk(8, "gpio DATA_BMP_LOAD done\n"); | ||
648 | break; | ||
649 | } | ||
650 | if (len > av7110->bmplen) | ||
651 | len = av7110->bmplen; | ||
652 | if (len > 2 * 1024) | ||
653 | len = 2 * 1024; | ||
654 | iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); | ||
655 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); | ||
656 | memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len); | ||
657 | av7110->bmpp += len; | ||
658 | av7110->bmplen -= len; | ||
659 | dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len); | ||
660 | start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len); | ||
661 | spin_unlock(&av7110->debilock); | ||
662 | return; | ||
663 | |||
664 | case DATA_CI_GET: | ||
665 | case DATA_COMMON_INTERFACE: | ||
666 | case DATA_FSECTION: | ||
667 | case DATA_IPMPE: | ||
668 | case DATA_PIPING: | ||
669 | if (!len || len > 4 * 1024) { | ||
670 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | ||
671 | break; | ||
672 | } | ||
673 | /* fall through */ | ||
674 | |||
675 | case DATA_TS_RECORD: | ||
676 | case DATA_PES_RECORD: | ||
677 | dprintk(8, "DMA: TS_REC etc.\n"); | ||
678 | start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len); | ||
679 | spin_unlock(&av7110->debilock); | ||
680 | return; | ||
681 | |||
682 | case DATA_DEBUG_MESSAGE: | ||
683 | if (!len || len > 0xff) { | ||
684 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | ||
685 | break; | ||
686 | } | ||
687 | start_debi_dma(av7110, DEBI_READ, Reserved, len); | ||
688 | spin_unlock(&av7110->debilock); | ||
689 | return; | ||
690 | |||
691 | case DATA_IRCOMMAND: | ||
692 | if (av7110->ir.ir_handler) | ||
693 | av7110->ir.ir_handler(av7110, | ||
694 | swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); | ||
695 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | ||
696 | break; | ||
697 | |||
698 | default: | ||
699 | printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n", | ||
700 | av7110->debitype, av7110->debilen); | ||
701 | break; | ||
702 | } | ||
703 | av7110->debitype = -1; | ||
704 | ARM_ClearMailBox(av7110); | ||
705 | spin_unlock(&av7110->debilock); | ||
706 | } | ||
707 | |||
708 | |||
709 | #ifdef CONFIG_DVB_AV7110_OSD | ||
710 | static int dvb_osd_ioctl(struct file *file, | ||
711 | unsigned int cmd, void *parg) | ||
712 | { | ||
713 | struct dvb_device *dvbdev = file->private_data; | ||
714 | struct av7110 *av7110 = dvbdev->priv; | ||
715 | |||
716 | dprintk(4, "%p\n", av7110); | ||
717 | |||
718 | if (cmd == OSD_SEND_CMD) | ||
719 | return av7110_osd_cmd(av7110, (osd_cmd_t *) parg); | ||
720 | if (cmd == OSD_GET_CAPABILITY) | ||
721 | return av7110_osd_capability(av7110, (osd_cap_t *) parg); | ||
722 | |||
723 | return -EINVAL; | ||
724 | } | ||
725 | |||
726 | |||
727 | static const struct file_operations dvb_osd_fops = { | ||
728 | .owner = THIS_MODULE, | ||
729 | .unlocked_ioctl = dvb_generic_ioctl, | ||
730 | .open = dvb_generic_open, | ||
731 | .release = dvb_generic_release, | ||
732 | .llseek = noop_llseek, | ||
733 | }; | ||
734 | |||
735 | static struct dvb_device dvbdev_osd = { | ||
736 | .priv = NULL, | ||
737 | .users = 1, | ||
738 | .writers = 1, | ||
739 | .fops = &dvb_osd_fops, | ||
740 | .kernel_ioctl = dvb_osd_ioctl, | ||
741 | }; | ||
742 | #endif /* CONFIG_DVB_AV7110_OSD */ | ||
743 | |||
744 | |||
745 | static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | ||
746 | u16 subpid, u16 pcrpid) | ||
747 | { | ||
748 | u16 aflags = 0; | ||
749 | |||
750 | dprintk(4, "%p\n", av7110); | ||
751 | |||
752 | if (vpid == 0x1fff || apid == 0x1fff || | ||
753 | ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) { | ||
754 | vpid = apid = ttpid = subpid = pcrpid = 0; | ||
755 | av7110->pids[DMX_PES_VIDEO] = 0; | ||
756 | av7110->pids[DMX_PES_AUDIO] = 0; | ||
757 | av7110->pids[DMX_PES_TELETEXT] = 0; | ||
758 | av7110->pids[DMX_PES_PCR] = 0; | ||
759 | } | ||
760 | |||
761 | if (av7110->audiostate.bypass_mode) | ||
762 | aflags |= 0x8000; | ||
763 | |||
764 | return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6, | ||
765 | pcrpid, vpid, apid, ttpid, subpid, aflags); | ||
766 | } | ||
767 | |||
768 | int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | ||
769 | u16 subpid, u16 pcrpid) | ||
770 | { | ||
771 | int ret = 0; | ||
772 | dprintk(4, "%p\n", av7110); | ||
773 | |||
774 | if (mutex_lock_interruptible(&av7110->pid_mutex)) | ||
775 | return -ERESTARTSYS; | ||
776 | |||
777 | if (!(vpid & 0x8000)) | ||
778 | av7110->pids[DMX_PES_VIDEO] = vpid; | ||
779 | if (!(apid & 0x8000)) | ||
780 | av7110->pids[DMX_PES_AUDIO] = apid; | ||
781 | if (!(ttpid & 0x8000)) | ||
782 | av7110->pids[DMX_PES_TELETEXT] = ttpid; | ||
783 | if (!(pcrpid & 0x8000)) | ||
784 | av7110->pids[DMX_PES_PCR] = pcrpid; | ||
785 | |||
786 | av7110->pids[DMX_PES_SUBTITLE] = 0; | ||
787 | |||
788 | if (av7110->fe_synced) { | ||
789 | pcrpid = av7110->pids[DMX_PES_PCR]; | ||
790 | ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); | ||
791 | } | ||
792 | |||
793 | mutex_unlock(&av7110->pid_mutex); | ||
794 | return ret; | ||
795 | } | ||
796 | |||
797 | |||
798 | /****************************************************************************** | ||
799 | * hardware filter functions | ||
800 | ******************************************************************************/ | ||
801 | |||
802 | static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) | ||
803 | { | ||
804 | struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed; | ||
805 | struct av7110 *av7110 = dvbdmxfeed->demux->priv; | ||
806 | u16 buf[20]; | ||
807 | int ret, i; | ||
808 | u16 handle; | ||
809 | // u16 mode = 0x0320; | ||
810 | u16 mode = 0xb96a; | ||
811 | |||
812 | dprintk(4, "%p\n", av7110); | ||
813 | |||
814 | if (av7110->full_ts) | ||
815 | return 0; | ||
816 | |||
817 | if (dvbdmxfilter->type == DMX_TYPE_SEC) { | ||
818 | if (hw_sections) { | ||
819 | buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) | | ||
820 | dvbdmxfilter->maskandmode[0]; | ||
821 | for (i = 3; i < 18; i++) | ||
822 | buf[i + 4 - 2] = | ||
823 | (dvbdmxfilter->filter.filter_value[i] << 8) | | ||
824 | dvbdmxfilter->maskandmode[i]; | ||
825 | mode = 4; | ||
826 | } | ||
827 | } else if ((dvbdmxfeed->ts_type & TS_PACKET) && | ||
828 | !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) { | ||
829 | av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed); | ||
830 | } | ||
831 | |||
832 | buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter; | ||
833 | buf[1] = 16; | ||
834 | buf[2] = dvbdmxfeed->pid; | ||
835 | buf[3] = mode; | ||
836 | |||
837 | ret = av7110_fw_request(av7110, buf, 20, &handle, 1); | ||
838 | if (ret != 0 || handle >= 32) { | ||
839 | printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " | ||
840 | "ret %d handle %04x\n", | ||
841 | __func__, buf[0], buf[1], buf[2], buf[3], | ||
842 | ret, handle); | ||
843 | dvbdmxfilter->hw_handle = 0xffff; | ||
844 | if (!ret) | ||
845 | ret = -1; | ||
846 | return ret; | ||
847 | } | ||
848 | |||
849 | av7110->handle2filter[handle] = dvbdmxfilter; | ||
850 | dvbdmxfilter->hw_handle = handle; | ||
851 | |||
852 | return ret; | ||
853 | } | ||
854 | |||
855 | static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) | ||
856 | { | ||
857 | struct av7110 *av7110 = dvbdmxfilter->feed->demux->priv; | ||
858 | u16 buf[3]; | ||
859 | u16 answ[2]; | ||
860 | int ret; | ||
861 | u16 handle; | ||
862 | |||
863 | dprintk(4, "%p\n", av7110); | ||
864 | |||
865 | if (av7110->full_ts) | ||
866 | return 0; | ||
867 | |||
868 | handle = dvbdmxfilter->hw_handle; | ||
869 | if (handle >= 32) { | ||
870 | printk("%s tried to stop invalid filter %04x, filter type = %x\n", | ||
871 | __func__, handle, dvbdmxfilter->type); | ||
872 | return -EINVAL; | ||
873 | } | ||
874 | |||
875 | av7110->handle2filter[handle] = NULL; | ||
876 | |||
877 | buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter; | ||
878 | buf[1] = 1; | ||
879 | buf[2] = handle; | ||
880 | ret = av7110_fw_request(av7110, buf, 3, answ, 2); | ||
881 | if (ret != 0 || answ[1] != handle) { | ||
882 | printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x " | ||
883 | "resp %04x %04x pid %d\n", | ||
884 | __func__, buf[0], buf[1], buf[2], ret, | ||
885 | answ[0], answ[1], dvbdmxfilter->feed->pid); | ||
886 | if (!ret) | ||
887 | ret = -1; | ||
888 | } | ||
889 | return ret; | ||
890 | } | ||
891 | |||
892 | |||
893 | static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) | ||
894 | { | ||
895 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
896 | struct av7110 *av7110 = dvbdmx->priv; | ||
897 | u16 *pid = dvbdmx->pids, npids[5]; | ||
898 | int i; | ||
899 | int ret = 0; | ||
900 | |||
901 | dprintk(4, "%p\n", av7110); | ||
902 | |||
903 | npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff; | ||
904 | i = dvbdmxfeed->pes_type; | ||
905 | npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; | ||
906 | if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) { | ||
907 | npids[i] = 0; | ||
908 | ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | ||
909 | if (!ret) | ||
910 | ret = StartHWFilter(dvbdmxfeed->filter); | ||
911 | return ret; | ||
912 | } | ||
913 | if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) { | ||
914 | ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | ||
915 | if (ret) | ||
916 | return ret; | ||
917 | } | ||
918 | |||
919 | if (dvbdmxfeed->pes_type < 2 && npids[0]) | ||
920 | if (av7110->fe_synced) | ||
921 | { | ||
922 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); | ||
923 | if (ret) | ||
924 | return ret; | ||
925 | } | ||
926 | |||
927 | if ((dvbdmxfeed->ts_type & TS_PACKET) && !av7110->full_ts) { | ||
928 | if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) | ||
929 | ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); | ||
930 | if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) | ||
931 | ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed); | ||
932 | } | ||
933 | return ret; | ||
934 | } | ||
935 | |||
936 | static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) | ||
937 | { | ||
938 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
939 | struct av7110 *av7110 = dvbdmx->priv; | ||
940 | u16 *pid = dvbdmx->pids, npids[5]; | ||
941 | int i; | ||
942 | |||
943 | int ret = 0; | ||
944 | |||
945 | dprintk(4, "%p\n", av7110); | ||
946 | |||
947 | if (dvbdmxfeed->pes_type <= 1) { | ||
948 | ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO); | ||
949 | if (ret) | ||
950 | return ret; | ||
951 | if (!av7110->rec_mode) | ||
952 | dvbdmx->recording = 0; | ||
953 | if (!av7110->playing) | ||
954 | dvbdmx->playing = 0; | ||
955 | } | ||
956 | npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff; | ||
957 | i = dvbdmxfeed->pes_type; | ||
958 | switch (i) { | ||
959 | case 2: //teletext | ||
960 | if (dvbdmxfeed->ts_type & TS_PACKET) | ||
961 | ret = StopHWFilter(dvbdmxfeed->filter); | ||
962 | npids[2] = 0; | ||
963 | break; | ||
964 | case 0: | ||
965 | case 1: | ||
966 | case 4: | ||
967 | if (!pids_off) | ||
968 | return 0; | ||
969 | npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; | ||
970 | break; | ||
971 | } | ||
972 | if (!ret) | ||
973 | ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); | ||
974 | return ret; | ||
975 | } | ||
976 | |||
977 | static int av7110_start_feed(struct dvb_demux_feed *feed) | ||
978 | { | ||
979 | struct dvb_demux *demux = feed->demux; | ||
980 | struct av7110 *av7110 = demux->priv; | ||
981 | int ret = 0; | ||
982 | |||
983 | dprintk(4, "%p\n", av7110); | ||
984 | |||
985 | if (!demux->dmx.frontend) | ||
986 | return -EINVAL; | ||
987 | |||
988 | if (!av7110->full_ts && feed->pid > 0x1fff) | ||
989 | return -EINVAL; | ||
990 | |||
991 | if (feed->type == DMX_TYPE_TS) { | ||
992 | if ((feed->ts_type & TS_DECODER) && | ||
993 | (feed->pes_type <= DMX_TS_PES_PCR)) { | ||
994 | switch (demux->dmx.frontend->source) { | ||
995 | case DMX_MEMORY_FE: | ||
996 | if (feed->ts_type & TS_DECODER) | ||
997 | if (feed->pes_type < 2 && | ||
998 | !(demux->pids[0] & 0x8000) && | ||
999 | !(demux->pids[1] & 0x8000)) { | ||
1000 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); | ||
1001 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); | ||
1002 | ret = av7110_av_start_play(av7110,RP_AV); | ||
1003 | if (!ret) | ||
1004 | demux->playing = 1; | ||
1005 | } | ||
1006 | break; | ||
1007 | default: | ||
1008 | ret = dvb_feed_start_pid(feed); | ||
1009 | break; | ||
1010 | } | ||
1011 | } else if ((feed->ts_type & TS_PACKET) && | ||
1012 | (demux->dmx.frontend->source != DMX_MEMORY_FE)) { | ||
1013 | ret = StartHWFilter(feed->filter); | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | if (av7110->full_ts) { | ||
1018 | budget_start_feed(feed); | ||
1019 | return ret; | ||
1020 | } | ||
1021 | |||
1022 | if (feed->type == DMX_TYPE_SEC) { | ||
1023 | int i; | ||
1024 | |||
1025 | for (i = 0; i < demux->filternum; i++) { | ||
1026 | if (demux->filter[i].state != DMX_STATE_READY) | ||
1027 | continue; | ||
1028 | if (demux->filter[i].type != DMX_TYPE_SEC) | ||
1029 | continue; | ||
1030 | if (demux->filter[i].filter.parent != &feed->feed.sec) | ||
1031 | continue; | ||
1032 | demux->filter[i].state = DMX_STATE_GO; | ||
1033 | if (demux->dmx.frontend->source != DMX_MEMORY_FE) { | ||
1034 | ret = StartHWFilter(&demux->filter[i]); | ||
1035 | if (ret) | ||
1036 | break; | ||
1037 | } | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | return ret; | ||
1042 | } | ||
1043 | |||
1044 | |||
1045 | static int av7110_stop_feed(struct dvb_demux_feed *feed) | ||
1046 | { | ||
1047 | struct dvb_demux *demux = feed->demux; | ||
1048 | struct av7110 *av7110 = demux->priv; | ||
1049 | int i, rc, ret = 0; | ||
1050 | dprintk(4, "%p\n", av7110); | ||
1051 | |||
1052 | if (feed->type == DMX_TYPE_TS) { | ||
1053 | if (feed->ts_type & TS_DECODER) { | ||
1054 | if (feed->pes_type >= DMX_TS_PES_OTHER || | ||
1055 | !demux->pesfilter[feed->pes_type]) | ||
1056 | return -EINVAL; | ||
1057 | demux->pids[feed->pes_type] |= 0x8000; | ||
1058 | demux->pesfilter[feed->pes_type] = NULL; | ||
1059 | } | ||
1060 | if (feed->ts_type & TS_DECODER && | ||
1061 | feed->pes_type < DMX_TS_PES_OTHER) { | ||
1062 | ret = dvb_feed_stop_pid(feed); | ||
1063 | } else | ||
1064 | if ((feed->ts_type & TS_PACKET) && | ||
1065 | (demux->dmx.frontend->source != DMX_MEMORY_FE)) | ||
1066 | ret = StopHWFilter(feed->filter); | ||
1067 | } | ||
1068 | |||
1069 | if (av7110->full_ts) { | ||
1070 | budget_stop_feed(feed); | ||
1071 | return ret; | ||
1072 | } | ||
1073 | |||
1074 | if (feed->type == DMX_TYPE_SEC) { | ||
1075 | for (i = 0; i<demux->filternum; i++) { | ||
1076 | if (demux->filter[i].state == DMX_STATE_GO && | ||
1077 | demux->filter[i].filter.parent == &feed->feed.sec) { | ||
1078 | demux->filter[i].state = DMX_STATE_READY; | ||
1079 | if (demux->dmx.frontend->source != DMX_MEMORY_FE) { | ||
1080 | rc = StopHWFilter(&demux->filter[i]); | ||
1081 | if (!ret) | ||
1082 | ret = rc; | ||
1083 | /* keep going, stop as many filters as possible */ | ||
1084 | } | ||
1085 | } | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | return ret; | ||
1090 | } | ||
1091 | |||
1092 | |||
1093 | static void restart_feeds(struct av7110 *av7110) | ||
1094 | { | ||
1095 | struct dvb_demux *dvbdmx = &av7110->demux; | ||
1096 | struct dvb_demux_feed *feed; | ||
1097 | int mode; | ||
1098 | int feeding; | ||
1099 | int i, j; | ||
1100 | |||
1101 | dprintk(4, "%p\n", av7110); | ||
1102 | |||
1103 | mode = av7110->playing; | ||
1104 | av7110->playing = 0; | ||
1105 | av7110->rec_mode = 0; | ||
1106 | |||
1107 | feeding = av7110->feeding1; /* full_ts mod */ | ||
1108 | |||
1109 | for (i = 0; i < dvbdmx->feednum; i++) { | ||
1110 | feed = &dvbdmx->feed[i]; | ||
1111 | if (feed->state == DMX_STATE_GO) { | ||
1112 | if (feed->type == DMX_TYPE_SEC) { | ||
1113 | for (j = 0; j < dvbdmx->filternum; j++) { | ||
1114 | if (dvbdmx->filter[j].type != DMX_TYPE_SEC) | ||
1115 | continue; | ||
1116 | if (dvbdmx->filter[j].filter.parent != &feed->feed.sec) | ||
1117 | continue; | ||
1118 | if (dvbdmx->filter[j].state == DMX_STATE_GO) | ||
1119 | dvbdmx->filter[j].state = DMX_STATE_READY; | ||
1120 | } | ||
1121 | } | ||
1122 | av7110_start_feed(feed); | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | av7110->feeding1 = feeding; /* full_ts mod */ | ||
1127 | |||
1128 | if (mode) | ||
1129 | av7110_av_start_play(av7110, mode); | ||
1130 | } | ||
1131 | |||
1132 | static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, | ||
1133 | uint64_t *stc, unsigned int *base) | ||
1134 | { | ||
1135 | int ret; | ||
1136 | u16 fwstc[4]; | ||
1137 | u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC); | ||
1138 | struct dvb_demux *dvbdemux; | ||
1139 | struct av7110 *av7110; | ||
1140 | |||
1141 | /* pointer casting paranoia... */ | ||
1142 | BUG_ON(!demux); | ||
1143 | dvbdemux = demux->priv; | ||
1144 | BUG_ON(!dvbdemux); | ||
1145 | av7110 = dvbdemux->priv; | ||
1146 | |||
1147 | dprintk(4, "%p\n", av7110); | ||
1148 | |||
1149 | if (num != 0) | ||
1150 | return -EINVAL; | ||
1151 | |||
1152 | ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4); | ||
1153 | if (ret) { | ||
1154 | printk(KERN_ERR "%s: av7110_fw_request error\n", __func__); | ||
1155 | return ret; | ||
1156 | } | ||
1157 | dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", | ||
1158 | fwstc[0], fwstc[1], fwstc[2], fwstc[3]); | ||
1159 | |||
1160 | *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) | | ||
1161 | (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]); | ||
1162 | *base = 1; | ||
1163 | |||
1164 | dprintk(4, "stc = %lu\n", (unsigned long)*stc); | ||
1165 | |||
1166 | return 0; | ||
1167 | } | ||
1168 | |||
1169 | |||
1170 | /****************************************************************************** | ||
1171 | * SEC device file operations | ||
1172 | ******************************************************************************/ | ||
1173 | |||
1174 | |||
1175 | static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
1176 | { | ||
1177 | struct av7110* av7110 = fe->dvb->priv; | ||
1178 | |||
1179 | switch (tone) { | ||
1180 | case SEC_TONE_ON: | ||
1181 | return Set22K(av7110, 1); | ||
1182 | |||
1183 | case SEC_TONE_OFF: | ||
1184 | return Set22K(av7110, 0); | ||
1185 | |||
1186 | default: | ||
1187 | return -EINVAL; | ||
1188 | } | ||
1189 | } | ||
1190 | |||
1191 | static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, | ||
1192 | struct dvb_diseqc_master_cmd* cmd) | ||
1193 | { | ||
1194 | struct av7110* av7110 = fe->dvb->priv; | ||
1195 | |||
1196 | return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); | ||
1197 | } | ||
1198 | |||
1199 | static int av7110_diseqc_send_burst(struct dvb_frontend* fe, | ||
1200 | fe_sec_mini_cmd_t minicmd) | ||
1201 | { | ||
1202 | struct av7110* av7110 = fe->dvb->priv; | ||
1203 | |||
1204 | return av7110_diseqc_send(av7110, 0, NULL, minicmd); | ||
1205 | } | ||
1206 | |||
1207 | /* simplified code from budget-core.c */ | ||
1208 | static int stop_ts_capture(struct av7110 *budget) | ||
1209 | { | ||
1210 | dprintk(2, "budget: %p\n", budget); | ||
1211 | |||
1212 | if (--budget->feeding1) | ||
1213 | return budget->feeding1; | ||
1214 | saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */ | ||
1215 | SAA7146_IER_DISABLE(budget->dev, MASK_10); | ||
1216 | SAA7146_ISR_CLEAR(budget->dev, MASK_10); | ||
1217 | return 0; | ||
1218 | } | ||
1219 | |||
1220 | static int start_ts_capture(struct av7110 *budget) | ||
1221 | { | ||
1222 | dprintk(2, "budget: %p\n", budget); | ||
1223 | |||
1224 | if (budget->feeding1) | ||
1225 | return ++budget->feeding1; | ||
1226 | memset(budget->grabbing, 0x00, TS_BUFLEN); | ||
1227 | budget->ttbp = 0; | ||
1228 | SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */ | ||
1229 | SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ | ||
1230 | saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ | ||
1231 | return ++budget->feeding1; | ||
1232 | } | ||
1233 | |||
1234 | static int budget_start_feed(struct dvb_demux_feed *feed) | ||
1235 | { | ||
1236 | struct dvb_demux *demux = feed->demux; | ||
1237 | struct av7110 *budget = demux->priv; | ||
1238 | int status; | ||
1239 | |||
1240 | dprintk(2, "av7110: %p\n", budget); | ||
1241 | |||
1242 | spin_lock(&budget->feedlock1); | ||
1243 | feed->pusi_seen = 0; /* have a clean section start */ | ||
1244 | status = start_ts_capture(budget); | ||
1245 | spin_unlock(&budget->feedlock1); | ||
1246 | return status; | ||
1247 | } | ||
1248 | |||
1249 | static int budget_stop_feed(struct dvb_demux_feed *feed) | ||
1250 | { | ||
1251 | struct dvb_demux *demux = feed->demux; | ||
1252 | struct av7110 *budget = demux->priv; | ||
1253 | int status; | ||
1254 | |||
1255 | dprintk(2, "budget: %p\n", budget); | ||
1256 | |||
1257 | spin_lock(&budget->feedlock1); | ||
1258 | status = stop_ts_capture(budget); | ||
1259 | spin_unlock(&budget->feedlock1); | ||
1260 | return status; | ||
1261 | } | ||
1262 | |||
1263 | static void vpeirq(unsigned long cookie) | ||
1264 | { | ||
1265 | struct av7110 *budget = (struct av7110 *)cookie; | ||
1266 | u8 *mem = (u8 *) (budget->grabbing); | ||
1267 | u32 olddma = budget->ttbp; | ||
1268 | u32 newdma = saa7146_read(budget->dev, PCI_VDP3); | ||
1269 | struct dvb_demux *demux = budget->full_ts ? &budget->demux : &budget->demux1; | ||
1270 | |||
1271 | /* nearest lower position divisible by 188 */ | ||
1272 | newdma -= newdma % 188; | ||
1273 | |||
1274 | if (newdma >= TS_BUFLEN) | ||
1275 | return; | ||
1276 | |||
1277 | budget->ttbp = newdma; | ||
1278 | |||
1279 | if (!budget->feeding1 || (newdma == olddma)) | ||
1280 | return; | ||
1281 | |||
1282 | /* Ensure streamed PCI data is synced to CPU */ | ||
1283 | pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE); | ||
1284 | |||
1285 | #if 0 | ||
1286 | /* track rps1 activity */ | ||
1287 | printk("vpeirq: %02x Event Counter 1 0x%04x\n", | ||
1288 | mem[olddma], | ||
1289 | saa7146_read(budget->dev, EC1R) & 0x3fff); | ||
1290 | #endif | ||
1291 | |||
1292 | if (newdma > olddma) | ||
1293 | /* no wraparound, dump olddma..newdma */ | ||
1294 | dvb_dmx_swfilter_packets(demux, mem + olddma, (newdma - olddma) / 188); | ||
1295 | else { | ||
1296 | /* wraparound, dump olddma..buflen and 0..newdma */ | ||
1297 | dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - olddma) / 188); | ||
1298 | dvb_dmx_swfilter_packets(demux, mem, newdma / 188); | ||
1299 | } | ||
1300 | } | ||
1301 | |||
1302 | static int av7110_register(struct av7110 *av7110) | ||
1303 | { | ||
1304 | int ret, i; | ||
1305 | struct dvb_demux *dvbdemux = &av7110->demux; | ||
1306 | struct dvb_demux *dvbdemux1 = &av7110->demux1; | ||
1307 | |||
1308 | dprintk(4, "%p\n", av7110); | ||
1309 | |||
1310 | if (av7110->registered) | ||
1311 | return -1; | ||
1312 | |||
1313 | av7110->registered = 1; | ||
1314 | |||
1315 | dvbdemux->priv = (void *) av7110; | ||
1316 | |||
1317 | for (i = 0; i < 32; i++) | ||
1318 | av7110->handle2filter[i] = NULL; | ||
1319 | |||
1320 | dvbdemux->filternum = (av7110->full_ts) ? 256 : 32; | ||
1321 | dvbdemux->feednum = (av7110->full_ts) ? 256 : 32; | ||
1322 | dvbdemux->start_feed = av7110_start_feed; | ||
1323 | dvbdemux->stop_feed = av7110_stop_feed; | ||
1324 | dvbdemux->write_to_decoder = av7110_write_to_decoder; | ||
1325 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
1326 | DMX_MEMORY_BASED_FILTERING); | ||
1327 | |||
1328 | dvb_dmx_init(&av7110->demux); | ||
1329 | av7110->demux.dmx.get_stc = dvb_get_stc; | ||
1330 | |||
1331 | av7110->dmxdev.filternum = (av7110->full_ts) ? 256 : 32; | ||
1332 | av7110->dmxdev.demux = &dvbdemux->dmx; | ||
1333 | av7110->dmxdev.capabilities = 0; | ||
1334 | |||
1335 | dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter); | ||
1336 | |||
1337 | av7110->hw_frontend.source = DMX_FRONTEND_0; | ||
1338 | |||
1339 | ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend); | ||
1340 | |||
1341 | if (ret < 0) | ||
1342 | return ret; | ||
1343 | |||
1344 | av7110->mem_frontend.source = DMX_MEMORY_FE; | ||
1345 | |||
1346 | ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend); | ||
1347 | |||
1348 | if (ret < 0) | ||
1349 | return ret; | ||
1350 | |||
1351 | ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, | ||
1352 | &av7110->hw_frontend); | ||
1353 | if (ret < 0) | ||
1354 | return ret; | ||
1355 | |||
1356 | av7110_av_register(av7110); | ||
1357 | av7110_ca_register(av7110); | ||
1358 | |||
1359 | #ifdef CONFIG_DVB_AV7110_OSD | ||
1360 | dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev, | ||
1361 | &dvbdev_osd, av7110, DVB_DEVICE_OSD); | ||
1362 | #endif | ||
1363 | |||
1364 | dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); | ||
1365 | |||
1366 | if (budgetpatch) { | ||
1367 | /* initialize software demux1 without its own frontend | ||
1368 | * demux1 hardware is connected to frontend0 of demux0 | ||
1369 | */ | ||
1370 | dvbdemux1->priv = (void *) av7110; | ||
1371 | |||
1372 | dvbdemux1->filternum = 256; | ||
1373 | dvbdemux1->feednum = 256; | ||
1374 | dvbdemux1->start_feed = budget_start_feed; | ||
1375 | dvbdemux1->stop_feed = budget_stop_feed; | ||
1376 | dvbdemux1->write_to_decoder = NULL; | ||
1377 | |||
1378 | dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
1379 | DMX_MEMORY_BASED_FILTERING); | ||
1380 | |||
1381 | dvb_dmx_init(&av7110->demux1); | ||
1382 | |||
1383 | av7110->dmxdev1.filternum = 256; | ||
1384 | av7110->dmxdev1.demux = &dvbdemux1->dmx; | ||
1385 | av7110->dmxdev1.capabilities = 0; | ||
1386 | |||
1387 | dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter); | ||
1388 | |||
1389 | dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx); | ||
1390 | printk("dvb-ttpci: additional demux1 for budget-patch registered\n"); | ||
1391 | } | ||
1392 | return 0; | ||
1393 | } | ||
1394 | |||
1395 | |||
1396 | static void dvb_unregister(struct av7110 *av7110) | ||
1397 | { | ||
1398 | struct dvb_demux *dvbdemux = &av7110->demux; | ||
1399 | struct dvb_demux *dvbdemux1 = &av7110->demux1; | ||
1400 | |||
1401 | dprintk(4, "%p\n", av7110); | ||
1402 | |||
1403 | if (!av7110->registered) | ||
1404 | return; | ||
1405 | |||
1406 | if (budgetpatch) { | ||
1407 | dvb_net_release(&av7110->dvb_net1); | ||
1408 | dvbdemux->dmx.close(&dvbdemux1->dmx); | ||
1409 | dvb_dmxdev_release(&av7110->dmxdev1); | ||
1410 | dvb_dmx_release(&av7110->demux1); | ||
1411 | } | ||
1412 | |||
1413 | dvb_net_release(&av7110->dvb_net); | ||
1414 | |||
1415 | dvbdemux->dmx.close(&dvbdemux->dmx); | ||
1416 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend); | ||
1417 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend); | ||
1418 | |||
1419 | dvb_dmxdev_release(&av7110->dmxdev); | ||
1420 | dvb_dmx_release(&av7110->demux); | ||
1421 | |||
1422 | if (av7110->fe != NULL) { | ||
1423 | dvb_unregister_frontend(av7110->fe); | ||
1424 | dvb_frontend_detach(av7110->fe); | ||
1425 | } | ||
1426 | dvb_unregister_device(av7110->osd_dev); | ||
1427 | av7110_av_unregister(av7110); | ||
1428 | av7110_ca_unregister(av7110); | ||
1429 | } | ||
1430 | |||
1431 | |||
1432 | /**************************************************************************** | ||
1433 | * I2C client commands | ||
1434 | ****************************************************************************/ | ||
1435 | |||
1436 | int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val) | ||
1437 | { | ||
1438 | u8 msg[2] = { reg, val }; | ||
1439 | struct i2c_msg msgs; | ||
1440 | |||
1441 | msgs.flags = 0; | ||
1442 | msgs.addr = id / 2; | ||
1443 | msgs.len = 2; | ||
1444 | msgs.buf = msg; | ||
1445 | return i2c_transfer(&av7110->i2c_adap, &msgs, 1); | ||
1446 | } | ||
1447 | |||
1448 | u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) | ||
1449 | { | ||
1450 | u8 mm1[] = {0x00}; | ||
1451 | u8 mm2[] = {0x00}; | ||
1452 | struct i2c_msg msgs[2]; | ||
1453 | |||
1454 | msgs[0].flags = 0; | ||
1455 | msgs[1].flags = I2C_M_RD; | ||
1456 | msgs[0].addr = msgs[1].addr = id / 2; | ||
1457 | mm1[0] = reg; | ||
1458 | msgs[0].len = 1; msgs[1].len = 1; | ||
1459 | msgs[0].buf = mm1; msgs[1].buf = mm2; | ||
1460 | i2c_transfer(&av7110->i2c_adap, msgs, 2); | ||
1461 | |||
1462 | return mm2[0]; | ||
1463 | } | ||
1464 | |||
1465 | /**************************************************************************** | ||
1466 | * INITIALIZATION | ||
1467 | ****************************************************************************/ | ||
1468 | |||
1469 | |||
1470 | static int check_firmware(struct av7110* av7110) | ||
1471 | { | ||
1472 | u32 crc = 0, len = 0; | ||
1473 | unsigned char *ptr; | ||
1474 | |||
1475 | /* check for firmware magic */ | ||
1476 | ptr = av7110->bin_fw; | ||
1477 | if (ptr[0] != 'A' || ptr[1] != 'V' || | ||
1478 | ptr[2] != 'F' || ptr[3] != 'W') { | ||
1479 | printk("dvb-ttpci: this is not an av7110 firmware\n"); | ||
1480 | return -EINVAL; | ||
1481 | } | ||
1482 | ptr += 4; | ||
1483 | |||
1484 | /* check dpram file */ | ||
1485 | crc = get_unaligned_be32(ptr); | ||
1486 | ptr += 4; | ||
1487 | len = get_unaligned_be32(ptr); | ||
1488 | ptr += 4; | ||
1489 | if (len >= 512) { | ||
1490 | printk("dvb-ttpci: dpram file is way too big.\n"); | ||
1491 | return -EINVAL; | ||
1492 | } | ||
1493 | if (crc != crc32_le(0, ptr, len)) { | ||
1494 | printk("dvb-ttpci: crc32 of dpram file does not match.\n"); | ||
1495 | return -EINVAL; | ||
1496 | } | ||
1497 | av7110->bin_dpram = ptr; | ||
1498 | av7110->size_dpram = len; | ||
1499 | ptr += len; | ||
1500 | |||
1501 | /* check root file */ | ||
1502 | crc = get_unaligned_be32(ptr); | ||
1503 | ptr += 4; | ||
1504 | len = get_unaligned_be32(ptr); | ||
1505 | ptr += 4; | ||
1506 | |||
1507 | if (len <= 200000 || len >= 300000 || | ||
1508 | len > ((av7110->bin_fw + av7110->size_fw) - ptr)) { | ||
1509 | printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len); | ||
1510 | return -EINVAL; | ||
1511 | } | ||
1512 | if( crc != crc32_le(0, ptr, len)) { | ||
1513 | printk("dvb-ttpci: crc32 of root file does not match.\n"); | ||
1514 | return -EINVAL; | ||
1515 | } | ||
1516 | av7110->bin_root = ptr; | ||
1517 | av7110->size_root = len; | ||
1518 | return 0; | ||
1519 | } | ||
1520 | |||
1521 | static void put_firmware(struct av7110* av7110) | ||
1522 | { | ||
1523 | vfree(av7110->bin_fw); | ||
1524 | } | ||
1525 | |||
1526 | static int get_firmware(struct av7110* av7110) | ||
1527 | { | ||
1528 | int ret; | ||
1529 | const struct firmware *fw; | ||
1530 | |||
1531 | /* request the av7110 firmware, this will block until someone uploads it */ | ||
1532 | ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); | ||
1533 | if (ret) { | ||
1534 | if (ret == -ENOENT) { | ||
1535 | printk(KERN_ERR "dvb-ttpci: could not load firmware," | ||
1536 | " file not found: dvb-ttpci-01.fw\n"); | ||
1537 | printk(KERN_ERR "dvb-ttpci: usually this should be in " | ||
1538 | "/usr/lib/hotplug/firmware or /lib/firmware\n"); | ||
1539 | printk(KERN_ERR "dvb-ttpci: and can be downloaded from" | ||
1540 | " http://www.linuxtv.org/download/dvb/firmware/\n"); | ||
1541 | } else | ||
1542 | printk(KERN_ERR "dvb-ttpci: cannot request firmware" | ||
1543 | " (error %i)\n", ret); | ||
1544 | return -EINVAL; | ||
1545 | } | ||
1546 | |||
1547 | if (fw->size <= 200000) { | ||
1548 | printk("dvb-ttpci: this firmware is way too small.\n"); | ||
1549 | release_firmware(fw); | ||
1550 | return -EINVAL; | ||
1551 | } | ||
1552 | |||
1553 | /* check if the firmware is available */ | ||
1554 | av7110->bin_fw = vmalloc(fw->size); | ||
1555 | if (NULL == av7110->bin_fw) { | ||
1556 | dprintk(1, "out of memory\n"); | ||
1557 | release_firmware(fw); | ||
1558 | return -ENOMEM; | ||
1559 | } | ||
1560 | |||
1561 | memcpy(av7110->bin_fw, fw->data, fw->size); | ||
1562 | av7110->size_fw = fw->size; | ||
1563 | if ((ret = check_firmware(av7110))) | ||
1564 | vfree(av7110->bin_fw); | ||
1565 | |||
1566 | release_firmware(fw); | ||
1567 | return ret; | ||
1568 | } | ||
1569 | |||
1570 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) | ||
1571 | { | ||
1572 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1573 | struct av7110* av7110 = fe->dvb->priv; | ||
1574 | u8 pwr = 0; | ||
1575 | u8 buf[4]; | ||
1576 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
1577 | u32 div = (p->frequency + 479500) / 125; | ||
1578 | |||
1579 | if (p->frequency > 2000000) | ||
1580 | pwr = 3; | ||
1581 | else if (p->frequency > 1800000) | ||
1582 | pwr = 2; | ||
1583 | else if (p->frequency > 1600000) | ||
1584 | pwr = 1; | ||
1585 | else if (p->frequency > 1200000) | ||
1586 | pwr = 0; | ||
1587 | else if (p->frequency >= 1100000) | ||
1588 | pwr = 1; | ||
1589 | else | ||
1590 | pwr = 2; | ||
1591 | |||
1592 | buf[0] = (div >> 8) & 0x7f; | ||
1593 | buf[1] = div & 0xff; | ||
1594 | buf[2] = ((div & 0x18000) >> 10) | 0x95; | ||
1595 | buf[3] = (pwr << 6) | 0x30; | ||
1596 | |||
1597 | // NOTE: since we're using a prescaler of 2, we set the | ||
1598 | // divisor frequency to 62.5kHz and divide by 125 above | ||
1599 | |||
1600 | if (fe->ops.i2c_gate_ctrl) | ||
1601 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1602 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) | ||
1603 | return -EIO; | ||
1604 | return 0; | ||
1605 | } | ||
1606 | |||
1607 | static struct ves1x93_config alps_bsrv2_config = { | ||
1608 | .demod_address = 0x08, | ||
1609 | .xin = 90100000UL, | ||
1610 | .invert_pwm = 0, | ||
1611 | }; | ||
1612 | |||
1613 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) | ||
1614 | { | ||
1615 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1616 | struct av7110* av7110 = fe->dvb->priv; | ||
1617 | u32 div; | ||
1618 | u8 data[4]; | ||
1619 | struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1620 | |||
1621 | div = (p->frequency + 35937500 + 31250) / 62500; | ||
1622 | |||
1623 | data[0] = (div >> 8) & 0x7f; | ||
1624 | data[1] = div & 0xff; | ||
1625 | data[2] = 0x85 | ((div >> 10) & 0x60); | ||
1626 | data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81); | ||
1627 | |||
1628 | if (fe->ops.i2c_gate_ctrl) | ||
1629 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1630 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | ||
1631 | return -EIO; | ||
1632 | return 0; | ||
1633 | } | ||
1634 | |||
1635 | static struct ves1820_config alps_tdbe2_config = { | ||
1636 | .demod_address = 0x09, | ||
1637 | .xin = 57840000UL, | ||
1638 | .invert = 1, | ||
1639 | .selagc = VES1820_SELAGC_SIGNAMPERR, | ||
1640 | }; | ||
1641 | |||
1642 | |||
1643 | |||
1644 | |||
1645 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) | ||
1646 | { | ||
1647 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1648 | struct av7110* av7110 = fe->dvb->priv; | ||
1649 | u32 div; | ||
1650 | u8 data[4]; | ||
1651 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1652 | |||
1653 | div = p->frequency / 125; | ||
1654 | data[0] = (div >> 8) & 0x7f; | ||
1655 | data[1] = div & 0xff; | ||
1656 | data[2] = 0x8e; | ||
1657 | data[3] = 0x00; | ||
1658 | |||
1659 | if (fe->ops.i2c_gate_ctrl) | ||
1660 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1661 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | ||
1662 | return -EIO; | ||
1663 | return 0; | ||
1664 | } | ||
1665 | |||
1666 | static struct tda8083_config grundig_29504_451_config = { | ||
1667 | .demod_address = 0x68, | ||
1668 | }; | ||
1669 | |||
1670 | |||
1671 | |||
1672 | static int philips_cd1516_tuner_set_params(struct dvb_frontend *fe) | ||
1673 | { | ||
1674 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1675 | struct av7110* av7110 = fe->dvb->priv; | ||
1676 | u32 div; | ||
1677 | u32 f = p->frequency; | ||
1678 | u8 data[4]; | ||
1679 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1680 | |||
1681 | div = (f + 36125000 + 31250) / 62500; | ||
1682 | |||
1683 | data[0] = (div >> 8) & 0x7f; | ||
1684 | data[1] = div & 0xff; | ||
1685 | data[2] = 0x8e; | ||
1686 | data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); | ||
1687 | |||
1688 | if (fe->ops.i2c_gate_ctrl) | ||
1689 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1690 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | ||
1691 | return -EIO; | ||
1692 | return 0; | ||
1693 | } | ||
1694 | |||
1695 | static struct ves1820_config philips_cd1516_config = { | ||
1696 | .demod_address = 0x09, | ||
1697 | .xin = 57840000UL, | ||
1698 | .invert = 1, | ||
1699 | .selagc = VES1820_SELAGC_SIGNAMPERR, | ||
1700 | }; | ||
1701 | |||
1702 | |||
1703 | |||
1704 | static int alps_tdlb7_tuner_set_params(struct dvb_frontend *fe) | ||
1705 | { | ||
1706 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1707 | struct av7110* av7110 = fe->dvb->priv; | ||
1708 | u32 div, pwr; | ||
1709 | u8 data[4]; | ||
1710 | struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1711 | |||
1712 | div = (p->frequency + 36200000) / 166666; | ||
1713 | |||
1714 | if (p->frequency <= 782000000) | ||
1715 | pwr = 1; | ||
1716 | else | ||
1717 | pwr = 2; | ||
1718 | |||
1719 | data[0] = (div >> 8) & 0x7f; | ||
1720 | data[1] = div & 0xff; | ||
1721 | data[2] = 0x85; | ||
1722 | data[3] = pwr << 6; | ||
1723 | |||
1724 | if (fe->ops.i2c_gate_ctrl) | ||
1725 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1726 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | ||
1727 | return -EIO; | ||
1728 | return 0; | ||
1729 | } | ||
1730 | |||
1731 | static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) | ||
1732 | { | ||
1733 | #if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE) | ||
1734 | struct av7110* av7110 = fe->dvb->priv; | ||
1735 | |||
1736 | return request_firmware(fw, name, &av7110->dev->pci->dev); | ||
1737 | #else | ||
1738 | return -EINVAL; | ||
1739 | #endif | ||
1740 | } | ||
1741 | |||
1742 | static struct sp8870_config alps_tdlb7_config = { | ||
1743 | |||
1744 | .demod_address = 0x71, | ||
1745 | .request_firmware = alps_tdlb7_request_firmware, | ||
1746 | }; | ||
1747 | |||
1748 | |||
1749 | static u8 nexusca_stv0297_inittab[] = { | ||
1750 | 0x80, 0x01, | ||
1751 | 0x80, 0x00, | ||
1752 | 0x81, 0x01, | ||
1753 | 0x81, 0x00, | ||
1754 | 0x00, 0x09, | ||
1755 | 0x01, 0x69, | ||
1756 | 0x03, 0x00, | ||
1757 | 0x04, 0x00, | ||
1758 | 0x07, 0x00, | ||
1759 | 0x08, 0x00, | ||
1760 | 0x20, 0x00, | ||
1761 | 0x21, 0x40, | ||
1762 | 0x22, 0x00, | ||
1763 | 0x23, 0x00, | ||
1764 | 0x24, 0x40, | ||
1765 | 0x25, 0x88, | ||
1766 | 0x30, 0xff, | ||
1767 | 0x31, 0x00, | ||
1768 | 0x32, 0xff, | ||
1769 | 0x33, 0x00, | ||
1770 | 0x34, 0x50, | ||
1771 | 0x35, 0x7f, | ||
1772 | 0x36, 0x00, | ||
1773 | 0x37, 0x20, | ||
1774 | 0x38, 0x00, | ||
1775 | 0x40, 0x1c, | ||
1776 | 0x41, 0xff, | ||
1777 | 0x42, 0x29, | ||
1778 | 0x43, 0x00, | ||
1779 | 0x44, 0xff, | ||
1780 | 0x45, 0x00, | ||
1781 | 0x46, 0x00, | ||
1782 | 0x49, 0x04, | ||
1783 | 0x4a, 0x00, | ||
1784 | 0x4b, 0x7b, | ||
1785 | 0x52, 0x30, | ||
1786 | 0x55, 0xae, | ||
1787 | 0x56, 0x47, | ||
1788 | 0x57, 0xe1, | ||
1789 | 0x58, 0x3a, | ||
1790 | 0x5a, 0x1e, | ||
1791 | 0x5b, 0x34, | ||
1792 | 0x60, 0x00, | ||
1793 | 0x63, 0x00, | ||
1794 | 0x64, 0x00, | ||
1795 | 0x65, 0x00, | ||
1796 | 0x66, 0x00, | ||
1797 | 0x67, 0x00, | ||
1798 | 0x68, 0x00, | ||
1799 | 0x69, 0x00, | ||
1800 | 0x6a, 0x02, | ||
1801 | 0x6b, 0x00, | ||
1802 | 0x70, 0xff, | ||
1803 | 0x71, 0x00, | ||
1804 | 0x72, 0x00, | ||
1805 | 0x73, 0x00, | ||
1806 | 0x74, 0x0c, | ||
1807 | 0x80, 0x00, | ||
1808 | 0x81, 0x00, | ||
1809 | 0x82, 0x00, | ||
1810 | 0x83, 0x00, | ||
1811 | 0x84, 0x04, | ||
1812 | 0x85, 0x80, | ||
1813 | 0x86, 0x24, | ||
1814 | 0x87, 0x78, | ||
1815 | 0x88, 0x10, | ||
1816 | 0x89, 0x00, | ||
1817 | 0x90, 0x01, | ||
1818 | 0x91, 0x01, | ||
1819 | 0xa0, 0x04, | ||
1820 | 0xa1, 0x00, | ||
1821 | 0xa2, 0x00, | ||
1822 | 0xb0, 0x91, | ||
1823 | 0xb1, 0x0b, | ||
1824 | 0xc0, 0x53, | ||
1825 | 0xc1, 0x70, | ||
1826 | 0xc2, 0x12, | ||
1827 | 0xd0, 0x00, | ||
1828 | 0xd1, 0x00, | ||
1829 | 0xd2, 0x00, | ||
1830 | 0xd3, 0x00, | ||
1831 | 0xd4, 0x00, | ||
1832 | 0xd5, 0x00, | ||
1833 | 0xde, 0x00, | ||
1834 | 0xdf, 0x00, | ||
1835 | 0x61, 0x49, | ||
1836 | 0x62, 0x0b, | ||
1837 | 0x53, 0x08, | ||
1838 | 0x59, 0x08, | ||
1839 | 0xff, 0xff, | ||
1840 | }; | ||
1841 | |||
1842 | static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe) | ||
1843 | { | ||
1844 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1845 | struct av7110* av7110 = fe->dvb->priv; | ||
1846 | u32 div; | ||
1847 | u8 data[4]; | ||
1848 | struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1849 | struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 }; | ||
1850 | int i; | ||
1851 | |||
1852 | div = (p->frequency + 36150000 + 31250) / 62500; | ||
1853 | |||
1854 | data[0] = (div >> 8) & 0x7f; | ||
1855 | data[1] = div & 0xff; | ||
1856 | data[2] = 0xce; | ||
1857 | |||
1858 | if (p->frequency < 45000000) | ||
1859 | return -EINVAL; | ||
1860 | else if (p->frequency < 137000000) | ||
1861 | data[3] = 0x01; | ||
1862 | else if (p->frequency < 403000000) | ||
1863 | data[3] = 0x02; | ||
1864 | else if (p->frequency < 860000000) | ||
1865 | data[3] = 0x04; | ||
1866 | else | ||
1867 | return -EINVAL; | ||
1868 | |||
1869 | if (fe->ops.i2c_gate_ctrl) | ||
1870 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1871 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { | ||
1872 | printk("nexusca: pll transfer failed!\n"); | ||
1873 | return -EIO; | ||
1874 | } | ||
1875 | |||
1876 | // wait for PLL lock | ||
1877 | for(i = 0; i < 20; i++) { | ||
1878 | if (fe->ops.i2c_gate_ctrl) | ||
1879 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1880 | if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) | ||
1881 | if (data[0] & 0x40) break; | ||
1882 | msleep(10); | ||
1883 | } | ||
1884 | |||
1885 | return 0; | ||
1886 | } | ||
1887 | |||
1888 | static struct stv0297_config nexusca_stv0297_config = { | ||
1889 | |||
1890 | .demod_address = 0x1C, | ||
1891 | .inittab = nexusca_stv0297_inittab, | ||
1892 | .invert = 1, | ||
1893 | .stop_during_read = 1, | ||
1894 | }; | ||
1895 | |||
1896 | |||
1897 | |||
1898 | static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe) | ||
1899 | { | ||
1900 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1901 | struct av7110* av7110 = fe->dvb->priv; | ||
1902 | u32 div; | ||
1903 | u8 cfg, cpump, band_select; | ||
1904 | u8 data[4]; | ||
1905 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1906 | |||
1907 | div = (36125000 + p->frequency) / 166666; | ||
1908 | |||
1909 | cfg = 0x88; | ||
1910 | |||
1911 | if (p->frequency < 175000000) | ||
1912 | cpump = 2; | ||
1913 | else if (p->frequency < 390000000) | ||
1914 | cpump = 1; | ||
1915 | else if (p->frequency < 470000000) | ||
1916 | cpump = 2; | ||
1917 | else if (p->frequency < 750000000) | ||
1918 | cpump = 1; | ||
1919 | else | ||
1920 | cpump = 3; | ||
1921 | |||
1922 | if (p->frequency < 175000000) | ||
1923 | band_select = 0x0e; | ||
1924 | else if (p->frequency < 470000000) | ||
1925 | band_select = 0x05; | ||
1926 | else | ||
1927 | band_select = 0x03; | ||
1928 | |||
1929 | data[0] = (div >> 8) & 0x7f; | ||
1930 | data[1] = div & 0xff; | ||
1931 | data[2] = ((div >> 10) & 0x60) | cfg; | ||
1932 | data[3] = (cpump << 6) | band_select; | ||
1933 | |||
1934 | if (fe->ops.i2c_gate_ctrl) | ||
1935 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1936 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; | ||
1937 | return 0; | ||
1938 | } | ||
1939 | |||
1940 | static struct l64781_config grundig_29504_401_config = { | ||
1941 | .demod_address = 0x55, | ||
1942 | }; | ||
1943 | |||
1944 | |||
1945 | |||
1946 | static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) | ||
1947 | { | ||
1948 | int ret = 0; | ||
1949 | int synced = (status & FE_HAS_LOCK) ? 1 : 0; | ||
1950 | |||
1951 | av7110->fe_status = status; | ||
1952 | |||
1953 | if (av7110->fe_synced == synced) | ||
1954 | return 0; | ||
1955 | |||
1956 | if (av7110->playing) { | ||
1957 | av7110->fe_synced = synced; | ||
1958 | return 0; | ||
1959 | } | ||
1960 | |||
1961 | if (mutex_lock_interruptible(&av7110->pid_mutex)) | ||
1962 | return -ERESTARTSYS; | ||
1963 | |||
1964 | if (synced) { | ||
1965 | ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], | ||
1966 | av7110->pids[DMX_PES_AUDIO], | ||
1967 | av7110->pids[DMX_PES_TELETEXT], 0, | ||
1968 | av7110->pids[DMX_PES_PCR]); | ||
1969 | if (!ret) | ||
1970 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); | ||
1971 | } else { | ||
1972 | ret = SetPIDs(av7110, 0, 0, 0, 0, 0); | ||
1973 | if (!ret) { | ||
1974 | ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0); | ||
1975 | if (!ret) | ||
1976 | ret = av7110_wait_msgstate(av7110, GPMQBusy); | ||
1977 | } | ||
1978 | } | ||
1979 | |||
1980 | if (!ret) | ||
1981 | av7110->fe_synced = synced; | ||
1982 | |||
1983 | mutex_unlock(&av7110->pid_mutex); | ||
1984 | return ret; | ||
1985 | } | ||
1986 | |||
1987 | static int av7110_fe_set_frontend(struct dvb_frontend *fe) | ||
1988 | { | ||
1989 | struct av7110* av7110 = fe->dvb->priv; | ||
1990 | |||
1991 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
1992 | if (!ret) | ||
1993 | ret = av7110->fe_set_frontend(fe); | ||
1994 | |||
1995 | return ret; | ||
1996 | } | ||
1997 | |||
1998 | static int av7110_fe_init(struct dvb_frontend* fe) | ||
1999 | { | ||
2000 | struct av7110* av7110 = fe->dvb->priv; | ||
2001 | |||
2002 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
2003 | if (!ret) | ||
2004 | ret = av7110->fe_init(fe); | ||
2005 | return ret; | ||
2006 | } | ||
2007 | |||
2008 | static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
2009 | { | ||
2010 | struct av7110* av7110 = fe->dvb->priv; | ||
2011 | |||
2012 | /* call the real implementation */ | ||
2013 | int ret = av7110->fe_read_status(fe, status); | ||
2014 | if (!ret) | ||
2015 | if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) | ||
2016 | ret = av7110_fe_lock_fix(av7110, *status); | ||
2017 | return ret; | ||
2018 | } | ||
2019 | |||
2020 | static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) | ||
2021 | { | ||
2022 | struct av7110* av7110 = fe->dvb->priv; | ||
2023 | |||
2024 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
2025 | if (!ret) | ||
2026 | ret = av7110->fe_diseqc_reset_overload(fe); | ||
2027 | return ret; | ||
2028 | } | ||
2029 | |||
2030 | static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, | ||
2031 | struct dvb_diseqc_master_cmd* cmd) | ||
2032 | { | ||
2033 | struct av7110* av7110 = fe->dvb->priv; | ||
2034 | |||
2035 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
2036 | if (!ret) { | ||
2037 | av7110->saved_master_cmd = *cmd; | ||
2038 | ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); | ||
2039 | } | ||
2040 | return ret; | ||
2041 | } | ||
2042 | |||
2043 | static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | ||
2044 | { | ||
2045 | struct av7110* av7110 = fe->dvb->priv; | ||
2046 | |||
2047 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
2048 | if (!ret) { | ||
2049 | av7110->saved_minicmd = minicmd; | ||
2050 | ret = av7110->fe_diseqc_send_burst(fe, minicmd); | ||
2051 | } | ||
2052 | return ret; | ||
2053 | } | ||
2054 | |||
2055 | static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
2056 | { | ||
2057 | struct av7110* av7110 = fe->dvb->priv; | ||
2058 | |||
2059 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
2060 | if (!ret) { | ||
2061 | av7110->saved_tone = tone; | ||
2062 | ret = av7110->fe_set_tone(fe, tone); | ||
2063 | } | ||
2064 | return ret; | ||
2065 | } | ||
2066 | |||
2067 | static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
2068 | { | ||
2069 | struct av7110* av7110 = fe->dvb->priv; | ||
2070 | |||
2071 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
2072 | if (!ret) { | ||
2073 | av7110->saved_voltage = voltage; | ||
2074 | ret = av7110->fe_set_voltage(fe, voltage); | ||
2075 | } | ||
2076 | return ret; | ||
2077 | } | ||
2078 | |||
2079 | static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd) | ||
2080 | { | ||
2081 | struct av7110* av7110 = fe->dvb->priv; | ||
2082 | |||
2083 | int ret = av7110_fe_lock_fix(av7110, 0); | ||
2084 | if (!ret) | ||
2085 | ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd); | ||
2086 | return ret; | ||
2087 | } | ||
2088 | |||
2089 | static void dvb_s_recover(struct av7110* av7110) | ||
2090 | { | ||
2091 | av7110_fe_init(av7110->fe); | ||
2092 | |||
2093 | av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage); | ||
2094 | if (av7110->saved_master_cmd.msg_len) { | ||
2095 | msleep(20); | ||
2096 | av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd); | ||
2097 | } | ||
2098 | msleep(20); | ||
2099 | av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd); | ||
2100 | msleep(20); | ||
2101 | av7110_fe_set_tone(av7110->fe, av7110->saved_tone); | ||
2102 | |||
2103 | av7110_fe_set_frontend(av7110->fe); | ||
2104 | } | ||
2105 | |||
2106 | static u8 read_pwm(struct av7110* av7110) | ||
2107 | { | ||
2108 | u8 b = 0xff; | ||
2109 | u8 pwm; | ||
2110 | struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, | ||
2111 | { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; | ||
2112 | |||
2113 | if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) | ||
2114 | pwm = 0x48; | ||
2115 | |||
2116 | return pwm; | ||
2117 | } | ||
2118 | |||
2119 | static int frontend_init(struct av7110 *av7110) | ||
2120 | { | ||
2121 | int ret; | ||
2122 | |||
2123 | if (av7110->dev->pci->subsystem_vendor == 0x110a) { | ||
2124 | switch(av7110->dev->pci->subsystem_device) { | ||
2125 | case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) | ||
2126 | av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, | ||
2127 | &av7110->i2c_adap, read_pwm(av7110)); | ||
2128 | if (av7110->fe) { | ||
2129 | av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; | ||
2130 | } | ||
2131 | break; | ||
2132 | } | ||
2133 | |||
2134 | } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) { | ||
2135 | switch(av7110->dev->pci->subsystem_device) { | ||
2136 | case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X | ||
2137 | case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X | ||
2138 | case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE | ||
2139 | |||
2140 | // try the ALPS BSRV2 first of all | ||
2141 | av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap); | ||
2142 | if (av7110->fe) { | ||
2143 | av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; | ||
2144 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2145 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; | ||
2146 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2147 | av7110->recover = dvb_s_recover; | ||
2148 | break; | ||
2149 | } | ||
2150 | |||
2151 | // try the ALPS BSRU6 now | ||
2152 | av7110->fe = dvb_attach(stv0299_attach, &alps_bsru6_config, &av7110->i2c_adap); | ||
2153 | if (av7110->fe) { | ||
2154 | av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | ||
2155 | av7110->fe->tuner_priv = &av7110->i2c_adap; | ||
2156 | |||
2157 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2158 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; | ||
2159 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2160 | av7110->recover = dvb_s_recover; | ||
2161 | break; | ||
2162 | } | ||
2163 | |||
2164 | // Try the grundig 29504-451 | ||
2165 | av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap); | ||
2166 | if (av7110->fe) { | ||
2167 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; | ||
2168 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2169 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; | ||
2170 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2171 | av7110->recover = dvb_s_recover; | ||
2172 | break; | ||
2173 | } | ||
2174 | |||
2175 | /* Try DVB-C cards */ | ||
2176 | switch(av7110->dev->pci->subsystem_device) { | ||
2177 | case 0x0000: | ||
2178 | /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ | ||
2179 | av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, &av7110->i2c_adap, | ||
2180 | read_pwm(av7110)); | ||
2181 | if (av7110->fe) { | ||
2182 | av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; | ||
2183 | } | ||
2184 | break; | ||
2185 | case 0x0003: | ||
2186 | /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ | ||
2187 | av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, | ||
2188 | read_pwm(av7110)); | ||
2189 | if (av7110->fe) { | ||
2190 | av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
2191 | } | ||
2192 | break; | ||
2193 | } | ||
2194 | break; | ||
2195 | |||
2196 | case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X | ||
2197 | // try ALPS TDLB7 first, then Grundig 29504-401 | ||
2198 | av7110->fe = dvb_attach(sp8870_attach, &alps_tdlb7_config, &av7110->i2c_adap); | ||
2199 | if (av7110->fe) { | ||
2200 | av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params; | ||
2201 | break; | ||
2202 | } | ||
2203 | /* fall-thru */ | ||
2204 | |||
2205 | case 0x0008: // Hauppauge/TT DVB-T | ||
2206 | // Grundig 29504-401 | ||
2207 | av7110->fe = dvb_attach(l64781_attach, &grundig_29504_401_config, &av7110->i2c_adap); | ||
2208 | if (av7110->fe) | ||
2209 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; | ||
2210 | break; | ||
2211 | |||
2212 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X | ||
2213 | |||
2214 | av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); | ||
2215 | if (av7110->fe) { | ||
2216 | av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
2217 | } | ||
2218 | break; | ||
2219 | |||
2220 | case 0x0004: // Galaxis DVB-S rev1.3 | ||
2221 | /* ALPS BSRV2 */ | ||
2222 | av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap); | ||
2223 | if (av7110->fe) { | ||
2224 | av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; | ||
2225 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2226 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; | ||
2227 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2228 | av7110->recover = dvb_s_recover; | ||
2229 | } | ||
2230 | break; | ||
2231 | |||
2232 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ | ||
2233 | /* Grundig 29504-451 */ | ||
2234 | av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap); | ||
2235 | if (av7110->fe) { | ||
2236 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; | ||
2237 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2238 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; | ||
2239 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2240 | av7110->recover = dvb_s_recover; | ||
2241 | } | ||
2242 | break; | ||
2243 | |||
2244 | case 0x000A: // Hauppauge/TT Nexus-CA rev1.X | ||
2245 | |||
2246 | av7110->fe = dvb_attach(stv0297_attach, &nexusca_stv0297_config, &av7110->i2c_adap); | ||
2247 | if (av7110->fe) { | ||
2248 | av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params; | ||
2249 | |||
2250 | /* set TDA9819 into DVB mode */ | ||
2251 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) | ||
2252 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) | ||
2253 | |||
2254 | /* tuner on this needs a slower i2c bus speed */ | ||
2255 | av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | ||
2256 | break; | ||
2257 | } | ||
2258 | break; | ||
2259 | |||
2260 | case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ | ||
2261 | /* ALPS BSBE1 */ | ||
2262 | av7110->fe = dvb_attach(stv0299_attach, &alps_bsbe1_config, &av7110->i2c_adap); | ||
2263 | if (av7110->fe) { | ||
2264 | av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; | ||
2265 | av7110->fe->tuner_priv = &av7110->i2c_adap; | ||
2266 | |||
2267 | if (dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0) == NULL) { | ||
2268 | printk("dvb-ttpci: LNBP21 not found!\n"); | ||
2269 | if (av7110->fe->ops.release) | ||
2270 | av7110->fe->ops.release(av7110->fe); | ||
2271 | av7110->fe = NULL; | ||
2272 | } else { | ||
2273 | av7110->fe->ops.dishnetwork_send_legacy_command = NULL; | ||
2274 | av7110->recover = dvb_s_recover; | ||
2275 | } | ||
2276 | } | ||
2277 | break; | ||
2278 | } | ||
2279 | } | ||
2280 | |||
2281 | if (!av7110->fe) { | ||
2282 | /* FIXME: propagate the failure code from the lower layers */ | ||
2283 | ret = -ENOMEM; | ||
2284 | printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", | ||
2285 | av7110->dev->pci->vendor, | ||
2286 | av7110->dev->pci->device, | ||
2287 | av7110->dev->pci->subsystem_vendor, | ||
2288 | av7110->dev->pci->subsystem_device); | ||
2289 | } else { | ||
2290 | FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init); | ||
2291 | FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status); | ||
2292 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); | ||
2293 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); | ||
2294 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); | ||
2295 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone); | ||
2296 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage); | ||
2297 | FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); | ||
2298 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); | ||
2299 | |||
2300 | ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); | ||
2301 | if (ret < 0) { | ||
2302 | printk("av7110: Frontend registration failed!\n"); | ||
2303 | dvb_frontend_detach(av7110->fe); | ||
2304 | av7110->fe = NULL; | ||
2305 | } | ||
2306 | } | ||
2307 | return ret; | ||
2308 | } | ||
2309 | |||
2310 | /* Budgetpatch note: | ||
2311 | * Original hardware design by Roberto Deza: | ||
2312 | * There is a DVB_Wiki at | ||
2313 | * http://www.linuxtv.org/ | ||
2314 | * | ||
2315 | * New software triggering design by Emard that works on | ||
2316 | * original Roberto Deza's hardware: | ||
2317 | * | ||
2318 | * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin. | ||
2319 | * GPIO3 is in budget-patch hardware connectd to port B VSYNC | ||
2320 | * HS is an internal event of 7146, accessible with RPS | ||
2321 | * and temporarily raised high every n lines | ||
2322 | * (n in defined in the RPS_THRESH1 counter threshold) | ||
2323 | * I think HS is raised high on the beginning of the n-th line | ||
2324 | * and remains high until this n-th line that triggered | ||
2325 | * it is completely received. When the receiption of n-th line | ||
2326 | * ends, HS is lowered. | ||
2327 | * | ||
2328 | * To transmit data over DMA, 7146 needs changing state at | ||
2329 | * port B VSYNC pin. Any changing of port B VSYNC will | ||
2330 | * cause some DMA data transfer, with more or less packets loss. | ||
2331 | * It depends on the phase and frequency of VSYNC and | ||
2332 | * the way of 7146 is instructed to trigger on port B (defined | ||
2333 | * in DD1_INIT register, 3rd nibble from the right valid | ||
2334 | * numbers are 0-7, see datasheet) | ||
2335 | * | ||
2336 | * The correct triggering can minimize packet loss, | ||
2337 | * dvbtraffic should give this stable bandwidths: | ||
2338 | * 22k transponder = 33814 kbit/s | ||
2339 | * 27.5k transponder = 38045 kbit/s | ||
2340 | * by experiment it is found that the best results | ||
2341 | * (stable bandwidths and almost no packet loss) | ||
2342 | * are obtained using DD1_INIT triggering number 2 | ||
2343 | * (Va at rising edge of VS Fa = HS x VS-failing forced toggle) | ||
2344 | * and a VSYNC phase that occurs in the middle of DMA transfer | ||
2345 | * (about byte 188*512=96256 in the DMA window). | ||
2346 | * | ||
2347 | * Phase of HS is still not clear to me how to control, | ||
2348 | * It just happens to be so. It can be seen if one enables | ||
2349 | * RPS_IRQ and print Event Counter 1 in vpeirq(). Every | ||
2350 | * time RPS_INTERRUPT is called, the Event Counter 1 will | ||
2351 | * increment. That's how the 7146 is programmed to do event | ||
2352 | * counting in this budget-patch.c | ||
2353 | * I *think* HPS setting has something to do with the phase | ||
2354 | * of HS but I can't be 100% sure in that. | ||
2355 | * | ||
2356 | * hardware debug note: a working budget card (including budget patch) | ||
2357 | * with vpeirq() interrupt setup in mode "0x90" (every 64K) will | ||
2358 | * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes | ||
2359 | * and that means 3*25=75 Hz of interrupt freqency, as seen by | ||
2360 | * watch cat /proc/interrupts | ||
2361 | * | ||
2362 | * If this frequency is 3x lower (and data received in the DMA | ||
2363 | * buffer don't start with 0x47, but in the middle of packets, | ||
2364 | * whose lengths appear to be like 188 292 188 104 etc. | ||
2365 | * this means VSYNC line is not connected in the hardware. | ||
2366 | * (check soldering pcb and pins) | ||
2367 | * The same behaviour of missing VSYNC can be duplicated on budget | ||
2368 | * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. | ||
2369 | */ | ||
2370 | static int __devinit av7110_attach(struct saa7146_dev* dev, | ||
2371 | struct saa7146_pci_extension_data *pci_ext) | ||
2372 | { | ||
2373 | const int length = TS_WIDTH * TS_HEIGHT; | ||
2374 | struct pci_dev *pdev = dev->pci; | ||
2375 | struct av7110 *av7110; | ||
2376 | struct task_struct *thread; | ||
2377 | int ret, count = 0; | ||
2378 | |||
2379 | dprintk(4, "dev: %p\n", dev); | ||
2380 | |||
2381 | /* Set RPS_IRQ to 1 to track rps1 activity. | ||
2382 | * Enabling this won't send any interrupt to PC CPU. | ||
2383 | */ | ||
2384 | #define RPS_IRQ 0 | ||
2385 | |||
2386 | if (budgetpatch == 1) { | ||
2387 | budgetpatch = 0; | ||
2388 | /* autodetect the presence of budget patch | ||
2389 | * this only works if saa7146 has been recently | ||
2390 | * reset with with MASK_31 to MC1 | ||
2391 | * | ||
2392 | * will wait for VBI_B event (vertical blank at port B) | ||
2393 | * and will reset GPIO3 after VBI_B is detected. | ||
2394 | * (GPIO3 should be raised high by CPU to | ||
2395 | * test if GPIO3 will generate vertical blank signal | ||
2396 | * in budget patch GPIO3 is connected to VSYNC_B | ||
2397 | */ | ||
2398 | |||
2399 | /* RESET SAA7146 */ | ||
2400 | saa7146_write(dev, MC1, MASK_31); | ||
2401 | /* autodetection success seems to be time-dependend after reset */ | ||
2402 | |||
2403 | /* Fix VSYNC level */ | ||
2404 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
2405 | /* set vsync_b triggering */ | ||
2406 | saa7146_write(dev, DD1_STREAM_B, 0); | ||
2407 | /* port B VSYNC at rising edge */ | ||
2408 | saa7146_write(dev, DD1_INIT, 0x00000200); | ||
2409 | saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI | ||
2410 | saa7146_write(dev, MC2, | ||
2411 | 1 * (MASK_08 | MASK_24) | // BRS control | ||
2412 | 0 * (MASK_09 | MASK_25) | // a | ||
2413 | 1 * (MASK_10 | MASK_26) | // b | ||
2414 | 0 * (MASK_06 | MASK_22) | // HPS_CTRL1 | ||
2415 | 0 * (MASK_05 | MASK_21) | // HPS_CTRL2 | ||
2416 | 0 * (MASK_01 | MASK_15) // DEBI | ||
2417 | ); | ||
2418 | |||
2419 | /* start writing RPS1 code from beginning */ | ||
2420 | count = 0; | ||
2421 | /* Disable RPS1 */ | ||
2422 | saa7146_write(dev, MC1, MASK_29); | ||
2423 | /* RPS1 timeout disable */ | ||
2424 | saa7146_write(dev, RPS_TOV1, 0); | ||
2425 | WRITE_RPS1(CMD_PAUSE | EVT_VBI_B); | ||
2426 | WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); | ||
2427 | WRITE_RPS1(GPIO3_MSK); | ||
2428 | WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); | ||
2429 | #if RPS_IRQ | ||
2430 | /* issue RPS1 interrupt to increment counter */ | ||
2431 | WRITE_RPS1(CMD_INTERRUPT); | ||
2432 | #endif | ||
2433 | WRITE_RPS1(CMD_STOP); | ||
2434 | /* Jump to begin of RPS program as safety measure (p37) */ | ||
2435 | WRITE_RPS1(CMD_JUMP); | ||
2436 | WRITE_RPS1(dev->d_rps1.dma_handle); | ||
2437 | |||
2438 | #if RPS_IRQ | ||
2439 | /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) | ||
2440 | * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled | ||
2441 | * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called | ||
2442 | */ | ||
2443 | saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); | ||
2444 | /* set event counter 1 threshold to maximum allowed value (rEC p55) */ | ||
2445 | saa7146_write(dev, ECT1R, 0x3fff ); | ||
2446 | #endif | ||
2447 | /* Set RPS1 Address register to point to RPS code (r108 p42) */ | ||
2448 | saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); | ||
2449 | /* Enable RPS1, (rFC p33) */ | ||
2450 | saa7146_write(dev, MC1, (MASK_13 | MASK_29 )); | ||
2451 | |||
2452 | mdelay(10); | ||
2453 | /* now send VSYNC_B to rps1 by rising GPIO3 */ | ||
2454 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); | ||
2455 | mdelay(10); | ||
2456 | /* if rps1 responded by lowering the GPIO3, | ||
2457 | * then we have budgetpatch hardware | ||
2458 | */ | ||
2459 | if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) { | ||
2460 | budgetpatch = 1; | ||
2461 | printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n"); | ||
2462 | } | ||
2463 | /* Disable RPS1 */ | ||
2464 | saa7146_write(dev, MC1, ( MASK_29 )); | ||
2465 | #if RPS_IRQ | ||
2466 | printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff ); | ||
2467 | #endif | ||
2468 | } | ||
2469 | |||
2470 | /* prepare the av7110 device struct */ | ||
2471 | av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL); | ||
2472 | if (!av7110) { | ||
2473 | dprintk(1, "out of memory\n"); | ||
2474 | return -ENOMEM; | ||
2475 | } | ||
2476 | |||
2477 | av7110->card_name = (char*) pci_ext->ext_priv; | ||
2478 | av7110->dev = dev; | ||
2479 | dev->ext_priv = av7110; | ||
2480 | |||
2481 | ret = get_firmware(av7110); | ||
2482 | if (ret < 0) | ||
2483 | goto err_kfree_0; | ||
2484 | |||
2485 | ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, | ||
2486 | THIS_MODULE, &dev->pci->dev, adapter_nr); | ||
2487 | if (ret < 0) | ||
2488 | goto err_put_firmware_1; | ||
2489 | |||
2490 | /* the Siemens DVB needs this if you want to have the i2c chips | ||
2491 | get recognized before the main driver is fully loaded */ | ||
2492 | saa7146_write(dev, GPIO_CTRL, 0x500000); | ||
2493 | |||
2494 | strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); | ||
2495 | |||
2496 | saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ | ||
2497 | |||
2498 | ret = i2c_add_adapter(&av7110->i2c_adap); | ||
2499 | if (ret < 0) | ||
2500 | goto err_dvb_unregister_adapter_2; | ||
2501 | |||
2502 | ttpci_eeprom_parse_mac(&av7110->i2c_adap, | ||
2503 | av7110->dvb_adapter.proposed_mac); | ||
2504 | ret = -ENOMEM; | ||
2505 | |||
2506 | /* full-ts mod? */ | ||
2507 | if (full_ts) | ||
2508 | av7110->full_ts = true; | ||
2509 | |||
2510 | /* check for full-ts flag in eeprom */ | ||
2511 | if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 1) == 0x45) { | ||
2512 | u8 flags = i2c_readreg(av7110, 0xaa, 2); | ||
2513 | if (flags != 0xff && (flags & 0x01)) | ||
2514 | av7110->full_ts = true; | ||
2515 | } | ||
2516 | |||
2517 | if (av7110->full_ts) { | ||
2518 | printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 port B\n"); | ||
2519 | spin_lock_init(&av7110->feedlock1); | ||
2520 | av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length, | ||
2521 | &av7110->pt); | ||
2522 | if (!av7110->grabbing) | ||
2523 | goto err_i2c_del_3; | ||
2524 | |||
2525 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | ||
2526 | saa7146_write(dev, MC2, (MASK_10 | MASK_26)); | ||
2527 | |||
2528 | saa7146_write(dev, DD1_INIT, 0x00000600); | ||
2529 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
2530 | |||
2531 | saa7146_write(dev, BRS_CTRL, 0x60000000); | ||
2532 | saa7146_write(dev, MC2, MASK_08 | MASK_24); | ||
2533 | |||
2534 | /* dma3 */ | ||
2535 | saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000)); | ||
2536 | saa7146_write(dev, BASE_ODD3, 0); | ||
2537 | saa7146_write(dev, BASE_EVEN3, 0); | ||
2538 | saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT); | ||
2539 | saa7146_write(dev, PITCH3, TS_WIDTH); | ||
2540 | saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90); | ||
2541 | saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH); | ||
2542 | saa7146_write(dev, MC2, MASK_04 | MASK_20); | ||
2543 | |||
2544 | tasklet_init(&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); | ||
2545 | |||
2546 | } else if (budgetpatch) { | ||
2547 | spin_lock_init(&av7110->feedlock1); | ||
2548 | av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length, | ||
2549 | &av7110->pt); | ||
2550 | if (!av7110->grabbing) | ||
2551 | goto err_i2c_del_3; | ||
2552 | |||
2553 | saa7146_write(dev, PCI_BT_V1, 0x1c1f101f); | ||
2554 | saa7146_write(dev, BCS_CTRL, 0x80400040); | ||
2555 | /* set dd1 stream a & b */ | ||
2556 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | ||
2557 | saa7146_write(dev, DD1_INIT, 0x03000200); | ||
2558 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
2559 | saa7146_write(dev, BRS_CTRL, 0x60000000); | ||
2560 | saa7146_write(dev, BASE_ODD3, 0); | ||
2561 | saa7146_write(dev, BASE_EVEN3, 0); | ||
2562 | saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT); | ||
2563 | saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90); | ||
2564 | |||
2565 | saa7146_write(dev, PITCH3, TS_WIDTH); | ||
2566 | saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH); | ||
2567 | |||
2568 | /* upload all */ | ||
2569 | saa7146_write(dev, MC2, 0x077c077c); | ||
2570 | saa7146_write(dev, GPIO_CTRL, 0x000000); | ||
2571 | #if RPS_IRQ | ||
2572 | /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) | ||
2573 | * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled | ||
2574 | * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called | ||
2575 | */ | ||
2576 | saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); | ||
2577 | /* set event counter 1 threshold to maximum allowed value (rEC p55) */ | ||
2578 | saa7146_write(dev, ECT1R, 0x3fff ); | ||
2579 | #endif | ||
2580 | /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */ | ||
2581 | count = 0; | ||
2582 | |||
2583 | /* Wait Source Line Counter Threshold (p36) */ | ||
2584 | WRITE_RPS1(CMD_PAUSE | EVT_HS); | ||
2585 | /* Set GPIO3=1 (p42) */ | ||
2586 | WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); | ||
2587 | WRITE_RPS1(GPIO3_MSK); | ||
2588 | WRITE_RPS1(SAA7146_GPIO_OUTHI<<24); | ||
2589 | #if RPS_IRQ | ||
2590 | /* issue RPS1 interrupt */ | ||
2591 | WRITE_RPS1(CMD_INTERRUPT); | ||
2592 | #endif | ||
2593 | /* Wait reset Source Line Counter Threshold (p36) */ | ||
2594 | WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS); | ||
2595 | /* Set GPIO3=0 (p42) */ | ||
2596 | WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); | ||
2597 | WRITE_RPS1(GPIO3_MSK); | ||
2598 | WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); | ||
2599 | #if RPS_IRQ | ||
2600 | /* issue RPS1 interrupt */ | ||
2601 | WRITE_RPS1(CMD_INTERRUPT); | ||
2602 | #endif | ||
2603 | /* Jump to begin of RPS program (p37) */ | ||
2604 | WRITE_RPS1(CMD_JUMP); | ||
2605 | WRITE_RPS1(dev->d_rps1.dma_handle); | ||
2606 | |||
2607 | /* Fix VSYNC level */ | ||
2608 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
2609 | /* Set RPS1 Address register to point to RPS code (r108 p42) */ | ||
2610 | saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); | ||
2611 | /* Set Source Line Counter Threshold, using BRS (rCC p43) | ||
2612 | * It generates HS event every TS_HEIGHT lines | ||
2613 | * this is related to TS_WIDTH set in register | ||
2614 | * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits | ||
2615 | * are set to TS_WIDTH bytes (TS_WIDTH=2*188), | ||
2616 | * then RPS_THRESH1 should be set to trigger | ||
2617 | * every TS_HEIGHT (512) lines. | ||
2618 | */ | ||
2619 | saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 ); | ||
2620 | |||
2621 | /* Enable RPS1 (rFC p33) */ | ||
2622 | saa7146_write(dev, MC1, (MASK_13 | MASK_29)); | ||
2623 | |||
2624 | /* end of budgetpatch register initialization */ | ||
2625 | tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); | ||
2626 | } else { | ||
2627 | saa7146_write(dev, PCI_BT_V1, 0x1c00101f); | ||
2628 | saa7146_write(dev, BCS_CTRL, 0x80400040); | ||
2629 | |||
2630 | /* set dd1 stream a & b */ | ||
2631 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | ||
2632 | saa7146_write(dev, DD1_INIT, 0x03000000); | ||
2633 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
2634 | |||
2635 | /* upload all */ | ||
2636 | saa7146_write(dev, MC2, 0x077c077c); | ||
2637 | saa7146_write(dev, GPIO_CTRL, 0x000000); | ||
2638 | } | ||
2639 | |||
2640 | tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); | ||
2641 | tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); | ||
2642 | |||
2643 | mutex_init(&av7110->pid_mutex); | ||
2644 | |||
2645 | /* locks for data transfers from/to AV7110 */ | ||
2646 | spin_lock_init(&av7110->debilock); | ||
2647 | mutex_init(&av7110->dcomlock); | ||
2648 | av7110->debitype = -1; | ||
2649 | |||
2650 | /* default OSD window */ | ||
2651 | av7110->osdwin = 1; | ||
2652 | mutex_init(&av7110->osd_mutex); | ||
2653 | |||
2654 | /* TV standard */ | ||
2655 | av7110->vidmode = tv_standard == 1 ? AV7110_VIDEO_MODE_NTSC | ||
2656 | : AV7110_VIDEO_MODE_PAL; | ||
2657 | |||
2658 | /* ARM "watchdog" */ | ||
2659 | init_waitqueue_head(&av7110->arm_wait); | ||
2660 | av7110->arm_thread = NULL; | ||
2661 | |||
2662 | /* allocate and init buffers */ | ||
2663 | av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus); | ||
2664 | if (!av7110->debi_virt) | ||
2665 | goto err_saa71466_vfree_4; | ||
2666 | |||
2667 | |||
2668 | av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS); | ||
2669 | if (!av7110->iobuf) | ||
2670 | goto err_pci_free_5; | ||
2671 | |||
2672 | ret = av7110_av_init(av7110); | ||
2673 | if (ret < 0) | ||
2674 | goto err_iobuf_vfree_6; | ||
2675 | |||
2676 | /* init BMP buffer */ | ||
2677 | av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN; | ||
2678 | init_waitqueue_head(&av7110->bmpq); | ||
2679 | |||
2680 | ret = av7110_ca_init(av7110); | ||
2681 | if (ret < 0) | ||
2682 | goto err_av7110_av_exit_7; | ||
2683 | |||
2684 | /* load firmware into AV7110 cards */ | ||
2685 | ret = av7110_bootarm(av7110); | ||
2686 | if (ret < 0) | ||
2687 | goto err_av7110_ca_exit_8; | ||
2688 | |||
2689 | ret = av7110_firmversion(av7110); | ||
2690 | if (ret < 0) | ||
2691 | goto err_stop_arm_9; | ||
2692 | |||
2693 | if (FW_VERSION(av7110->arm_app)<0x2501) | ||
2694 | printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " | ||
2695 | "System might be unstable!\n", FW_VERSION(av7110->arm_app)); | ||
2696 | |||
2697 | thread = kthread_run(arm_thread, (void *) av7110, "arm_mon"); | ||
2698 | if (IS_ERR(thread)) { | ||
2699 | ret = PTR_ERR(thread); | ||
2700 | goto err_stop_arm_9; | ||
2701 | } | ||
2702 | av7110->arm_thread = thread; | ||
2703 | |||
2704 | /* set initial volume in mixer struct */ | ||
2705 | av7110->mixer.volume_left = volume; | ||
2706 | av7110->mixer.volume_right = volume; | ||
2707 | |||
2708 | ret = av7110_register(av7110); | ||
2709 | if (ret < 0) | ||
2710 | goto err_arm_thread_stop_10; | ||
2711 | |||
2712 | init_av7110_av(av7110); | ||
2713 | |||
2714 | /* special case DVB-C: these cards have an analog tuner | ||
2715 | plus need some special handling, so we have separate | ||
2716 | saa7146_ext_vv data for these... */ | ||
2717 | ret = av7110_init_v4l(av7110); | ||
2718 | if (ret < 0) | ||
2719 | goto err_av7110_unregister_11; | ||
2720 | |||
2721 | av7110->dvb_adapter.priv = av7110; | ||
2722 | ret = frontend_init(av7110); | ||
2723 | if (ret < 0) | ||
2724 | goto err_av7110_exit_v4l_12; | ||
2725 | |||
2726 | #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) | ||
2727 | av7110_ir_init(av7110); | ||
2728 | #endif | ||
2729 | printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num); | ||
2730 | av7110_num++; | ||
2731 | out: | ||
2732 | return ret; | ||
2733 | |||
2734 | err_av7110_exit_v4l_12: | ||
2735 | av7110_exit_v4l(av7110); | ||
2736 | err_av7110_unregister_11: | ||
2737 | dvb_unregister(av7110); | ||
2738 | err_arm_thread_stop_10: | ||
2739 | av7110_arm_sync(av7110); | ||
2740 | err_stop_arm_9: | ||
2741 | /* Nothing to do. Rejoice. */ | ||
2742 | err_av7110_ca_exit_8: | ||
2743 | av7110_ca_exit(av7110); | ||
2744 | err_av7110_av_exit_7: | ||
2745 | av7110_av_exit(av7110); | ||
2746 | err_iobuf_vfree_6: | ||
2747 | vfree(av7110->iobuf); | ||
2748 | err_pci_free_5: | ||
2749 | pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus); | ||
2750 | err_saa71466_vfree_4: | ||
2751 | if (av7110->grabbing) | ||
2752 | saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt); | ||
2753 | err_i2c_del_3: | ||
2754 | i2c_del_adapter(&av7110->i2c_adap); | ||
2755 | err_dvb_unregister_adapter_2: | ||
2756 | dvb_unregister_adapter(&av7110->dvb_adapter); | ||
2757 | err_put_firmware_1: | ||
2758 | put_firmware(av7110); | ||
2759 | err_kfree_0: | ||
2760 | kfree(av7110); | ||
2761 | goto out; | ||
2762 | } | ||
2763 | |||
2764 | static int __devexit av7110_detach(struct saa7146_dev* saa) | ||
2765 | { | ||
2766 | struct av7110 *av7110 = saa->ext_priv; | ||
2767 | dprintk(4, "%p\n", av7110); | ||
2768 | |||
2769 | #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) | ||
2770 | av7110_ir_exit(av7110); | ||
2771 | #endif | ||
2772 | if (budgetpatch || av7110->full_ts) { | ||
2773 | if (budgetpatch) { | ||
2774 | /* Disable RPS1 */ | ||
2775 | saa7146_write(saa, MC1, MASK_29); | ||
2776 | /* VSYNC LOW (inactive) */ | ||
2777 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
2778 | } | ||
2779 | saa7146_write(saa, MC1, MASK_20); /* DMA3 off */ | ||
2780 | SAA7146_IER_DISABLE(saa, MASK_10); | ||
2781 | SAA7146_ISR_CLEAR(saa, MASK_10); | ||
2782 | msleep(50); | ||
2783 | tasklet_kill(&av7110->vpe_tasklet); | ||
2784 | saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt); | ||
2785 | } | ||
2786 | av7110_exit_v4l(av7110); | ||
2787 | |||
2788 | av7110_arm_sync(av7110); | ||
2789 | |||
2790 | tasklet_kill(&av7110->debi_tasklet); | ||
2791 | tasklet_kill(&av7110->gpio_tasklet); | ||
2792 | |||
2793 | dvb_unregister(av7110); | ||
2794 | |||
2795 | SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03); | ||
2796 | SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03); | ||
2797 | |||
2798 | av7110_ca_exit(av7110); | ||
2799 | av7110_av_exit(av7110); | ||
2800 | |||
2801 | vfree(av7110->iobuf); | ||
2802 | pci_free_consistent(saa->pci, 8192, av7110->debi_virt, | ||
2803 | av7110->debi_bus); | ||
2804 | |||
2805 | i2c_del_adapter(&av7110->i2c_adap); | ||
2806 | |||
2807 | dvb_unregister_adapter (&av7110->dvb_adapter); | ||
2808 | |||
2809 | av7110_num--; | ||
2810 | |||
2811 | put_firmware(av7110); | ||
2812 | |||
2813 | kfree(av7110); | ||
2814 | |||
2815 | saa->ext_priv = NULL; | ||
2816 | |||
2817 | return 0; | ||
2818 | } | ||
2819 | |||
2820 | |||
2821 | static void av7110_irq(struct saa7146_dev* dev, u32 *isr) | ||
2822 | { | ||
2823 | struct av7110 *av7110 = dev->ext_priv; | ||
2824 | |||
2825 | //print_time("av7110_irq"); | ||
2826 | |||
2827 | /* Note: Don't try to handle the DEBI error irq (MASK_18), in | ||
2828 | * intel mode the timeout is asserted all the time... | ||
2829 | */ | ||
2830 | |||
2831 | if (*isr & MASK_19) { | ||
2832 | //printk("av7110_irq: DEBI\n"); | ||
2833 | /* Note 1: The DEBI irq is level triggered: We must enable it | ||
2834 | * only after we started a DMA xfer, and disable it here | ||
2835 | * immediately, or it will be signalled all the time while | ||
2836 | * DEBI is idle. | ||
2837 | * Note 2: You would think that an irq which is masked is | ||
2838 | * not signalled by the hardware. Not so for the SAA7146: | ||
2839 | * An irq is signalled as long as the corresponding bit | ||
2840 | * in the ISR is set, and disabling irqs just prevents the | ||
2841 | * hardware from setting the ISR bit. This means a) that we | ||
2842 | * must clear the ISR *after* disabling the irq (which is why | ||
2843 | * we must do it here even though saa7146_core did it already), | ||
2844 | * and b) that if we were to disable an edge triggered irq | ||
2845 | * (like the gpio irqs sadly are) temporarily we would likely | ||
2846 | * loose some. This sucks :-( | ||
2847 | */ | ||
2848 | SAA7146_IER_DISABLE(av7110->dev, MASK_19); | ||
2849 | SAA7146_ISR_CLEAR(av7110->dev, MASK_19); | ||
2850 | tasklet_schedule(&av7110->debi_tasklet); | ||
2851 | } | ||
2852 | |||
2853 | if (*isr & MASK_03) { | ||
2854 | //printk("av7110_irq: GPIO\n"); | ||
2855 | tasklet_schedule(&av7110->gpio_tasklet); | ||
2856 | } | ||
2857 | |||
2858 | if (*isr & MASK_10) | ||
2859 | tasklet_schedule(&av7110->vpe_tasklet); | ||
2860 | } | ||
2861 | |||
2862 | |||
2863 | static struct saa7146_extension av7110_extension_driver; | ||
2864 | |||
2865 | #define MAKE_AV7110_INFO(x_var,x_name) \ | ||
2866 | static struct saa7146_pci_extension_data x_var = { \ | ||
2867 | .ext_priv = x_name, \ | ||
2868 | .ext = &av7110_extension_driver } | ||
2869 | |||
2870 | MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C"); | ||
2871 | MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X"); | ||
2872 | MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X"); | ||
2873 | MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X"); | ||
2874 | MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X"); | ||
2875 | MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3"); | ||
2876 | MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE"); | ||
2877 | MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); | ||
2878 | MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); | ||
2879 | MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); | ||
2880 | MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3"); | ||
2881 | |||
2882 | static struct pci_device_id pci_tbl[] = { | ||
2883 | MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), | ||
2884 | MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000), | ||
2885 | MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), | ||
2886 | MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), | ||
2887 | MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), | ||
2888 | MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004), | ||
2889 | MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), | ||
2890 | MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), | ||
2891 | MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), | ||
2892 | MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), | ||
2893 | MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), | ||
2894 | |||
2895 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 | ||
2896 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v???? | ||
2897 | |||
2898 | { | ||
2899 | .vendor = 0, | ||
2900 | } | ||
2901 | }; | ||
2902 | |||
2903 | MODULE_DEVICE_TABLE(pci, pci_tbl); | ||
2904 | |||
2905 | |||
2906 | static struct saa7146_extension av7110_extension_driver = { | ||
2907 | .name = "av7110", | ||
2908 | .flags = SAA7146_USE_I2C_IRQ, | ||
2909 | |||
2910 | .module = THIS_MODULE, | ||
2911 | .pci_tbl = &pci_tbl[0], | ||
2912 | .attach = av7110_attach, | ||
2913 | .detach = __devexit_p(av7110_detach), | ||
2914 | |||
2915 | .irq_mask = MASK_19 | MASK_03 | MASK_10, | ||
2916 | .irq_func = av7110_irq, | ||
2917 | }; | ||
2918 | |||
2919 | |||
2920 | static int __init av7110_init(void) | ||
2921 | { | ||
2922 | int retval; | ||
2923 | retval = saa7146_register_extension(&av7110_extension_driver); | ||
2924 | return retval; | ||
2925 | } | ||
2926 | |||
2927 | |||
2928 | static void __exit av7110_exit(void) | ||
2929 | { | ||
2930 | saa7146_unregister_extension(&av7110_extension_driver); | ||
2931 | } | ||
2932 | |||
2933 | module_init(av7110_init); | ||
2934 | module_exit(av7110_exit); | ||
2935 | |||
2936 | MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " | ||
2937 | "Siemens, Technotrend, Hauppauge"); | ||
2938 | MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); | ||
2939 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h deleted file mode 100644 index 88b3b2d6cc0e..000000000000 --- a/drivers/media/dvb/ttpci/av7110.h +++ /dev/null | |||
@@ -1,314 +0,0 @@ | |||
1 | #ifndef _AV7110_H_ | ||
2 | #define _AV7110_H_ | ||
3 | |||
4 | #include <linux/interrupt.h> | ||
5 | #include <linux/socket.h> | ||
6 | #include <linux/netdevice.h> | ||
7 | #include <linux/i2c.h> | ||
8 | #include <linux/input.h> | ||
9 | |||
10 | #include <linux/dvb/video.h> | ||
11 | #include <linux/dvb/audio.h> | ||
12 | #include <linux/dvb/dmx.h> | ||
13 | #include <linux/dvb/ca.h> | ||
14 | #include <linux/dvb/osd.h> | ||
15 | #include <linux/dvb/net.h> | ||
16 | #include <linux/mutex.h> | ||
17 | |||
18 | #include "dvbdev.h" | ||
19 | #include "demux.h" | ||
20 | #include "dvb_demux.h" | ||
21 | #include "dmxdev.h" | ||
22 | #include "dvb_filter.h" | ||
23 | #include "dvb_net.h" | ||
24 | #include "dvb_ringbuffer.h" | ||
25 | #include "dvb_frontend.h" | ||
26 | #include "ves1820.h" | ||
27 | #include "ves1x93.h" | ||
28 | #include "stv0299.h" | ||
29 | #include "tda8083.h" | ||
30 | #include "sp8870.h" | ||
31 | #include "stv0297.h" | ||
32 | #include "l64781.h" | ||
33 | |||
34 | #include <media/saa7146_vv.h> | ||
35 | |||
36 | |||
37 | #define ANALOG_TUNER_VES1820 1 | ||
38 | #define ANALOG_TUNER_STV0297 2 | ||
39 | |||
40 | extern int av7110_debug; | ||
41 | |||
42 | #define dprintk(level,args...) \ | ||
43 | do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __func__); printk(args); } } while (0) | ||
44 | |||
45 | #define MAXFILT 32 | ||
46 | |||
47 | enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM}; | ||
48 | |||
49 | enum av7110_video_mode { | ||
50 | AV7110_VIDEO_MODE_PAL = 0, | ||
51 | AV7110_VIDEO_MODE_NTSC = 1 | ||
52 | }; | ||
53 | |||
54 | struct av7110_p2t { | ||
55 | u8 pes[TS_SIZE]; | ||
56 | u8 counter; | ||
57 | long int pos; | ||
58 | int frags; | ||
59 | struct dvb_demux_feed *feed; | ||
60 | }; | ||
61 | |||
62 | /* video MPEG decoder events: */ | ||
63 | /* (code copied from dvb_frontend.c, should maybe be factored out...) */ | ||
64 | #define MAX_VIDEO_EVENT 8 | ||
65 | struct dvb_video_events { | ||
66 | struct video_event events[MAX_VIDEO_EVENT]; | ||
67 | int eventw; | ||
68 | int eventr; | ||
69 | int overflow; | ||
70 | wait_queue_head_t wait_queue; | ||
71 | spinlock_t lock; | ||
72 | }; | ||
73 | |||
74 | |||
75 | struct av7110; | ||
76 | |||
77 | /* infrared remote control */ | ||
78 | struct infrared { | ||
79 | u16 key_map[256]; | ||
80 | struct input_dev *input_dev; | ||
81 | char input_phys[32]; | ||
82 | struct timer_list keyup_timer; | ||
83 | struct tasklet_struct ir_tasklet; | ||
84 | void (*ir_handler)(struct av7110 *av7110, u32 ircom); | ||
85 | u32 ir_command; | ||
86 | u32 ir_config; | ||
87 | u32 device_mask; | ||
88 | u8 protocol; | ||
89 | u8 inversion; | ||
90 | u16 last_key; | ||
91 | u16 last_toggle; | ||
92 | u8 delay_timer_finished; | ||
93 | }; | ||
94 | |||
95 | |||
96 | /* place to store all the necessary device information */ | ||
97 | struct av7110 { | ||
98 | |||
99 | /* devices */ | ||
100 | |||
101 | struct dvb_device dvb_dev; | ||
102 | struct dvb_net dvb_net; | ||
103 | |||
104 | struct video_device *v4l_dev; | ||
105 | struct video_device *vbi_dev; | ||
106 | |||
107 | struct saa7146_dev *dev; | ||
108 | |||
109 | struct i2c_adapter i2c_adap; | ||
110 | |||
111 | char *card_name; | ||
112 | |||
113 | /* support for analog module of dvb-c */ | ||
114 | int analog_tuner_flags; | ||
115 | int current_input; | ||
116 | u32 current_freq; | ||
117 | |||
118 | struct tasklet_struct debi_tasklet; | ||
119 | struct tasklet_struct gpio_tasklet; | ||
120 | |||
121 | int adac_type; /* audio DAC type */ | ||
122 | #define DVB_ADAC_TI 0 | ||
123 | #define DVB_ADAC_CRYSTAL 1 | ||
124 | #define DVB_ADAC_MSP34x0 2 | ||
125 | #define DVB_ADAC_MSP34x5 3 | ||
126 | #define DVB_ADAC_NONE -1 | ||
127 | |||
128 | |||
129 | /* buffers */ | ||
130 | |||
131 | void *iobuf; /* memory for all buffers */ | ||
132 | struct dvb_ringbuffer avout; /* buffer for video or A/V mux */ | ||
133 | #define AVOUTLEN (128*1024) | ||
134 | struct dvb_ringbuffer aout; /* buffer for audio */ | ||
135 | #define AOUTLEN (64*1024) | ||
136 | void *bmpbuf; | ||
137 | #define BMPLEN (8*32768+1024) | ||
138 | |||
139 | /* bitmap buffers and states */ | ||
140 | |||
141 | int bmpp; | ||
142 | int bmplen; | ||
143 | volatile int bmp_state; | ||
144 | #define BMP_NONE 0 | ||
145 | #define BMP_LOADING 1 | ||
146 | #define BMP_LOADED 2 | ||
147 | wait_queue_head_t bmpq; | ||
148 | |||
149 | |||
150 | /* DEBI and polled command interface */ | ||
151 | |||
152 | spinlock_t debilock; | ||
153 | struct mutex dcomlock; | ||
154 | volatile int debitype; | ||
155 | volatile int debilen; | ||
156 | |||
157 | |||
158 | /* Recording and playback flags */ | ||
159 | |||
160 | int rec_mode; | ||
161 | int playing; | ||
162 | #define RP_NONE 0 | ||
163 | #define RP_VIDEO 1 | ||
164 | #define RP_AUDIO 2 | ||
165 | #define RP_AV 3 | ||
166 | |||
167 | |||
168 | /* OSD */ | ||
169 | |||
170 | int osdwin; /* currently active window */ | ||
171 | u16 osdbpp[8]; | ||
172 | struct mutex osd_mutex; | ||
173 | |||
174 | /* CA */ | ||
175 | |||
176 | ca_slot_info_t ci_slot[2]; | ||
177 | |||
178 | enum av7110_video_mode vidmode; | ||
179 | struct dmxdev dmxdev; | ||
180 | struct dvb_demux demux; | ||
181 | |||
182 | struct dmx_frontend hw_frontend; | ||
183 | struct dmx_frontend mem_frontend; | ||
184 | |||
185 | /* for budget mode demux1 */ | ||
186 | struct dmxdev dmxdev1; | ||
187 | struct dvb_demux demux1; | ||
188 | struct dvb_net dvb_net1; | ||
189 | spinlock_t feedlock1; | ||
190 | int feeding1; | ||
191 | u32 ttbp; | ||
192 | unsigned char *grabbing; | ||
193 | struct saa7146_pgtable pt; | ||
194 | struct tasklet_struct vpe_tasklet; | ||
195 | bool full_ts; | ||
196 | |||
197 | int fe_synced; | ||
198 | struct mutex pid_mutex; | ||
199 | |||
200 | int video_blank; | ||
201 | struct video_status videostate; | ||
202 | u16 display_panscan; | ||
203 | int display_ar; | ||
204 | int trickmode; | ||
205 | #define TRICK_NONE 0 | ||
206 | #define TRICK_FAST 1 | ||
207 | #define TRICK_SLOW 2 | ||
208 | #define TRICK_FREEZE 3 | ||
209 | struct audio_status audiostate; | ||
210 | |||
211 | struct dvb_demux_filter *handle2filter[32]; | ||
212 | struct av7110_p2t p2t_filter[MAXFILT]; | ||
213 | struct dvb_filter_pes2ts p2t[2]; | ||
214 | struct ipack ipack[2]; | ||
215 | u8 *kbuf[2]; | ||
216 | |||
217 | int sinfo; | ||
218 | int feeding; | ||
219 | |||
220 | int arm_errors; | ||
221 | int registered; | ||
222 | |||
223 | |||
224 | /* AV711X */ | ||
225 | |||
226 | u32 arm_fw; | ||
227 | u32 arm_rtsl; | ||
228 | u32 arm_vid; | ||
229 | u32 arm_app; | ||
230 | u32 avtype; | ||
231 | int arm_ready; | ||
232 | struct task_struct *arm_thread; | ||
233 | wait_queue_head_t arm_wait; | ||
234 | u16 arm_loops; | ||
235 | |||
236 | void *debi_virt; | ||
237 | dma_addr_t debi_bus; | ||
238 | |||
239 | u16 pids[DMX_PES_OTHER]; | ||
240 | |||
241 | struct dvb_ringbuffer ci_rbuffer; | ||
242 | struct dvb_ringbuffer ci_wbuffer; | ||
243 | |||
244 | struct audio_mixer mixer; | ||
245 | |||
246 | struct dvb_adapter dvb_adapter; | ||
247 | struct dvb_device *video_dev; | ||
248 | struct dvb_device *audio_dev; | ||
249 | struct dvb_device *ca_dev; | ||
250 | struct dvb_device *osd_dev; | ||
251 | |||
252 | struct dvb_video_events video_events; | ||
253 | video_size_t video_size; | ||
254 | |||
255 | u16 wssMode; | ||
256 | u16 wssData; | ||
257 | |||
258 | struct infrared ir; | ||
259 | |||
260 | /* firmware stuff */ | ||
261 | unsigned char *bin_fw; | ||
262 | unsigned long size_fw; | ||
263 | |||
264 | unsigned char *bin_dpram; | ||
265 | unsigned long size_dpram; | ||
266 | |||
267 | unsigned char *bin_root; | ||
268 | unsigned long size_root; | ||
269 | |||
270 | struct dvb_frontend* fe; | ||
271 | fe_status_t fe_status; | ||
272 | |||
273 | /* crash recovery */ | ||
274 | void (*recover)(struct av7110* av7110); | ||
275 | fe_sec_voltage_t saved_voltage; | ||
276 | fe_sec_tone_mode_t saved_tone; | ||
277 | struct dvb_diseqc_master_cmd saved_master_cmd; | ||
278 | fe_sec_mini_cmd_t saved_minicmd; | ||
279 | |||
280 | int (*fe_init)(struct dvb_frontend* fe); | ||
281 | int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); | ||
282 | int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); | ||
283 | int (*fe_diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd); | ||
284 | int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); | ||
285 | int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); | ||
286 | int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | ||
287 | int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); | ||
288 | int (*fe_set_frontend)(struct dvb_frontend *fe); | ||
289 | }; | ||
290 | |||
291 | |||
292 | extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | ||
293 | u16 subpid, u16 pcrpid); | ||
294 | |||
295 | extern int av7110_check_ir_config(struct av7110 *av7110, int force); | ||
296 | extern int av7110_ir_init(struct av7110 *av7110); | ||
297 | extern void av7110_ir_exit(struct av7110 *av7110); | ||
298 | |||
299 | /* msp3400 i2c subaddresses */ | ||
300 | #define MSP_WR_DEM 0x10 | ||
301 | #define MSP_RD_DEM 0x11 | ||
302 | #define MSP_WR_DSP 0x12 | ||
303 | #define MSP_RD_DSP 0x13 | ||
304 | |||
305 | extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val); | ||
306 | extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg); | ||
307 | extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val); | ||
308 | |||
309 | |||
310 | extern int av7110_init_analog_module(struct av7110 *av7110); | ||
311 | extern int av7110_init_v4l(struct av7110 *av7110); | ||
312 | extern int av7110_exit_v4l(struct av7110 *av7110); | ||
313 | |||
314 | #endif /* _AV7110_H_ */ | ||
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c deleted file mode 100644 index 952b33dbac4f..000000000000 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ /dev/null | |||
@@ -1,1626 +0,0 @@ | |||
1 | /* | ||
2 | * av7110_av.c: audio and video MPEG decoder stuff | ||
3 | * | ||
4 | * Copyright (C) 1999-2002 Ralph Metzler | ||
5 | * & Marcus Metzler for convergence integrated media GmbH | ||
6 | * | ||
7 | * originally based on code by: | ||
8 | * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
25 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
26 | * | ||
27 | * | ||
28 | * the project's page is at http://www.linuxtv.org/ | ||
29 | */ | ||
30 | |||
31 | #include <linux/types.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/fs.h> | ||
36 | |||
37 | #include "av7110.h" | ||
38 | #include "av7110_hw.h" | ||
39 | #include "av7110_av.h" | ||
40 | #include "av7110_ipack.h" | ||
41 | |||
42 | /* MPEG-2 (ISO 13818 / H.222.0) stream types */ | ||
43 | #define PROG_STREAM_MAP 0xBC | ||
44 | #define PRIVATE_STREAM1 0xBD | ||
45 | #define PADDING_STREAM 0xBE | ||
46 | #define PRIVATE_STREAM2 0xBF | ||
47 | #define AUDIO_STREAM_S 0xC0 | ||
48 | #define AUDIO_STREAM_E 0xDF | ||
49 | #define VIDEO_STREAM_S 0xE0 | ||
50 | #define VIDEO_STREAM_E 0xEF | ||
51 | #define ECM_STREAM 0xF0 | ||
52 | #define EMM_STREAM 0xF1 | ||
53 | #define DSM_CC_STREAM 0xF2 | ||
54 | #define ISO13522_STREAM 0xF3 | ||
55 | #define PROG_STREAM_DIR 0xFF | ||
56 | |||
57 | #define PTS_DTS_FLAGS 0xC0 | ||
58 | |||
59 | //pts_dts flags | ||
60 | #define PTS_ONLY 0x80 | ||
61 | #define PTS_DTS 0xC0 | ||
62 | #define TS_SIZE 188 | ||
63 | #define TRANS_ERROR 0x80 | ||
64 | #define PAY_START 0x40 | ||
65 | #define TRANS_PRIO 0x20 | ||
66 | #define PID_MASK_HI 0x1F | ||
67 | //flags | ||
68 | #define TRANS_SCRMBL1 0x80 | ||
69 | #define TRANS_SCRMBL2 0x40 | ||
70 | #define ADAPT_FIELD 0x20 | ||
71 | #define PAYLOAD 0x10 | ||
72 | #define COUNT_MASK 0x0F | ||
73 | |||
74 | // adaptation flags | ||
75 | #define DISCON_IND 0x80 | ||
76 | #define RAND_ACC_IND 0x40 | ||
77 | #define ES_PRI_IND 0x20 | ||
78 | #define PCR_FLAG 0x10 | ||
79 | #define OPCR_FLAG 0x08 | ||
80 | #define SPLICE_FLAG 0x04 | ||
81 | #define TRANS_PRIV 0x02 | ||
82 | #define ADAP_EXT_FLAG 0x01 | ||
83 | |||
84 | // adaptation extension flags | ||
85 | #define LTW_FLAG 0x80 | ||
86 | #define PIECE_RATE 0x40 | ||
87 | #define SEAM_SPLICE 0x20 | ||
88 | |||
89 | |||
90 | static void p_to_t(u8 const *buf, long int length, u16 pid, | ||
91 | u8 *counter, struct dvb_demux_feed *feed); | ||
92 | static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len); | ||
93 | |||
94 | |||
95 | int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) | ||
96 | { | ||
97 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv; | ||
98 | |||
99 | if (!(dvbdmxfeed->ts_type & TS_PACKET)) | ||
100 | return 0; | ||
101 | if (buf[3] == 0xe0) // video PES do not have a length in TS | ||
102 | buf[4] = buf[5] = 0; | ||
103 | if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) | ||
104 | return dvbdmxfeed->cb.ts(buf, len, NULL, 0, | ||
105 | &dvbdmxfeed->feed.ts, DMX_OK); | ||
106 | else | ||
107 | return dvb_filter_pes2ts(p2t, buf, len, 1); | ||
108 | } | ||
109 | |||
110 | static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) | ||
111 | { | ||
112 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; | ||
113 | |||
114 | dvbdmxfeed->cb.ts(data, 188, NULL, 0, | ||
115 | &dvbdmxfeed->feed.ts, DMX_OK); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | int av7110_av_start_record(struct av7110 *av7110, int av, | ||
120 | struct dvb_demux_feed *dvbdmxfeed) | ||
121 | { | ||
122 | int ret = 0; | ||
123 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
124 | |||
125 | dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed); | ||
126 | |||
127 | if (av7110->playing || (av7110->rec_mode & av)) | ||
128 | return -EBUSY; | ||
129 | av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); | ||
130 | dvbdmx->recording = 1; | ||
131 | av7110->rec_mode |= av; | ||
132 | |||
133 | switch (av7110->rec_mode) { | ||
134 | case RP_AUDIO: | ||
135 | dvb_filter_pes2ts_init(&av7110->p2t[0], | ||
136 | dvbdmx->pesfilter[0]->pid, | ||
137 | dvb_filter_pes2ts_cb, | ||
138 | (void *) dvbdmx->pesfilter[0]); | ||
139 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); | ||
140 | break; | ||
141 | |||
142 | case RP_VIDEO: | ||
143 | dvb_filter_pes2ts_init(&av7110->p2t[1], | ||
144 | dvbdmx->pesfilter[1]->pid, | ||
145 | dvb_filter_pes2ts_cb, | ||
146 | (void *) dvbdmx->pesfilter[1]); | ||
147 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); | ||
148 | break; | ||
149 | |||
150 | case RP_AV: | ||
151 | dvb_filter_pes2ts_init(&av7110->p2t[0], | ||
152 | dvbdmx->pesfilter[0]->pid, | ||
153 | dvb_filter_pes2ts_cb, | ||
154 | (void *) dvbdmx->pesfilter[0]); | ||
155 | dvb_filter_pes2ts_init(&av7110->p2t[1], | ||
156 | dvbdmx->pesfilter[1]->pid, | ||
157 | dvb_filter_pes2ts_cb, | ||
158 | (void *) dvbdmx->pesfilter[1]); | ||
159 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); | ||
160 | break; | ||
161 | } | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | int av7110_av_start_play(struct av7110 *av7110, int av) | ||
166 | { | ||
167 | int ret = 0; | ||
168 | dprintk(2, "av7110:%p, \n", av7110); | ||
169 | |||
170 | if (av7110->rec_mode) | ||
171 | return -EBUSY; | ||
172 | if (av7110->playing & av) | ||
173 | return -EBUSY; | ||
174 | |||
175 | av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); | ||
176 | |||
177 | if (av7110->playing == RP_NONE) { | ||
178 | av7110_ipack_reset(&av7110->ipack[0]); | ||
179 | av7110_ipack_reset(&av7110->ipack[1]); | ||
180 | } | ||
181 | |||
182 | av7110->playing |= av; | ||
183 | switch (av7110->playing) { | ||
184 | case RP_AUDIO: | ||
185 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); | ||
186 | break; | ||
187 | case RP_VIDEO: | ||
188 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); | ||
189 | av7110->sinfo = 0; | ||
190 | break; | ||
191 | case RP_AV: | ||
192 | av7110->sinfo = 0; | ||
193 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); | ||
194 | break; | ||
195 | } | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | int av7110_av_stop(struct av7110 *av7110, int av) | ||
200 | { | ||
201 | int ret = 0; | ||
202 | dprintk(2, "av7110:%p, \n", av7110); | ||
203 | |||
204 | if (!(av7110->playing & av) && !(av7110->rec_mode & av)) | ||
205 | return 0; | ||
206 | av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); | ||
207 | if (av7110->playing) { | ||
208 | av7110->playing &= ~av; | ||
209 | switch (av7110->playing) { | ||
210 | case RP_AUDIO: | ||
211 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); | ||
212 | break; | ||
213 | case RP_VIDEO: | ||
214 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); | ||
215 | break; | ||
216 | case RP_NONE: | ||
217 | ret = av7110_set_vidmode(av7110, av7110->vidmode); | ||
218 | break; | ||
219 | } | ||
220 | } else { | ||
221 | av7110->rec_mode &= ~av; | ||
222 | switch (av7110->rec_mode) { | ||
223 | case RP_AUDIO: | ||
224 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); | ||
225 | break; | ||
226 | case RP_VIDEO: | ||
227 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); | ||
228 | break; | ||
229 | case RP_NONE: | ||
230 | break; | ||
231 | } | ||
232 | } | ||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | |||
237 | int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) | ||
238 | { | ||
239 | int len; | ||
240 | u32 sync; | ||
241 | u16 blen; | ||
242 | |||
243 | if (!dlen) { | ||
244 | wake_up(&buf->queue); | ||
245 | return -1; | ||
246 | } | ||
247 | while (1) { | ||
248 | len = dvb_ringbuffer_avail(buf); | ||
249 | if (len < 6) { | ||
250 | wake_up(&buf->queue); | ||
251 | return -1; | ||
252 | } | ||
253 | sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; | ||
254 | sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; | ||
255 | sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; | ||
256 | sync |= DVB_RINGBUFFER_PEEK(buf, 3); | ||
257 | |||
258 | if (((sync &~ 0x0f) == 0x000001e0) || | ||
259 | ((sync &~ 0x1f) == 0x000001c0) || | ||
260 | (sync == 0x000001bd)) | ||
261 | break; | ||
262 | printk("resync\n"); | ||
263 | DVB_RINGBUFFER_SKIP(buf, 1); | ||
264 | } | ||
265 | blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8; | ||
266 | blen |= DVB_RINGBUFFER_PEEK(buf, 5); | ||
267 | blen += 6; | ||
268 | if (len < blen || blen > dlen) { | ||
269 | //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen); | ||
270 | wake_up(&buf->queue); | ||
271 | return -1; | ||
272 | } | ||
273 | |||
274 | dvb_ringbuffer_read(buf, dest, (size_t) blen); | ||
275 | |||
276 | dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", | ||
277 | (unsigned long) buf->pread, (unsigned long) buf->pwrite); | ||
278 | wake_up(&buf->queue); | ||
279 | return blen; | ||
280 | } | ||
281 | |||
282 | |||
283 | int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) | ||
284 | { | ||
285 | int err, vol, val, balance = 0; | ||
286 | |||
287 | dprintk(2, "av7110:%p, \n", av7110); | ||
288 | |||
289 | av7110->mixer.volume_left = volleft; | ||
290 | av7110->mixer.volume_right = volright; | ||
291 | |||
292 | switch (av7110->adac_type) { | ||
293 | case DVB_ADAC_TI: | ||
294 | volleft = (volleft * 256) / 1036; | ||
295 | volright = (volright * 256) / 1036; | ||
296 | if (volleft > 0x3f) | ||
297 | volleft = 0x3f; | ||
298 | if (volright > 0x3f) | ||
299 | volright = 0x3f; | ||
300 | if ((err = SendDAC(av7110, 3, 0x80 + volleft))) | ||
301 | return err; | ||
302 | return SendDAC(av7110, 4, volright); | ||
303 | |||
304 | case DVB_ADAC_CRYSTAL: | ||
305 | volleft = 127 - volleft / 2; | ||
306 | volright = 127 - volright / 2; | ||
307 | i2c_writereg(av7110, 0x20, 0x03, volleft); | ||
308 | i2c_writereg(av7110, 0x20, 0x04, volright); | ||
309 | return 0; | ||
310 | |||
311 | case DVB_ADAC_MSP34x0: | ||
312 | vol = (volleft > volright) ? volleft : volright; | ||
313 | val = (vol * 0x73 / 255) << 8; | ||
314 | if (vol > 0) | ||
315 | balance = ((volright - volleft) * 127) / vol; | ||
316 | msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); | ||
317 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ | ||
318 | msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ | ||
319 | return 0; | ||
320 | |||
321 | case DVB_ADAC_MSP34x5: | ||
322 | vol = (volleft > volright) ? volleft : volright; | ||
323 | val = (vol * 0x73 / 255) << 8; | ||
324 | if (vol > 0) | ||
325 | balance = ((volright - volleft) * 127) / vol; | ||
326 | msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); | ||
327 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode) | ||
335 | { | ||
336 | int ret; | ||
337 | dprintk(2, "av7110:%p, \n", av7110); | ||
338 | |||
339 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); | ||
340 | |||
341 | if (!ret && !av7110->playing) { | ||
342 | ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], | ||
343 | av7110->pids[DMX_PES_AUDIO], | ||
344 | av7110->pids[DMX_PES_TELETEXT], | ||
345 | 0, av7110->pids[DMX_PES_PCR]); | ||
346 | if (!ret) | ||
347 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); | ||
348 | } | ||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | |||
353 | static enum av7110_video_mode sw2mode[16] = { | ||
354 | AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, | ||
355 | AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL, | ||
356 | AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC, | ||
357 | AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, | ||
358 | AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, | ||
359 | AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, | ||
360 | AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, | ||
361 | AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, | ||
362 | }; | ||
363 | |||
364 | static int get_video_format(struct av7110 *av7110, u8 *buf, int count) | ||
365 | { | ||
366 | int i; | ||
367 | int hsize, vsize; | ||
368 | int sw; | ||
369 | u8 *p; | ||
370 | int ret = 0; | ||
371 | |||
372 | dprintk(2, "av7110:%p, \n", av7110); | ||
373 | |||
374 | if (av7110->sinfo) | ||
375 | return 0; | ||
376 | for (i = 7; i < count - 10; i++) { | ||
377 | p = buf + i; | ||
378 | if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) | ||
379 | continue; | ||
380 | p += 4; | ||
381 | hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); | ||
382 | vsize = ((p[1] &0x0F) << 8) | (p[2]); | ||
383 | sw = (p[3] & 0x0F); | ||
384 | ret = av7110_set_vidmode(av7110, sw2mode[sw]); | ||
385 | if (!ret) { | ||
386 | dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); | ||
387 | av7110->sinfo = 1; | ||
388 | } | ||
389 | break; | ||
390 | } | ||
391 | return ret; | ||
392 | } | ||
393 | |||
394 | |||
395 | /**************************************************************************** | ||
396 | * I/O buffer management and control | ||
397 | ****************************************************************************/ | ||
398 | |||
399 | static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, | ||
400 | const u8 *buf, unsigned long count) | ||
401 | { | ||
402 | unsigned long todo = count; | ||
403 | int free; | ||
404 | |||
405 | while (todo > 0) { | ||
406 | if (dvb_ringbuffer_free(rbuf) < 2048) { | ||
407 | if (wait_event_interruptible(rbuf->queue, | ||
408 | (dvb_ringbuffer_free(rbuf) >= 2048))) | ||
409 | return count - todo; | ||
410 | } | ||
411 | free = dvb_ringbuffer_free(rbuf); | ||
412 | if (free > todo) | ||
413 | free = todo; | ||
414 | dvb_ringbuffer_write(rbuf, buf, free); | ||
415 | todo -= free; | ||
416 | buf += free; | ||
417 | } | ||
418 | |||
419 | return count - todo; | ||
420 | } | ||
421 | |||
422 | static void play_video_cb(u8 *buf, int count, void *priv) | ||
423 | { | ||
424 | struct av7110 *av7110 = (struct av7110 *) priv; | ||
425 | dprintk(2, "av7110:%p, \n", av7110); | ||
426 | |||
427 | if ((buf[3] & 0xe0) == 0xe0) { | ||
428 | get_video_format(av7110, buf, count); | ||
429 | aux_ring_buffer_write(&av7110->avout, buf, count); | ||
430 | } else | ||
431 | aux_ring_buffer_write(&av7110->aout, buf, count); | ||
432 | } | ||
433 | |||
434 | static void play_audio_cb(u8 *buf, int count, void *priv) | ||
435 | { | ||
436 | struct av7110 *av7110 = (struct av7110 *) priv; | ||
437 | dprintk(2, "av7110:%p, \n", av7110); | ||
438 | |||
439 | aux_ring_buffer_write(&av7110->aout, buf, count); | ||
440 | } | ||
441 | |||
442 | |||
443 | #define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096) | ||
444 | |||
445 | static ssize_t ts_play(struct av7110 *av7110, const char __user *buf, | ||
446 | unsigned long count, int nonblock, int type) | ||
447 | { | ||
448 | struct dvb_ringbuffer *rb; | ||
449 | u8 *kb; | ||
450 | unsigned long todo = count; | ||
451 | |||
452 | dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count); | ||
453 | |||
454 | rb = (type) ? &av7110->avout : &av7110->aout; | ||
455 | kb = av7110->kbuf[type]; | ||
456 | |||
457 | if (!kb) | ||
458 | return -ENOBUFS; | ||
459 | |||
460 | if (nonblock && !FREE_COND_TS) | ||
461 | return -EWOULDBLOCK; | ||
462 | |||
463 | while (todo >= TS_SIZE) { | ||
464 | if (!FREE_COND_TS) { | ||
465 | if (nonblock) | ||
466 | return count - todo; | ||
467 | if (wait_event_interruptible(rb->queue, FREE_COND_TS)) | ||
468 | return count - todo; | ||
469 | } | ||
470 | if (copy_from_user(kb, buf, TS_SIZE)) | ||
471 | return -EFAULT; | ||
472 | write_ts_to_decoder(av7110, type, kb, TS_SIZE); | ||
473 | todo -= TS_SIZE; | ||
474 | buf += TS_SIZE; | ||
475 | } | ||
476 | |||
477 | return count - todo; | ||
478 | } | ||
479 | |||
480 | |||
481 | #define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ | ||
482 | dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) | ||
483 | |||
484 | static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf, | ||
485 | unsigned long count, int nonblock, int type) | ||
486 | { | ||
487 | unsigned long todo = count, n; | ||
488 | dprintk(2, "av7110:%p, \n", av7110); | ||
489 | |||
490 | if (!av7110->kbuf[type]) | ||
491 | return -ENOBUFS; | ||
492 | |||
493 | if (nonblock && !FREE_COND) | ||
494 | return -EWOULDBLOCK; | ||
495 | |||
496 | while (todo > 0) { | ||
497 | if (!FREE_COND) { | ||
498 | if (nonblock) | ||
499 | return count - todo; | ||
500 | if (wait_event_interruptible(av7110->avout.queue, | ||
501 | FREE_COND)) | ||
502 | return count - todo; | ||
503 | } | ||
504 | n = todo; | ||
505 | if (n > IPACKS * 2) | ||
506 | n = IPACKS * 2; | ||
507 | if (copy_from_user(av7110->kbuf[type], buf, n)) | ||
508 | return -EFAULT; | ||
509 | av7110_ipack_instant_repack(av7110->kbuf[type], n, | ||
510 | &av7110->ipack[type]); | ||
511 | todo -= n; | ||
512 | buf += n; | ||
513 | } | ||
514 | return count - todo; | ||
515 | } | ||
516 | |||
517 | static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf, | ||
518 | unsigned long count, int nonblock, int type) | ||
519 | { | ||
520 | unsigned long todo = count, n; | ||
521 | dprintk(2, "av7110:%p, \n", av7110); | ||
522 | |||
523 | if (!av7110->kbuf[type]) | ||
524 | return -ENOBUFS; | ||
525 | |||
526 | if (nonblock && !FREE_COND) | ||
527 | return -EWOULDBLOCK; | ||
528 | |||
529 | while (todo > 0) { | ||
530 | if (!FREE_COND) { | ||
531 | if (nonblock) | ||
532 | return count - todo; | ||
533 | if (wait_event_interruptible(av7110->avout.queue, | ||
534 | FREE_COND)) | ||
535 | return count - todo; | ||
536 | } | ||
537 | n = todo; | ||
538 | if (n > IPACKS * 2) | ||
539 | n = IPACKS * 2; | ||
540 | av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]); | ||
541 | todo -= n; | ||
542 | buf += n; | ||
543 | } | ||
544 | return count - todo; | ||
545 | } | ||
546 | |||
547 | static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf, | ||
548 | unsigned long count, int nonblock, int type) | ||
549 | { | ||
550 | unsigned long todo = count, n; | ||
551 | dprintk(2, "av7110:%p, \n", av7110); | ||
552 | |||
553 | if (!av7110->kbuf[type]) | ||
554 | return -ENOBUFS; | ||
555 | if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) | ||
556 | return -EWOULDBLOCK; | ||
557 | |||
558 | while (todo > 0) { | ||
559 | if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) { | ||
560 | if (nonblock) | ||
561 | return count - todo; | ||
562 | if (wait_event_interruptible(av7110->aout.queue, | ||
563 | (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024))) | ||
564 | return count-todo; | ||
565 | } | ||
566 | n = todo; | ||
567 | if (n > IPACKS * 2) | ||
568 | n = IPACKS * 2; | ||
569 | if (copy_from_user(av7110->kbuf[type], buf, n)) | ||
570 | return -EFAULT; | ||
571 | av7110_ipack_instant_repack(av7110->kbuf[type], n, | ||
572 | &av7110->ipack[type]); | ||
573 | todo -= n; | ||
574 | buf += n; | ||
575 | } | ||
576 | return count - todo; | ||
577 | } | ||
578 | |||
579 | void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed) | ||
580 | { | ||
581 | memset(p->pes, 0, TS_SIZE); | ||
582 | p->counter = 0; | ||
583 | p->pos = 0; | ||
584 | p->frags = 0; | ||
585 | if (feed) | ||
586 | p->feed = feed; | ||
587 | } | ||
588 | |||
589 | static void clear_p2t(struct av7110_p2t *p) | ||
590 | { | ||
591 | memset(p->pes, 0, TS_SIZE); | ||
592 | // p->counter = 0; | ||
593 | p->pos = 0; | ||
594 | p->frags = 0; | ||
595 | } | ||
596 | |||
597 | |||
598 | static int find_pes_header(u8 const *buf, long int length, int *frags) | ||
599 | { | ||
600 | int c = 0; | ||
601 | int found = 0; | ||
602 | |||
603 | *frags = 0; | ||
604 | |||
605 | while (c < length - 3 && !found) { | ||
606 | if (buf[c] == 0x00 && buf[c + 1] == 0x00 && | ||
607 | buf[c + 2] == 0x01) { | ||
608 | switch ( buf[c + 3] ) { | ||
609 | case PROG_STREAM_MAP: | ||
610 | case PRIVATE_STREAM2: | ||
611 | case PROG_STREAM_DIR: | ||
612 | case ECM_STREAM : | ||
613 | case EMM_STREAM : | ||
614 | case PADDING_STREAM : | ||
615 | case DSM_CC_STREAM : | ||
616 | case ISO13522_STREAM: | ||
617 | case PRIVATE_STREAM1: | ||
618 | case AUDIO_STREAM_S ... AUDIO_STREAM_E: | ||
619 | case VIDEO_STREAM_S ... VIDEO_STREAM_E: | ||
620 | found = 1; | ||
621 | break; | ||
622 | |||
623 | default: | ||
624 | c++; | ||
625 | break; | ||
626 | } | ||
627 | } else | ||
628 | c++; | ||
629 | } | ||
630 | if (c == length - 3 && !found) { | ||
631 | if (buf[length - 1] == 0x00) | ||
632 | *frags = 1; | ||
633 | if (buf[length - 2] == 0x00 && | ||
634 | buf[length - 1] == 0x00) | ||
635 | *frags = 2; | ||
636 | if (buf[length - 3] == 0x00 && | ||
637 | buf[length - 2] == 0x00 && | ||
638 | buf[length - 1] == 0x01) | ||
639 | *frags = 3; | ||
640 | return -1; | ||
641 | } | ||
642 | |||
643 | return c; | ||
644 | } | ||
645 | |||
646 | void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) | ||
647 | { | ||
648 | int c, c2, l, add; | ||
649 | int check, rest; | ||
650 | |||
651 | c = 0; | ||
652 | c2 = 0; | ||
653 | if (p->frags){ | ||
654 | check = 0; | ||
655 | switch(p->frags) { | ||
656 | case 1: | ||
657 | if (buf[c] == 0x00 && buf[c + 1] == 0x01) { | ||
658 | check = 1; | ||
659 | c += 2; | ||
660 | } | ||
661 | break; | ||
662 | case 2: | ||
663 | if (buf[c] == 0x01) { | ||
664 | check = 1; | ||
665 | c++; | ||
666 | } | ||
667 | break; | ||
668 | case 3: | ||
669 | check = 1; | ||
670 | } | ||
671 | if (check) { | ||
672 | switch (buf[c]) { | ||
673 | case PROG_STREAM_MAP: | ||
674 | case PRIVATE_STREAM2: | ||
675 | case PROG_STREAM_DIR: | ||
676 | case ECM_STREAM : | ||
677 | case EMM_STREAM : | ||
678 | case PADDING_STREAM : | ||
679 | case DSM_CC_STREAM : | ||
680 | case ISO13522_STREAM: | ||
681 | case PRIVATE_STREAM1: | ||
682 | case AUDIO_STREAM_S ... AUDIO_STREAM_E: | ||
683 | case VIDEO_STREAM_S ... VIDEO_STREAM_E: | ||
684 | p->pes[0] = 0x00; | ||
685 | p->pes[1] = 0x00; | ||
686 | p->pes[2] = 0x01; | ||
687 | p->pes[3] = buf[c]; | ||
688 | p->pos = 4; | ||
689 | memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos); | ||
690 | c += (TS_SIZE - 4) - p->pos; | ||
691 | p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed); | ||
692 | clear_p2t(p); | ||
693 | break; | ||
694 | |||
695 | default: | ||
696 | c = 0; | ||
697 | break; | ||
698 | } | ||
699 | } | ||
700 | p->frags = 0; | ||
701 | } | ||
702 | |||
703 | if (p->pos) { | ||
704 | c2 = find_pes_header(buf + c, length - c, &p->frags); | ||
705 | if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos) | ||
706 | l = c2+c; | ||
707 | else | ||
708 | l = (TS_SIZE - 4) - p->pos; | ||
709 | memcpy(p->pes + p->pos, buf, l); | ||
710 | c += l; | ||
711 | p->pos += l; | ||
712 | p_to_t(p->pes, p->pos, pid, &p->counter, p->feed); | ||
713 | clear_p2t(p); | ||
714 | } | ||
715 | |||
716 | add = 0; | ||
717 | while (c < length) { | ||
718 | c2 = find_pes_header(buf + c + add, length - c - add, &p->frags); | ||
719 | if (c2 >= 0) { | ||
720 | c2 += c + add; | ||
721 | if (c2 > c){ | ||
722 | p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed); | ||
723 | c = c2; | ||
724 | clear_p2t(p); | ||
725 | add = 0; | ||
726 | } else | ||
727 | add = 1; | ||
728 | } else { | ||
729 | l = length - c; | ||
730 | rest = l % (TS_SIZE - 4); | ||
731 | l -= rest; | ||
732 | p_to_t(buf + c, l, pid, &p->counter, p->feed); | ||
733 | memcpy(p->pes, buf + c + l, rest); | ||
734 | p->pos = rest; | ||
735 | c = length; | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | |||
740 | |||
741 | static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length) | ||
742 | { | ||
743 | int i; | ||
744 | int c = 0; | ||
745 | int fill; | ||
746 | u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 }; | ||
747 | |||
748 | fill = (TS_SIZE - 4) - length; | ||
749 | if (pes_start) | ||
750 | tshead[1] = 0x40; | ||
751 | if (fill) | ||
752 | tshead[3] = 0x30; | ||
753 | tshead[1] |= (u8)((pid & 0x1F00) >> 8); | ||
754 | tshead[2] |= (u8)(pid & 0x00FF); | ||
755 | tshead[3] |= ((*counter)++ & 0x0F); | ||
756 | memcpy(buf, tshead, 4); | ||
757 | c += 4; | ||
758 | |||
759 | if (fill) { | ||
760 | buf[4] = fill - 1; | ||
761 | c++; | ||
762 | if (fill > 1) { | ||
763 | buf[5] = 0x00; | ||
764 | c++; | ||
765 | } | ||
766 | for (i = 6; i < fill + 4; i++) { | ||
767 | buf[i] = 0xFF; | ||
768 | c++; | ||
769 | } | ||
770 | } | ||
771 | |||
772 | return c; | ||
773 | } | ||
774 | |||
775 | |||
776 | static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, | ||
777 | struct dvb_demux_feed *feed) | ||
778 | { | ||
779 | int l, pes_start; | ||
780 | u8 obuf[TS_SIZE]; | ||
781 | long c = 0; | ||
782 | |||
783 | pes_start = 0; | ||
784 | if (length > 3 && | ||
785 | buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01) | ||
786 | switch (buf[3]) { | ||
787 | case PROG_STREAM_MAP: | ||
788 | case PRIVATE_STREAM2: | ||
789 | case PROG_STREAM_DIR: | ||
790 | case ECM_STREAM : | ||
791 | case EMM_STREAM : | ||
792 | case PADDING_STREAM : | ||
793 | case DSM_CC_STREAM : | ||
794 | case ISO13522_STREAM: | ||
795 | case PRIVATE_STREAM1: | ||
796 | case AUDIO_STREAM_S ... AUDIO_STREAM_E: | ||
797 | case VIDEO_STREAM_S ... VIDEO_STREAM_E: | ||
798 | pes_start = 1; | ||
799 | break; | ||
800 | |||
801 | default: | ||
802 | break; | ||
803 | } | ||
804 | |||
805 | while (c < length) { | ||
806 | memset(obuf, 0, TS_SIZE); | ||
807 | if (length - c >= (TS_SIZE - 4)){ | ||
808 | l = write_ts_header2(pid, counter, pes_start, | ||
809 | obuf, (TS_SIZE - 4)); | ||
810 | memcpy(obuf + l, buf + c, TS_SIZE - l); | ||
811 | c += TS_SIZE - l; | ||
812 | } else { | ||
813 | l = write_ts_header2(pid, counter, pes_start, | ||
814 | obuf, length - c); | ||
815 | memcpy(obuf + l, buf + c, TS_SIZE - l); | ||
816 | c = length; | ||
817 | } | ||
818 | feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK); | ||
819 | pes_start = 0; | ||
820 | } | ||
821 | } | ||
822 | |||
823 | |||
824 | static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len) | ||
825 | { | ||
826 | struct ipack *ipack = &av7110->ipack[type]; | ||
827 | |||
828 | if (buf[1] & TRANS_ERROR) { | ||
829 | av7110_ipack_reset(ipack); | ||
830 | return -1; | ||
831 | } | ||
832 | |||
833 | if (!(buf[3] & PAYLOAD)) | ||
834 | return -1; | ||
835 | |||
836 | if (buf[1] & PAY_START) | ||
837 | av7110_ipack_flush(ipack); | ||
838 | |||
839 | if (buf[3] & ADAPT_FIELD) { | ||
840 | len -= buf[4] + 1; | ||
841 | buf += buf[4] + 1; | ||
842 | if (!len) | ||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | av7110_ipack_instant_repack(buf + 4, len - 4, ipack); | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | |||
851 | int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) | ||
852 | { | ||
853 | struct dvb_demux *demux = feed->demux; | ||
854 | struct av7110 *av7110 = (struct av7110 *) demux->priv; | ||
855 | |||
856 | dprintk(2, "av7110:%p, \n", av7110); | ||
857 | |||
858 | if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE) | ||
859 | return 0; | ||
860 | |||
861 | switch (feed->pes_type) { | ||
862 | case 0: | ||
863 | if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) | ||
864 | return -EINVAL; | ||
865 | break; | ||
866 | case 1: | ||
867 | if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) | ||
868 | return -EINVAL; | ||
869 | break; | ||
870 | default: | ||
871 | return -1; | ||
872 | } | ||
873 | |||
874 | return write_ts_to_decoder(av7110, feed->pes_type, buf, len); | ||
875 | } | ||
876 | |||
877 | |||
878 | |||
879 | /****************************************************************************** | ||
880 | * Video MPEG decoder events | ||
881 | ******************************************************************************/ | ||
882 | void dvb_video_add_event(struct av7110 *av7110, struct video_event *event) | ||
883 | { | ||
884 | struct dvb_video_events *events = &av7110->video_events; | ||
885 | int wp; | ||
886 | |||
887 | spin_lock_bh(&events->lock); | ||
888 | |||
889 | wp = (events->eventw + 1) % MAX_VIDEO_EVENT; | ||
890 | if (wp == events->eventr) { | ||
891 | events->overflow = 1; | ||
892 | events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; | ||
893 | } | ||
894 | |||
895 | //FIXME: timestamp? | ||
896 | memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); | ||
897 | events->eventw = wp; | ||
898 | |||
899 | spin_unlock_bh(&events->lock); | ||
900 | |||
901 | wake_up_interruptible(&events->wait_queue); | ||
902 | } | ||
903 | |||
904 | |||
905 | static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) | ||
906 | { | ||
907 | struct dvb_video_events *events = &av7110->video_events; | ||
908 | |||
909 | if (events->overflow) { | ||
910 | events->overflow = 0; | ||
911 | return -EOVERFLOW; | ||
912 | } | ||
913 | if (events->eventw == events->eventr) { | ||
914 | int ret; | ||
915 | |||
916 | if (flags & O_NONBLOCK) | ||
917 | return -EWOULDBLOCK; | ||
918 | |||
919 | ret = wait_event_interruptible(events->wait_queue, | ||
920 | events->eventw != events->eventr); | ||
921 | if (ret < 0) | ||
922 | return ret; | ||
923 | } | ||
924 | |||
925 | spin_lock_bh(&events->lock); | ||
926 | |||
927 | memcpy(event, &events->events[events->eventr], | ||
928 | sizeof(struct video_event)); | ||
929 | events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; | ||
930 | |||
931 | spin_unlock_bh(&events->lock); | ||
932 | |||
933 | return 0; | ||
934 | } | ||
935 | |||
936 | |||
937 | /****************************************************************************** | ||
938 | * DVB device file operations | ||
939 | ******************************************************************************/ | ||
940 | |||
941 | static unsigned int dvb_video_poll(struct file *file, poll_table *wait) | ||
942 | { | ||
943 | struct dvb_device *dvbdev = file->private_data; | ||
944 | struct av7110 *av7110 = dvbdev->priv; | ||
945 | unsigned int mask = 0; | ||
946 | |||
947 | dprintk(2, "av7110:%p, \n", av7110); | ||
948 | |||
949 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) | ||
950 | poll_wait(file, &av7110->avout.queue, wait); | ||
951 | |||
952 | poll_wait(file, &av7110->video_events.wait_queue, wait); | ||
953 | |||
954 | if (av7110->video_events.eventw != av7110->video_events.eventr) | ||
955 | mask = POLLPRI; | ||
956 | |||
957 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | ||
958 | if (av7110->playing) { | ||
959 | if (FREE_COND) | ||
960 | mask |= (POLLOUT | POLLWRNORM); | ||
961 | } else /* if not playing: may play if asked for */ | ||
962 | mask |= (POLLOUT | POLLWRNORM); | ||
963 | } | ||
964 | |||
965 | return mask; | ||
966 | } | ||
967 | |||
968 | static ssize_t dvb_video_write(struct file *file, const char __user *buf, | ||
969 | size_t count, loff_t *ppos) | ||
970 | { | ||
971 | struct dvb_device *dvbdev = file->private_data; | ||
972 | struct av7110 *av7110 = dvbdev->priv; | ||
973 | unsigned char c; | ||
974 | |||
975 | dprintk(2, "av7110:%p, \n", av7110); | ||
976 | |||
977 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) | ||
978 | return -EPERM; | ||
979 | |||
980 | if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) | ||
981 | return -EPERM; | ||
982 | |||
983 | if (get_user(c, buf)) | ||
984 | return -EFAULT; | ||
985 | if (c == 0x47 && count % TS_SIZE == 0) | ||
986 | return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); | ||
987 | else | ||
988 | return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); | ||
989 | } | ||
990 | |||
991 | static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) | ||
992 | { | ||
993 | struct dvb_device *dvbdev = file->private_data; | ||
994 | struct av7110 *av7110 = dvbdev->priv; | ||
995 | unsigned int mask = 0; | ||
996 | |||
997 | dprintk(2, "av7110:%p, \n", av7110); | ||
998 | |||
999 | poll_wait(file, &av7110->aout.queue, wait); | ||
1000 | |||
1001 | if (av7110->playing) { | ||
1002 | if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) | ||
1003 | mask |= (POLLOUT | POLLWRNORM); | ||
1004 | } else /* if not playing: may play if asked for */ | ||
1005 | mask = (POLLOUT | POLLWRNORM); | ||
1006 | |||
1007 | return mask; | ||
1008 | } | ||
1009 | |||
1010 | static ssize_t dvb_audio_write(struct file *file, const char __user *buf, | ||
1011 | size_t count, loff_t *ppos) | ||
1012 | { | ||
1013 | struct dvb_device *dvbdev = file->private_data; | ||
1014 | struct av7110 *av7110 = dvbdev->priv; | ||
1015 | unsigned char c; | ||
1016 | |||
1017 | dprintk(2, "av7110:%p, \n", av7110); | ||
1018 | |||
1019 | if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) { | ||
1020 | printk(KERN_ERR "not audio source memory\n"); | ||
1021 | return -EPERM; | ||
1022 | } | ||
1023 | |||
1024 | if (get_user(c, buf)) | ||
1025 | return -EFAULT; | ||
1026 | if (c == 0x47 && count % TS_SIZE == 0) | ||
1027 | return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); | ||
1028 | else | ||
1029 | return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); | ||
1030 | } | ||
1031 | |||
1032 | static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; | ||
1033 | |||
1034 | #define MIN_IFRAME 400000 | ||
1035 | |||
1036 | static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) | ||
1037 | { | ||
1038 | unsigned i, n; | ||
1039 | int progressive = 0; | ||
1040 | int match = 0; | ||
1041 | |||
1042 | dprintk(2, "av7110:%p, \n", av7110); | ||
1043 | |||
1044 | if (!(av7110->playing & RP_VIDEO)) { | ||
1045 | if (av7110_av_start_play(av7110, RP_VIDEO) < 0) | ||
1046 | return -EBUSY; | ||
1047 | } | ||
1048 | |||
1049 | /* search in buf for instances of 00 00 01 b5 1? */ | ||
1050 | for (i = 0; i < len; i++) { | ||
1051 | unsigned char c; | ||
1052 | if (get_user(c, buf + i)) | ||
1053 | return -EFAULT; | ||
1054 | if (match == 5) { | ||
1055 | progressive = c & 0x08; | ||
1056 | match = 0; | ||
1057 | } | ||
1058 | if (c == 0x00) { | ||
1059 | match = (match == 1 || match == 2) ? 2 : 1; | ||
1060 | continue; | ||
1061 | } | ||
1062 | switch (match++) { | ||
1063 | case 2: if (c == 0x01) | ||
1064 | continue; | ||
1065 | break; | ||
1066 | case 3: if (c == 0xb5) | ||
1067 | continue; | ||
1068 | break; | ||
1069 | case 4: if ((c & 0xf0) == 0x10) | ||
1070 | continue; | ||
1071 | break; | ||
1072 | } | ||
1073 | match = 0; | ||
1074 | } | ||
1075 | |||
1076 | /* setting n always > 1, fixes problems when playing stillframes | ||
1077 | consisting of I- and P-Frames */ | ||
1078 | n = MIN_IFRAME / len + 1; | ||
1079 | |||
1080 | /* FIXME: nonblock? */ | ||
1081 | dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1); | ||
1082 | |||
1083 | for (i = 0; i < n; i++) | ||
1084 | dvb_play(av7110, buf, len, 0, 1); | ||
1085 | |||
1086 | av7110_ipack_flush(&av7110->ipack[1]); | ||
1087 | |||
1088 | if (progressive) | ||
1089 | return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); | ||
1090 | else | ||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | |||
1095 | static int dvb_video_ioctl(struct file *file, | ||
1096 | unsigned int cmd, void *parg) | ||
1097 | { | ||
1098 | struct dvb_device *dvbdev = file->private_data; | ||
1099 | struct av7110 *av7110 = dvbdev->priv; | ||
1100 | unsigned long arg = (unsigned long) parg; | ||
1101 | int ret = 0; | ||
1102 | |||
1103 | dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); | ||
1104 | |||
1105 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) { | ||
1106 | if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && | ||
1107 | cmd != VIDEO_GET_SIZE ) { | ||
1108 | return -EPERM; | ||
1109 | } | ||
1110 | } | ||
1111 | |||
1112 | switch (cmd) { | ||
1113 | case VIDEO_STOP: | ||
1114 | av7110->videostate.play_state = VIDEO_STOPPED; | ||
1115 | if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) | ||
1116 | ret = av7110_av_stop(av7110, RP_VIDEO); | ||
1117 | else | ||
1118 | ret = vidcom(av7110, AV_VIDEO_CMD_STOP, | ||
1119 | av7110->videostate.video_blank ? 0 : 1); | ||
1120 | if (!ret) | ||
1121 | av7110->trickmode = TRICK_NONE; | ||
1122 | break; | ||
1123 | |||
1124 | case VIDEO_PLAY: | ||
1125 | av7110->trickmode = TRICK_NONE; | ||
1126 | if (av7110->videostate.play_state == VIDEO_FREEZED) { | ||
1127 | av7110->videostate.play_state = VIDEO_PLAYING; | ||
1128 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); | ||
1129 | if (ret) | ||
1130 | break; | ||
1131 | } | ||
1132 | if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { | ||
1133 | if (av7110->playing == RP_AV) { | ||
1134 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); | ||
1135 | if (ret) | ||
1136 | break; | ||
1137 | av7110->playing &= ~RP_VIDEO; | ||
1138 | } | ||
1139 | ret = av7110_av_start_play(av7110, RP_VIDEO); | ||
1140 | } | ||
1141 | if (!ret) | ||
1142 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); | ||
1143 | if (!ret) | ||
1144 | av7110->videostate.play_state = VIDEO_PLAYING; | ||
1145 | break; | ||
1146 | |||
1147 | case VIDEO_FREEZE: | ||
1148 | av7110->videostate.play_state = VIDEO_FREEZED; | ||
1149 | if (av7110->playing & RP_VIDEO) | ||
1150 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); | ||
1151 | else | ||
1152 | ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); | ||
1153 | if (!ret) | ||
1154 | av7110->trickmode = TRICK_FREEZE; | ||
1155 | break; | ||
1156 | |||
1157 | case VIDEO_CONTINUE: | ||
1158 | if (av7110->playing & RP_VIDEO) | ||
1159 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); | ||
1160 | if (!ret) | ||
1161 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); | ||
1162 | if (!ret) { | ||
1163 | av7110->videostate.play_state = VIDEO_PLAYING; | ||
1164 | av7110->trickmode = TRICK_NONE; | ||
1165 | } | ||
1166 | break; | ||
1167 | |||
1168 | case VIDEO_SELECT_SOURCE: | ||
1169 | av7110->videostate.stream_source = (video_stream_source_t) arg; | ||
1170 | break; | ||
1171 | |||
1172 | case VIDEO_SET_BLANK: | ||
1173 | av7110->videostate.video_blank = (int) arg; | ||
1174 | break; | ||
1175 | |||
1176 | case VIDEO_GET_STATUS: | ||
1177 | memcpy(parg, &av7110->videostate, sizeof(struct video_status)); | ||
1178 | break; | ||
1179 | |||
1180 | case VIDEO_GET_EVENT: | ||
1181 | ret = dvb_video_get_event(av7110, parg, file->f_flags); | ||
1182 | break; | ||
1183 | |||
1184 | case VIDEO_GET_SIZE: | ||
1185 | memcpy(parg, &av7110->video_size, sizeof(video_size_t)); | ||
1186 | break; | ||
1187 | |||
1188 | case VIDEO_SET_DISPLAY_FORMAT: | ||
1189 | { | ||
1190 | video_displayformat_t format = (video_displayformat_t) arg; | ||
1191 | switch (format) { | ||
1192 | case VIDEO_PAN_SCAN: | ||
1193 | av7110->display_panscan = VID_PAN_SCAN_PREF; | ||
1194 | break; | ||
1195 | case VIDEO_LETTER_BOX: | ||
1196 | av7110->display_panscan = VID_VC_AND_PS_PREF; | ||
1197 | break; | ||
1198 | case VIDEO_CENTER_CUT_OUT: | ||
1199 | av7110->display_panscan = VID_CENTRE_CUT_PREF; | ||
1200 | break; | ||
1201 | default: | ||
1202 | ret = -EINVAL; | ||
1203 | } | ||
1204 | if (ret < 0) | ||
1205 | break; | ||
1206 | av7110->videostate.display_format = format; | ||
1207 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, | ||
1208 | 1, av7110->display_panscan); | ||
1209 | break; | ||
1210 | } | ||
1211 | |||
1212 | case VIDEO_SET_FORMAT: | ||
1213 | if (arg > 1) { | ||
1214 | ret = -EINVAL; | ||
1215 | break; | ||
1216 | } | ||
1217 | av7110->display_ar = arg; | ||
1218 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, | ||
1219 | 1, (u16) arg); | ||
1220 | break; | ||
1221 | |||
1222 | case VIDEO_STILLPICTURE: | ||
1223 | { | ||
1224 | struct video_still_picture *pic = | ||
1225 | (struct video_still_picture *) parg; | ||
1226 | av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; | ||
1227 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); | ||
1228 | ret = play_iframe(av7110, pic->iFrame, pic->size, | ||
1229 | file->f_flags & O_NONBLOCK); | ||
1230 | break; | ||
1231 | } | ||
1232 | |||
1233 | case VIDEO_FAST_FORWARD: | ||
1234 | //note: arg is ignored by firmware | ||
1235 | if (av7110->playing & RP_VIDEO) | ||
1236 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | ||
1237 | __Scan_I, 2, AV_PES, 0); | ||
1238 | else | ||
1239 | ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg); | ||
1240 | if (!ret) { | ||
1241 | av7110->trickmode = TRICK_FAST; | ||
1242 | av7110->videostate.play_state = VIDEO_PLAYING; | ||
1243 | } | ||
1244 | break; | ||
1245 | |||
1246 | case VIDEO_SLOWMOTION: | ||
1247 | if (av7110->playing&RP_VIDEO) { | ||
1248 | if (av7110->trickmode != TRICK_SLOW) | ||
1249 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); | ||
1250 | if (!ret) | ||
1251 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); | ||
1252 | } else { | ||
1253 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); | ||
1254 | if (!ret) | ||
1255 | ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0); | ||
1256 | if (!ret) | ||
1257 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); | ||
1258 | } | ||
1259 | if (!ret) { | ||
1260 | av7110->trickmode = TRICK_SLOW; | ||
1261 | av7110->videostate.play_state = VIDEO_PLAYING; | ||
1262 | } | ||
1263 | break; | ||
1264 | |||
1265 | case VIDEO_GET_CAPABILITIES: | ||
1266 | *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 | | ||
1267 | VIDEO_CAP_SYS | VIDEO_CAP_PROG; | ||
1268 | break; | ||
1269 | |||
1270 | case VIDEO_CLEAR_BUFFER: | ||
1271 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); | ||
1272 | av7110_ipack_reset(&av7110->ipack[1]); | ||
1273 | if (av7110->playing == RP_AV) { | ||
1274 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | ||
1275 | __Play, 2, AV_PES, 0); | ||
1276 | if (ret) | ||
1277 | break; | ||
1278 | if (av7110->trickmode == TRICK_FAST) | ||
1279 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | ||
1280 | __Scan_I, 2, AV_PES, 0); | ||
1281 | if (av7110->trickmode == TRICK_SLOW) { | ||
1282 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | ||
1283 | __Slow, 2, 0, 0); | ||
1284 | if (!ret) | ||
1285 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); | ||
1286 | } | ||
1287 | if (av7110->trickmode == TRICK_FREEZE) | ||
1288 | ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1); | ||
1289 | } | ||
1290 | break; | ||
1291 | |||
1292 | case VIDEO_SET_STREAMTYPE: | ||
1293 | break; | ||
1294 | |||
1295 | default: | ||
1296 | ret = -ENOIOCTLCMD; | ||
1297 | break; | ||
1298 | } | ||
1299 | |||
1300 | return ret; | ||
1301 | } | ||
1302 | |||
1303 | static int dvb_audio_ioctl(struct file *file, | ||
1304 | unsigned int cmd, void *parg) | ||
1305 | { | ||
1306 | struct dvb_device *dvbdev = file->private_data; | ||
1307 | struct av7110 *av7110 = dvbdev->priv; | ||
1308 | unsigned long arg = (unsigned long) parg; | ||
1309 | int ret = 0; | ||
1310 | |||
1311 | dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); | ||
1312 | |||
1313 | if (((file->f_flags & O_ACCMODE) == O_RDONLY) && | ||
1314 | (cmd != AUDIO_GET_STATUS)) | ||
1315 | return -EPERM; | ||
1316 | |||
1317 | switch (cmd) { | ||
1318 | case AUDIO_STOP: | ||
1319 | if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) | ||
1320 | ret = av7110_av_stop(av7110, RP_AUDIO); | ||
1321 | else | ||
1322 | ret = audcom(av7110, AUDIO_CMD_MUTE); | ||
1323 | if (!ret) | ||
1324 | av7110->audiostate.play_state = AUDIO_STOPPED; | ||
1325 | break; | ||
1326 | |||
1327 | case AUDIO_PLAY: | ||
1328 | if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) | ||
1329 | ret = av7110_av_start_play(av7110, RP_AUDIO); | ||
1330 | if (!ret) | ||
1331 | ret = audcom(av7110, AUDIO_CMD_UNMUTE); | ||
1332 | if (!ret) | ||
1333 | av7110->audiostate.play_state = AUDIO_PLAYING; | ||
1334 | break; | ||
1335 | |||
1336 | case AUDIO_PAUSE: | ||
1337 | ret = audcom(av7110, AUDIO_CMD_MUTE); | ||
1338 | if (!ret) | ||
1339 | av7110->audiostate.play_state = AUDIO_PAUSED; | ||
1340 | break; | ||
1341 | |||
1342 | case AUDIO_CONTINUE: | ||
1343 | if (av7110->audiostate.play_state == AUDIO_PAUSED) { | ||
1344 | av7110->audiostate.play_state = AUDIO_PLAYING; | ||
1345 | ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); | ||
1346 | } | ||
1347 | break; | ||
1348 | |||
1349 | case AUDIO_SELECT_SOURCE: | ||
1350 | av7110->audiostate.stream_source = (audio_stream_source_t) arg; | ||
1351 | break; | ||
1352 | |||
1353 | case AUDIO_SET_MUTE: | ||
1354 | { | ||
1355 | ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); | ||
1356 | if (!ret) | ||
1357 | av7110->audiostate.mute_state = (int) arg; | ||
1358 | break; | ||
1359 | } | ||
1360 | |||
1361 | case AUDIO_SET_AV_SYNC: | ||
1362 | av7110->audiostate.AV_sync_state = (int) arg; | ||
1363 | ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); | ||
1364 | break; | ||
1365 | |||
1366 | case AUDIO_SET_BYPASS_MODE: | ||
1367 | if (FW_VERSION(av7110->arm_app) < 0x2621) | ||
1368 | ret = -EINVAL; | ||
1369 | av7110->audiostate.bypass_mode = (int)arg; | ||
1370 | break; | ||
1371 | |||
1372 | case AUDIO_CHANNEL_SELECT: | ||
1373 | av7110->audiostate.channel_select = (audio_channel_select_t) arg; | ||
1374 | switch(av7110->audiostate.channel_select) { | ||
1375 | case AUDIO_STEREO: | ||
1376 | ret = audcom(av7110, AUDIO_CMD_STEREO); | ||
1377 | if (!ret) { | ||
1378 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | ||
1379 | i2c_writereg(av7110, 0x20, 0x02, 0x49); | ||
1380 | else if (av7110->adac_type == DVB_ADAC_MSP34x5) | ||
1381 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); | ||
1382 | } | ||
1383 | break; | ||
1384 | case AUDIO_MONO_LEFT: | ||
1385 | ret = audcom(av7110, AUDIO_CMD_MONO_L); | ||
1386 | if (!ret) { | ||
1387 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | ||
1388 | i2c_writereg(av7110, 0x20, 0x02, 0x4a); | ||
1389 | else if (av7110->adac_type == DVB_ADAC_MSP34x5) | ||
1390 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); | ||
1391 | } | ||
1392 | break; | ||
1393 | case AUDIO_MONO_RIGHT: | ||
1394 | ret = audcom(av7110, AUDIO_CMD_MONO_R); | ||
1395 | if (!ret) { | ||
1396 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | ||
1397 | i2c_writereg(av7110, 0x20, 0x02, 0x45); | ||
1398 | else if (av7110->adac_type == DVB_ADAC_MSP34x5) | ||
1399 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); | ||
1400 | } | ||
1401 | break; | ||
1402 | default: | ||
1403 | ret = -EINVAL; | ||
1404 | break; | ||
1405 | } | ||
1406 | break; | ||
1407 | |||
1408 | case AUDIO_GET_STATUS: | ||
1409 | memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); | ||
1410 | break; | ||
1411 | |||
1412 | case AUDIO_GET_CAPABILITIES: | ||
1413 | if (FW_VERSION(av7110->arm_app) < 0x2621) | ||
1414 | *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | ||
1415 | else | ||
1416 | *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | | ||
1417 | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | ||
1418 | break; | ||
1419 | |||
1420 | case AUDIO_CLEAR_BUFFER: | ||
1421 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); | ||
1422 | av7110_ipack_reset(&av7110->ipack[0]); | ||
1423 | if (av7110->playing == RP_AV) | ||
1424 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | ||
1425 | __Play, 2, AV_PES, 0); | ||
1426 | break; | ||
1427 | |||
1428 | case AUDIO_SET_ID: | ||
1429 | break; | ||
1430 | |||
1431 | case AUDIO_SET_MIXER: | ||
1432 | { | ||
1433 | struct audio_mixer *amix = (struct audio_mixer *)parg; | ||
1434 | ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); | ||
1435 | break; | ||
1436 | } | ||
1437 | |||
1438 | case AUDIO_SET_STREAMTYPE: | ||
1439 | break; | ||
1440 | |||
1441 | default: | ||
1442 | ret = -ENOIOCTLCMD; | ||
1443 | } | ||
1444 | |||
1445 | return ret; | ||
1446 | } | ||
1447 | |||
1448 | |||
1449 | static int dvb_video_open(struct inode *inode, struct file *file) | ||
1450 | { | ||
1451 | struct dvb_device *dvbdev = file->private_data; | ||
1452 | struct av7110 *av7110 = dvbdev->priv; | ||
1453 | int err; | ||
1454 | |||
1455 | dprintk(2, "av7110:%p, \n", av7110); | ||
1456 | |||
1457 | if ((err = dvb_generic_open(inode, file)) < 0) | ||
1458 | return err; | ||
1459 | |||
1460 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | ||
1461 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); | ||
1462 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); | ||
1463 | av7110->video_blank = 1; | ||
1464 | av7110->audiostate.AV_sync_state = 1; | ||
1465 | av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; | ||
1466 | |||
1467 | /* empty event queue */ | ||
1468 | av7110->video_events.eventr = av7110->video_events.eventw = 0; | ||
1469 | } | ||
1470 | |||
1471 | return 0; | ||
1472 | } | ||
1473 | |||
1474 | static int dvb_video_release(struct inode *inode, struct file *file) | ||
1475 | { | ||
1476 | struct dvb_device *dvbdev = file->private_data; | ||
1477 | struct av7110 *av7110 = dvbdev->priv; | ||
1478 | |||
1479 | dprintk(2, "av7110:%p, \n", av7110); | ||
1480 | |||
1481 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | ||
1482 | av7110_av_stop(av7110, RP_VIDEO); | ||
1483 | } | ||
1484 | |||
1485 | return dvb_generic_release(inode, file); | ||
1486 | } | ||
1487 | |||
1488 | static int dvb_audio_open(struct inode *inode, struct file *file) | ||
1489 | { | ||
1490 | struct dvb_device *dvbdev = file->private_data; | ||
1491 | struct av7110 *av7110 = dvbdev->priv; | ||
1492 | int err = dvb_generic_open(inode, file); | ||
1493 | |||
1494 | dprintk(2, "av7110:%p, \n", av7110); | ||
1495 | |||
1496 | if (err < 0) | ||
1497 | return err; | ||
1498 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); | ||
1499 | av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; | ||
1500 | return 0; | ||
1501 | } | ||
1502 | |||
1503 | static int dvb_audio_release(struct inode *inode, struct file *file) | ||
1504 | { | ||
1505 | struct dvb_device *dvbdev = file->private_data; | ||
1506 | struct av7110 *av7110 = dvbdev->priv; | ||
1507 | |||
1508 | dprintk(2, "av7110:%p, \n", av7110); | ||
1509 | |||
1510 | av7110_av_stop(av7110, RP_AUDIO); | ||
1511 | return dvb_generic_release(inode, file); | ||
1512 | } | ||
1513 | |||
1514 | |||
1515 | |||
1516 | /****************************************************************************** | ||
1517 | * driver registration | ||
1518 | ******************************************************************************/ | ||
1519 | |||
1520 | static const struct file_operations dvb_video_fops = { | ||
1521 | .owner = THIS_MODULE, | ||
1522 | .write = dvb_video_write, | ||
1523 | .unlocked_ioctl = dvb_generic_ioctl, | ||
1524 | .open = dvb_video_open, | ||
1525 | .release = dvb_video_release, | ||
1526 | .poll = dvb_video_poll, | ||
1527 | .llseek = noop_llseek, | ||
1528 | }; | ||
1529 | |||
1530 | static struct dvb_device dvbdev_video = { | ||
1531 | .priv = NULL, | ||
1532 | .users = 6, | ||
1533 | .readers = 5, /* arbitrary */ | ||
1534 | .writers = 1, | ||
1535 | .fops = &dvb_video_fops, | ||
1536 | .kernel_ioctl = dvb_video_ioctl, | ||
1537 | }; | ||
1538 | |||
1539 | static const struct file_operations dvb_audio_fops = { | ||
1540 | .owner = THIS_MODULE, | ||
1541 | .write = dvb_audio_write, | ||
1542 | .unlocked_ioctl = dvb_generic_ioctl, | ||
1543 | .open = dvb_audio_open, | ||
1544 | .release = dvb_audio_release, | ||
1545 | .poll = dvb_audio_poll, | ||
1546 | .llseek = noop_llseek, | ||
1547 | }; | ||
1548 | |||
1549 | static struct dvb_device dvbdev_audio = { | ||
1550 | .priv = NULL, | ||
1551 | .users = 1, | ||
1552 | .writers = 1, | ||
1553 | .fops = &dvb_audio_fops, | ||
1554 | .kernel_ioctl = dvb_audio_ioctl, | ||
1555 | }; | ||
1556 | |||
1557 | |||
1558 | int av7110_av_register(struct av7110 *av7110) | ||
1559 | { | ||
1560 | av7110->audiostate.AV_sync_state = 0; | ||
1561 | av7110->audiostate.mute_state = 0; | ||
1562 | av7110->audiostate.play_state = AUDIO_STOPPED; | ||
1563 | av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; | ||
1564 | av7110->audiostate.channel_select = AUDIO_STEREO; | ||
1565 | av7110->audiostate.bypass_mode = 0; | ||
1566 | |||
1567 | av7110->videostate.video_blank = 0; | ||
1568 | av7110->videostate.play_state = VIDEO_STOPPED; | ||
1569 | av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; | ||
1570 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; | ||
1571 | av7110->videostate.display_format = VIDEO_LETTER_BOX; | ||
1572 | av7110->display_ar = VIDEO_FORMAT_4_3; | ||
1573 | av7110->display_panscan = VID_VC_AND_PS_PREF; | ||
1574 | |||
1575 | init_waitqueue_head(&av7110->video_events.wait_queue); | ||
1576 | spin_lock_init(&av7110->video_events.lock); | ||
1577 | av7110->video_events.eventw = av7110->video_events.eventr = 0; | ||
1578 | av7110->video_events.overflow = 0; | ||
1579 | memset(&av7110->video_size, 0, sizeof (video_size_t)); | ||
1580 | |||
1581 | dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, | ||
1582 | &dvbdev_video, av7110, DVB_DEVICE_VIDEO); | ||
1583 | |||
1584 | dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, | ||
1585 | &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); | ||
1586 | |||
1587 | return 0; | ||
1588 | } | ||
1589 | |||
1590 | void av7110_av_unregister(struct av7110 *av7110) | ||
1591 | { | ||
1592 | dvb_unregister_device(av7110->audio_dev); | ||
1593 | dvb_unregister_device(av7110->video_dev); | ||
1594 | } | ||
1595 | |||
1596 | int av7110_av_init(struct av7110 *av7110) | ||
1597 | { | ||
1598 | void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; | ||
1599 | int i, ret; | ||
1600 | |||
1601 | for (i = 0; i < 2; i++) { | ||
1602 | struct ipack *ipack = av7110->ipack + i; | ||
1603 | |||
1604 | ret = av7110_ipack_init(ipack, IPACKS, play[i]); | ||
1605 | if (ret < 0) { | ||
1606 | if (i) | ||
1607 | av7110_ipack_free(--ipack); | ||
1608 | goto out; | ||
1609 | } | ||
1610 | ipack->data = av7110; | ||
1611 | } | ||
1612 | |||
1613 | dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); | ||
1614 | dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN); | ||
1615 | |||
1616 | av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN); | ||
1617 | av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS; | ||
1618 | out: | ||
1619 | return ret; | ||
1620 | } | ||
1621 | |||
1622 | void av7110_av_exit(struct av7110 *av7110) | ||
1623 | { | ||
1624 | av7110_ipack_free(&av7110->ipack[0]); | ||
1625 | av7110_ipack_free(&av7110->ipack[1]); | ||
1626 | } | ||
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h deleted file mode 100644 index 5f02ef85e47d..000000000000 --- a/drivers/media/dvb/ttpci/av7110_av.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #ifndef _AV7110_AV_H_ | ||
2 | #define _AV7110_AV_H_ | ||
3 | |||
4 | struct av7110; | ||
5 | |||
6 | extern int av7110_set_vidmode(struct av7110 *av7110, | ||
7 | enum av7110_video_mode mode); | ||
8 | |||
9 | extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len); | ||
10 | extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen); | ||
11 | extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len); | ||
12 | |||
13 | extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright); | ||
14 | extern int av7110_av_stop(struct av7110 *av7110, int av); | ||
15 | extern int av7110_av_start_record(struct av7110 *av7110, int av, | ||
16 | struct dvb_demux_feed *dvbdmxfeed); | ||
17 | extern int av7110_av_start_play(struct av7110 *av7110, int av); | ||
18 | |||
19 | extern void dvb_video_add_event(struct av7110 *av7110, struct video_event *event); | ||
20 | |||
21 | extern void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed); | ||
22 | extern void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p); | ||
23 | |||
24 | extern int av7110_av_register(struct av7110 *av7110); | ||
25 | extern void av7110_av_unregister(struct av7110 *av7110); | ||
26 | extern int av7110_av_init(struct av7110 *av7110); | ||
27 | extern void av7110_av_exit(struct av7110 *av7110); | ||
28 | |||
29 | |||
30 | #endif /* _AV7110_AV_H_ */ | ||
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c deleted file mode 100644 index 9fc1dd0ba4c3..000000000000 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ /dev/null | |||
@@ -1,387 +0,0 @@ | |||
1 | /* | ||
2 | * av7110_ca.c: CA and CI stuff | ||
3 | * | ||
4 | * Copyright (C) 1999-2002 Ralph Metzler | ||
5 | * & Marcus Metzler for convergence integrated media GmbH | ||
6 | * | ||
7 | * originally based on code by: | ||
8 | * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
25 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
26 | * | ||
27 | * | ||
28 | * the project's page is at http://www.linuxtv.org/ | ||
29 | */ | ||
30 | |||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/types.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/timer.h> | ||
36 | #include <linux/poll.h> | ||
37 | #include <linux/gfp.h> | ||
38 | |||
39 | #include "av7110.h" | ||
40 | #include "av7110_hw.h" | ||
41 | #include "av7110_ca.h" | ||
42 | |||
43 | |||
44 | void CI_handle(struct av7110 *av7110, u8 *data, u16 len) | ||
45 | { | ||
46 | dprintk(8, "av7110:%p\n",av7110); | ||
47 | |||
48 | if (len < 3) | ||
49 | return; | ||
50 | switch (data[0]) { | ||
51 | case CI_MSG_CI_INFO: | ||
52 | if (data[2] != 1 && data[2] != 2) | ||
53 | break; | ||
54 | switch (data[1]) { | ||
55 | case 0: | ||
56 | av7110->ci_slot[data[2] - 1].flags = 0; | ||
57 | break; | ||
58 | case 1: | ||
59 | av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT; | ||
60 | break; | ||
61 | case 2: | ||
62 | av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY; | ||
63 | break; | ||
64 | } | ||
65 | break; | ||
66 | case CI_SWITCH_PRG_REPLY: | ||
67 | //av7110->ci_stat=data[1]; | ||
68 | break; | ||
69 | default: | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | |||
75 | void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len) | ||
76 | { | ||
77 | if (dvb_ringbuffer_free(cibuf) < len + 2) | ||
78 | return; | ||
79 | |||
80 | DVB_RINGBUFFER_WRITE_BYTE(cibuf, len >> 8); | ||
81 | DVB_RINGBUFFER_WRITE_BYTE(cibuf, len & 0xff); | ||
82 | dvb_ringbuffer_write(cibuf, data, len); | ||
83 | wake_up_interruptible(&cibuf->queue); | ||
84 | } | ||
85 | |||
86 | |||
87 | /****************************************************************************** | ||
88 | * CI link layer file ops | ||
89 | ******************************************************************************/ | ||
90 | |||
91 | static int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size) | ||
92 | { | ||
93 | struct dvb_ringbuffer *tab[] = { cirbuf, ciwbuf, NULL }, **p; | ||
94 | void *data; | ||
95 | |||
96 | for (p = tab; *p; p++) { | ||
97 | data = vmalloc(size); | ||
98 | if (!data) { | ||
99 | while (p-- != tab) { | ||
100 | vfree(p[0]->data); | ||
101 | p[0]->data = NULL; | ||
102 | } | ||
103 | return -ENOMEM; | ||
104 | } | ||
105 | dvb_ringbuffer_init(*p, data, size); | ||
106 | } | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) | ||
111 | { | ||
112 | dvb_ringbuffer_flush_spinlock_wakeup(cirbuf); | ||
113 | dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf); | ||
114 | } | ||
115 | |||
116 | static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) | ||
117 | { | ||
118 | vfree(cirbuf->data); | ||
119 | cirbuf->data = NULL; | ||
120 | vfree(ciwbuf->data); | ||
121 | ciwbuf->data = NULL; | ||
122 | } | ||
123 | |||
124 | static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, | ||
125 | int slots, ca_slot_info_t *slot) | ||
126 | { | ||
127 | int i; | ||
128 | int len = 0; | ||
129 | u8 msg[8] = { 0x00, 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00 }; | ||
130 | |||
131 | for (i = 0; i < 2; i++) { | ||
132 | if (slots & (1 << i)) | ||
133 | len += 8; | ||
134 | } | ||
135 | |||
136 | if (dvb_ringbuffer_free(cibuf) < len) | ||
137 | return -EBUSY; | ||
138 | |||
139 | for (i = 0; i < 2; i++) { | ||
140 | if (slots & (1 << i)) { | ||
141 | msg[2] = i; | ||
142 | dvb_ringbuffer_write(cibuf, msg, 8); | ||
143 | slot[i].flags = 0; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file, | ||
151 | const char __user *buf, size_t count, loff_t *ppos) | ||
152 | { | ||
153 | int free; | ||
154 | int non_blocking = file->f_flags & O_NONBLOCK; | ||
155 | u8 *page = (u8 *)__get_free_page(GFP_USER); | ||
156 | int res; | ||
157 | |||
158 | if (!page) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | res = -EINVAL; | ||
162 | if (count > 2048) | ||
163 | goto out; | ||
164 | |||
165 | res = -EFAULT; | ||
166 | if (copy_from_user(page, buf, count)) | ||
167 | goto out; | ||
168 | |||
169 | free = dvb_ringbuffer_free(cibuf); | ||
170 | if (count + 2 > free) { | ||
171 | res = -EWOULDBLOCK; | ||
172 | if (non_blocking) | ||
173 | goto out; | ||
174 | res = -ERESTARTSYS; | ||
175 | if (wait_event_interruptible(cibuf->queue, | ||
176 | (dvb_ringbuffer_free(cibuf) >= count + 2))) | ||
177 | goto out; | ||
178 | } | ||
179 | |||
180 | DVB_RINGBUFFER_WRITE_BYTE(cibuf, count >> 8); | ||
181 | DVB_RINGBUFFER_WRITE_BYTE(cibuf, count & 0xff); | ||
182 | |||
183 | res = dvb_ringbuffer_write(cibuf, page, count); | ||
184 | out: | ||
185 | free_page((unsigned long)page); | ||
186 | return res; | ||
187 | } | ||
188 | |||
189 | static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, | ||
190 | char __user *buf, size_t count, loff_t *ppos) | ||
191 | { | ||
192 | int avail; | ||
193 | int non_blocking = file->f_flags & O_NONBLOCK; | ||
194 | ssize_t len; | ||
195 | |||
196 | if (!cibuf->data || !count) | ||
197 | return 0; | ||
198 | if (non_blocking && (dvb_ringbuffer_empty(cibuf))) | ||
199 | return -EWOULDBLOCK; | ||
200 | if (wait_event_interruptible(cibuf->queue, | ||
201 | !dvb_ringbuffer_empty(cibuf))) | ||
202 | return -ERESTARTSYS; | ||
203 | avail = dvb_ringbuffer_avail(cibuf); | ||
204 | if (avail < 4) | ||
205 | return 0; | ||
206 | len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8; | ||
207 | len |= DVB_RINGBUFFER_PEEK(cibuf, 1); | ||
208 | if (avail < len + 2 || count < len) | ||
209 | return -EINVAL; | ||
210 | DVB_RINGBUFFER_SKIP(cibuf, 2); | ||
211 | |||
212 | return dvb_ringbuffer_read_user(cibuf, buf, len); | ||
213 | } | ||
214 | |||
215 | static int dvb_ca_open(struct inode *inode, struct file *file) | ||
216 | { | ||
217 | struct dvb_device *dvbdev = file->private_data; | ||
218 | struct av7110 *av7110 = dvbdev->priv; | ||
219 | int err = dvb_generic_open(inode, file); | ||
220 | |||
221 | dprintk(8, "av7110:%p\n",av7110); | ||
222 | |||
223 | if (err < 0) | ||
224 | return err; | ||
225 | ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer); | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) | ||
230 | { | ||
231 | struct dvb_device *dvbdev = file->private_data; | ||
232 | struct av7110 *av7110 = dvbdev->priv; | ||
233 | struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer; | ||
234 | struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer; | ||
235 | unsigned int mask = 0; | ||
236 | |||
237 | dprintk(8, "av7110:%p\n",av7110); | ||
238 | |||
239 | poll_wait(file, &rbuf->queue, wait); | ||
240 | poll_wait(file, &wbuf->queue, wait); | ||
241 | |||
242 | if (!dvb_ringbuffer_empty(rbuf)) | ||
243 | mask |= (POLLIN | POLLRDNORM); | ||
244 | |||
245 | if (dvb_ringbuffer_free(wbuf) > 1024) | ||
246 | mask |= (POLLOUT | POLLWRNORM); | ||
247 | |||
248 | return mask; | ||
249 | } | ||
250 | |||
251 | static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) | ||
252 | { | ||
253 | struct dvb_device *dvbdev = file->private_data; | ||
254 | struct av7110 *av7110 = dvbdev->priv; | ||
255 | unsigned long arg = (unsigned long) parg; | ||
256 | |||
257 | dprintk(8, "av7110:%p\n",av7110); | ||
258 | |||
259 | switch (cmd) { | ||
260 | case CA_RESET: | ||
261 | return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]); | ||
262 | break; | ||
263 | case CA_GET_CAP: | ||
264 | { | ||
265 | ca_caps_t cap; | ||
266 | |||
267 | cap.slot_num = 2; | ||
268 | cap.slot_type = (FW_CI_LL_SUPPORT(av7110->arm_app) ? | ||
269 | CA_CI_LINK : CA_CI) | CA_DESCR; | ||
270 | cap.descr_num = 16; | ||
271 | cap.descr_type = CA_ECD; | ||
272 | memcpy(parg, &cap, sizeof(cap)); | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | case CA_GET_SLOT_INFO: | ||
277 | { | ||
278 | ca_slot_info_t *info=(ca_slot_info_t *)parg; | ||
279 | |||
280 | if (info->num < 0 || info->num > 1) | ||
281 | return -EINVAL; | ||
282 | av7110->ci_slot[info->num].num = info->num; | ||
283 | av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? | ||
284 | CA_CI_LINK : CA_CI; | ||
285 | memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); | ||
286 | break; | ||
287 | } | ||
288 | |||
289 | case CA_GET_MSG: | ||
290 | break; | ||
291 | |||
292 | case CA_SEND_MSG: | ||
293 | break; | ||
294 | |||
295 | case CA_GET_DESCR_INFO: | ||
296 | { | ||
297 | ca_descr_info_t info; | ||
298 | |||
299 | info.num = 16; | ||
300 | info.type = CA_ECD; | ||
301 | memcpy(parg, &info, sizeof (info)); | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | case CA_SET_DESCR: | ||
306 | { | ||
307 | ca_descr_t *descr = (ca_descr_t*) parg; | ||
308 | |||
309 | if (descr->index >= 16) | ||
310 | return -EINVAL; | ||
311 | if (descr->parity > 1) | ||
312 | return -EINVAL; | ||
313 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetDescr, 5, | ||
314 | (descr->index<<8)|descr->parity, | ||
315 | (descr->cw[0]<<8)|descr->cw[1], | ||
316 | (descr->cw[2]<<8)|descr->cw[3], | ||
317 | (descr->cw[4]<<8)|descr->cw[5], | ||
318 | (descr->cw[6]<<8)|descr->cw[7]); | ||
319 | break; | ||
320 | } | ||
321 | |||
322 | default: | ||
323 | return -EINVAL; | ||
324 | } | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static ssize_t dvb_ca_write(struct file *file, const char __user *buf, | ||
329 | size_t count, loff_t *ppos) | ||
330 | { | ||
331 | struct dvb_device *dvbdev = file->private_data; | ||
332 | struct av7110 *av7110 = dvbdev->priv; | ||
333 | |||
334 | dprintk(8, "av7110:%p\n",av7110); | ||
335 | return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos); | ||
336 | } | ||
337 | |||
338 | static ssize_t dvb_ca_read(struct file *file, char __user *buf, | ||
339 | size_t count, loff_t *ppos) | ||
340 | { | ||
341 | struct dvb_device *dvbdev = file->private_data; | ||
342 | struct av7110 *av7110 = dvbdev->priv; | ||
343 | |||
344 | dprintk(8, "av7110:%p\n",av7110); | ||
345 | return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos); | ||
346 | } | ||
347 | |||
348 | static const struct file_operations dvb_ca_fops = { | ||
349 | .owner = THIS_MODULE, | ||
350 | .read = dvb_ca_read, | ||
351 | .write = dvb_ca_write, | ||
352 | .unlocked_ioctl = dvb_generic_ioctl, | ||
353 | .open = dvb_ca_open, | ||
354 | .release = dvb_generic_release, | ||
355 | .poll = dvb_ca_poll, | ||
356 | .llseek = default_llseek, | ||
357 | }; | ||
358 | |||
359 | static struct dvb_device dvbdev_ca = { | ||
360 | .priv = NULL, | ||
361 | .users = 1, | ||
362 | .writers = 1, | ||
363 | .fops = &dvb_ca_fops, | ||
364 | .kernel_ioctl = dvb_ca_ioctl, | ||
365 | }; | ||
366 | |||
367 | |||
368 | int av7110_ca_register(struct av7110 *av7110) | ||
369 | { | ||
370 | return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev, | ||
371 | &dvbdev_ca, av7110, DVB_DEVICE_CA); | ||
372 | } | ||
373 | |||
374 | void av7110_ca_unregister(struct av7110 *av7110) | ||
375 | { | ||
376 | dvb_unregister_device(av7110->ca_dev); | ||
377 | } | ||
378 | |||
379 | int av7110_ca_init(struct av7110* av7110) | ||
380 | { | ||
381 | return ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192); | ||
382 | } | ||
383 | |||
384 | void av7110_ca_exit(struct av7110* av7110) | ||
385 | { | ||
386 | ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer); | ||
387 | } | ||
diff --git a/drivers/media/dvb/ttpci/av7110_ca.h b/drivers/media/dvb/ttpci/av7110_ca.h deleted file mode 100644 index 70ee855ece1b..000000000000 --- a/drivers/media/dvb/ttpci/av7110_ca.h +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | #ifndef _AV7110_CA_H_ | ||
2 | #define _AV7110_CA_H_ | ||
3 | |||
4 | struct av7110; | ||
5 | |||
6 | extern void CI_handle(struct av7110 *av7110, u8 *data, u16 len); | ||
7 | extern void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len); | ||
8 | |||
9 | extern int av7110_ca_register(struct av7110 *av7110); | ||
10 | extern void av7110_ca_unregister(struct av7110 *av7110); | ||
11 | extern int av7110_ca_init(struct av7110* av7110); | ||
12 | extern void av7110_ca_exit(struct av7110* av7110); | ||
13 | |||
14 | #endif /* _AV7110_CA_H_ */ | ||
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c deleted file mode 100644 index f1cbfe526989..000000000000 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ /dev/null | |||
@@ -1,1208 +0,0 @@ | |||
1 | /* | ||
2 | * av7110_hw.c: av7110 low level hardware access and firmware interface | ||
3 | * | ||
4 | * Copyright (C) 1999-2002 Ralph Metzler | ||
5 | * & Marcus Metzler for convergence integrated media GmbH | ||
6 | * | ||
7 | * originally based on code by: | ||
8 | * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
23 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
24 | * | ||
25 | * the project's page is at http://www.linuxtv.org/ | ||
26 | */ | ||
27 | |||
28 | /* for debugging ARM communication: */ | ||
29 | //#define COM_DEBUG | ||
30 | |||
31 | #include <stdarg.h> | ||
32 | #include <linux/types.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/fs.h> | ||
37 | |||
38 | #include "av7110.h" | ||
39 | #include "av7110_hw.h" | ||
40 | |||
41 | #define _NOHANDSHAKE | ||
42 | |||
43 | /**************************************************************************** | ||
44 | * DEBI functions | ||
45 | ****************************************************************************/ | ||
46 | |||
47 | /* This DEBI code is based on the Stradis driver | ||
48 | by Nathan Laredo <laredo@gnu.org> */ | ||
49 | |||
50 | int av7110_debiwrite(struct av7110 *av7110, u32 config, | ||
51 | int addr, u32 val, int count) | ||
52 | { | ||
53 | struct saa7146_dev *dev = av7110->dev; | ||
54 | |||
55 | if (count <= 0 || count > 32764) { | ||
56 | printk("%s: invalid count %d\n", __func__, count); | ||
57 | return -1; | ||
58 | } | ||
59 | if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { | ||
60 | printk("%s: wait_for_debi_done failed\n", __func__); | ||
61 | return -1; | ||
62 | } | ||
63 | saa7146_write(dev, DEBI_CONFIG, config); | ||
64 | if (count <= 4) /* immediate transfer */ | ||
65 | saa7146_write(dev, DEBI_AD, val); | ||
66 | else /* block transfer */ | ||
67 | saa7146_write(dev, DEBI_AD, av7110->debi_bus); | ||
68 | saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff)); | ||
69 | saa7146_write(dev, MC2, (2 << 16) | 2); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count) | ||
74 | { | ||
75 | struct saa7146_dev *dev = av7110->dev; | ||
76 | u32 result = 0; | ||
77 | |||
78 | if (count > 32764 || count <= 0) { | ||
79 | printk("%s: invalid count %d\n", __func__, count); | ||
80 | return 0; | ||
81 | } | ||
82 | if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { | ||
83 | printk("%s: wait_for_debi_done #1 failed\n", __func__); | ||
84 | return 0; | ||
85 | } | ||
86 | saa7146_write(dev, DEBI_AD, av7110->debi_bus); | ||
87 | saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); | ||
88 | |||
89 | saa7146_write(dev, DEBI_CONFIG, config); | ||
90 | saa7146_write(dev, MC2, (2 << 16) | 2); | ||
91 | if (count > 4) | ||
92 | return count; | ||
93 | if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { | ||
94 | printk("%s: wait_for_debi_done #2 failed\n", __func__); | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | result = saa7146_read(dev, DEBI_AD); | ||
99 | result &= (0xffffffffUL >> ((4 - count) * 8)); | ||
100 | return result; | ||
101 | } | ||
102 | |||
103 | |||
104 | |||
105 | /* av7110 ARM core boot stuff */ | ||
106 | #if 0 | ||
107 | void av7110_reset_arm(struct av7110 *av7110) | ||
108 | { | ||
109 | saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); | ||
110 | |||
111 | /* Disable DEBI and GPIO irq */ | ||
112 | SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03); | ||
113 | SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); | ||
114 | |||
115 | saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI); | ||
116 | msleep(30); /* the firmware needs some time to initialize */ | ||
117 | |||
118 | ARM_ResetMailBox(av7110); | ||
119 | |||
120 | SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); | ||
121 | SAA7146_IER_ENABLE(av7110->dev, MASK_03); | ||
122 | |||
123 | av7110->arm_ready = 1; | ||
124 | dprintk(1, "reset ARM\n"); | ||
125 | } | ||
126 | #endif /* 0 */ | ||
127 | |||
128 | static int waitdebi(struct av7110 *av7110, int adr, int state) | ||
129 | { | ||
130 | int k; | ||
131 | |||
132 | dprintk(4, "%p\n", av7110); | ||
133 | |||
134 | for (k = 0; k < 100; k++) { | ||
135 | if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state) | ||
136 | return 0; | ||
137 | udelay(5); | ||
138 | } | ||
139 | return -ETIMEDOUT; | ||
140 | } | ||
141 | |||
142 | static int load_dram(struct av7110 *av7110, u32 *data, int len) | ||
143 | { | ||
144 | int i; | ||
145 | int blocks, rest; | ||
146 | u32 base, bootblock = AV7110_BOOT_BLOCK; | ||
147 | |||
148 | dprintk(4, "%p\n", av7110); | ||
149 | |||
150 | blocks = len / AV7110_BOOT_MAX_SIZE; | ||
151 | rest = len % AV7110_BOOT_MAX_SIZE; | ||
152 | base = DRAM_START_CODE; | ||
153 | |||
154 | for (i = 0; i < blocks; i++) { | ||
155 | if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { | ||
156 | printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i); | ||
157 | return -ETIMEDOUT; | ||
158 | } | ||
159 | dprintk(4, "writing DRAM block %d\n", i); | ||
160 | mwdebi(av7110, DEBISWAB, bootblock, | ||
161 | ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE); | ||
162 | bootblock ^= 0x1400; | ||
163 | iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); | ||
164 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2); | ||
165 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); | ||
166 | base += AV7110_BOOT_MAX_SIZE; | ||
167 | } | ||
168 | |||
169 | if (rest > 0) { | ||
170 | if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { | ||
171 | printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n"); | ||
172 | return -ETIMEDOUT; | ||
173 | } | ||
174 | if (rest > 4) | ||
175 | mwdebi(av7110, DEBISWAB, bootblock, | ||
176 | ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest); | ||
177 | else | ||
178 | mwdebi(av7110, DEBISWAB, bootblock, | ||
179 | ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4); | ||
180 | |||
181 | iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); | ||
182 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2); | ||
183 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); | ||
184 | } | ||
185 | if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { | ||
186 | printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n"); | ||
187 | return -ETIMEDOUT; | ||
188 | } | ||
189 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2); | ||
190 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); | ||
191 | if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) { | ||
192 | printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n"); | ||
193 | return -ETIMEDOUT; | ||
194 | } | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | |||
199 | /* we cannot write av7110 DRAM directly, so load a bootloader into | ||
200 | * the DPRAM which implements a simple boot protocol */ | ||
201 | int av7110_bootarm(struct av7110 *av7110) | ||
202 | { | ||
203 | const struct firmware *fw; | ||
204 | const char *fw_name = "av7110/bootcode.bin"; | ||
205 | struct saa7146_dev *dev = av7110->dev; | ||
206 | u32 ret; | ||
207 | int i; | ||
208 | |||
209 | dprintk(4, "%p\n", av7110); | ||
210 | |||
211 | av7110->arm_ready = 0; | ||
212 | |||
213 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); | ||
214 | |||
215 | /* Disable DEBI and GPIO irq */ | ||
216 | SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19); | ||
217 | SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); | ||
218 | |||
219 | /* enable DEBI */ | ||
220 | saa7146_write(av7110->dev, MC1, 0x08800880); | ||
221 | saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000); | ||
222 | saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
223 | |||
224 | /* test DEBI */ | ||
225 | iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); | ||
226 | /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */ | ||
227 | iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); | ||
228 | |||
229 | if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) { | ||
230 | printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: " | ||
231 | "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", | ||
232 | ret, 0x10325476); | ||
233 | return -1; | ||
234 | } | ||
235 | for (i = 0; i < 8192; i += 4) | ||
236 | iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4); | ||
237 | dprintk(2, "debi test OK\n"); | ||
238 | |||
239 | /* boot */ | ||
240 | dprintk(1, "load boot code\n"); | ||
241 | saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO); | ||
242 | //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT); | ||
243 | //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); | ||
244 | |||
245 | ret = request_firmware(&fw, fw_name, &dev->pci->dev); | ||
246 | if (ret) { | ||
247 | printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n", | ||
248 | fw_name); | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size); | ||
253 | release_firmware(fw); | ||
254 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); | ||
255 | |||
256 | if (saa7146_wait_for_debi_done(av7110->dev, 1)) { | ||
257 | printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " | ||
258 | "saa7146_wait_for_debi_done() timed out\n"); | ||
259 | return -ETIMEDOUT; | ||
260 | } | ||
261 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); | ||
262 | mdelay(1); | ||
263 | |||
264 | dprintk(1, "load dram code\n"); | ||
265 | if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) { | ||
266 | printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " | ||
267 | "load_dram() failed\n"); | ||
268 | return -1; | ||
269 | } | ||
270 | |||
271 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); | ||
272 | mdelay(1); | ||
273 | |||
274 | dprintk(1, "load dpram code\n"); | ||
275 | mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram); | ||
276 | |||
277 | if (saa7146_wait_for_debi_done(av7110->dev, 1)) { | ||
278 | printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " | ||
279 | "saa7146_wait_for_debi_done() timed out after loading DRAM\n"); | ||
280 | return -ETIMEDOUT; | ||
281 | } | ||
282 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); | ||
283 | msleep(30); /* the firmware needs some time to initialize */ | ||
284 | |||
285 | //ARM_ClearIrq(av7110); | ||
286 | ARM_ResetMailBox(av7110); | ||
287 | SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); | ||
288 | SAA7146_IER_ENABLE(av7110->dev, MASK_03); | ||
289 | |||
290 | av7110->arm_errors = 0; | ||
291 | av7110->arm_ready = 1; | ||
292 | return 0; | ||
293 | } | ||
294 | MODULE_FIRMWARE("av7110/bootcode.bin"); | ||
295 | |||
296 | /**************************************************************************** | ||
297 | * DEBI command polling | ||
298 | ****************************************************************************/ | ||
299 | |||
300 | int av7110_wait_msgstate(struct av7110 *av7110, u16 flags) | ||
301 | { | ||
302 | unsigned long start; | ||
303 | u32 stat; | ||
304 | int err; | ||
305 | |||
306 | if (FW_VERSION(av7110->arm_app) <= 0x261c) { | ||
307 | /* not supported by old firmware */ | ||
308 | msleep(50); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | /* new firmware */ | ||
313 | start = jiffies; | ||
314 | for (;;) { | ||
315 | err = time_after(jiffies, start + ARM_WAIT_FREE); | ||
316 | if (mutex_lock_interruptible(&av7110->dcomlock)) | ||
317 | return -ERESTARTSYS; | ||
318 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); | ||
319 | mutex_unlock(&av7110->dcomlock); | ||
320 | if ((stat & flags) == 0) | ||
321 | break; | ||
322 | if (err) { | ||
323 | printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n", | ||
324 | __func__, stat & flags); | ||
325 | return -ETIMEDOUT; | ||
326 | } | ||
327 | msleep(1); | ||
328 | } | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | ||
333 | { | ||
334 | int i; | ||
335 | unsigned long start; | ||
336 | char *type = NULL; | ||
337 | u16 flags[2] = {0, 0}; | ||
338 | u32 stat; | ||
339 | int err; | ||
340 | |||
341 | // dprintk(4, "%p\n", av7110); | ||
342 | |||
343 | if (!av7110->arm_ready) { | ||
344 | dprintk(1, "arm not ready.\n"); | ||
345 | return -ENXIO; | ||
346 | } | ||
347 | |||
348 | start = jiffies; | ||
349 | while (1) { | ||
350 | err = time_after(jiffies, start + ARM_WAIT_FREE); | ||
351 | if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) | ||
352 | break; | ||
353 | if (err) { | ||
354 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__); | ||
355 | av7110->arm_errors++; | ||
356 | return -ETIMEDOUT; | ||
357 | } | ||
358 | msleep(1); | ||
359 | } | ||
360 | |||
361 | if (FW_VERSION(av7110->arm_app) <= 0x261f) | ||
362 | wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2); | ||
363 | |||
364 | #ifndef _NOHANDSHAKE | ||
365 | start = jiffies; | ||
366 | while (1) { | ||
367 | err = time_after(jiffies, start + ARM_WAIT_SHAKE); | ||
368 | if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) | ||
369 | break; | ||
370 | if (err) { | ||
371 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__); | ||
372 | return -ETIMEDOUT; | ||
373 | } | ||
374 | msleep(1); | ||
375 | } | ||
376 | #endif | ||
377 | |||
378 | switch ((buf[0] >> 8) & 0xff) { | ||
379 | case COMTYPE_PIDFILTER: | ||
380 | case COMTYPE_ENCODER: | ||
381 | case COMTYPE_REC_PLAY: | ||
382 | case COMTYPE_MPEGDECODER: | ||
383 | type = "MSG"; | ||
384 | flags[0] = GPMQOver; | ||
385 | flags[1] = GPMQFull; | ||
386 | break; | ||
387 | case COMTYPE_OSD: | ||
388 | type = "OSD"; | ||
389 | flags[0] = OSDQOver; | ||
390 | flags[1] = OSDQFull; | ||
391 | break; | ||
392 | case COMTYPE_MISC: | ||
393 | if (FW_VERSION(av7110->arm_app) >= 0x261d) { | ||
394 | type = "MSG"; | ||
395 | flags[0] = GPMQOver; | ||
396 | flags[1] = GPMQBusy; | ||
397 | } | ||
398 | break; | ||
399 | default: | ||
400 | break; | ||
401 | } | ||
402 | |||
403 | if (type != NULL) { | ||
404 | /* non-immediate COMMAND type */ | ||
405 | start = jiffies; | ||
406 | for (;;) { | ||
407 | err = time_after(jiffies, start + ARM_WAIT_FREE); | ||
408 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); | ||
409 | if (stat & flags[0]) { | ||
410 | printk(KERN_ERR "%s: %s QUEUE overflow\n", | ||
411 | __func__, type); | ||
412 | return -1; | ||
413 | } | ||
414 | if ((stat & flags[1]) == 0) | ||
415 | break; | ||
416 | if (err) { | ||
417 | printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", | ||
418 | __func__, type); | ||
419 | av7110->arm_errors++; | ||
420 | return -ETIMEDOUT; | ||
421 | } | ||
422 | msleep(1); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | for (i = 2; i < length; i++) | ||
427 | wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2); | ||
428 | |||
429 | if (length) | ||
430 | wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2); | ||
431 | else | ||
432 | wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2); | ||
433 | |||
434 | wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2); | ||
435 | |||
436 | if (FW_VERSION(av7110->arm_app) <= 0x261f) | ||
437 | wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2); | ||
438 | |||
439 | #ifdef COM_DEBUG | ||
440 | start = jiffies; | ||
441 | while (1) { | ||
442 | err = time_after(jiffies, start + ARM_WAIT_FREE); | ||
443 | if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) | ||
444 | break; | ||
445 | if (err) { | ||
446 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n", | ||
447 | __func__, (buf[0] >> 8) & 0xff); | ||
448 | return -ETIMEDOUT; | ||
449 | } | ||
450 | msleep(1); | ||
451 | } | ||
452 | |||
453 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); | ||
454 | if (stat & GPMQOver) { | ||
455 | printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__); | ||
456 | return -ENOSPC; | ||
457 | } | ||
458 | else if (stat & OSDQOver) { | ||
459 | printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__); | ||
460 | return -ENOSPC; | ||
461 | } | ||
462 | #endif | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | ||
468 | { | ||
469 | int ret; | ||
470 | |||
471 | // dprintk(4, "%p\n", av7110); | ||
472 | |||
473 | if (!av7110->arm_ready) { | ||
474 | dprintk(1, "arm not ready.\n"); | ||
475 | return -1; | ||
476 | } | ||
477 | if (mutex_lock_interruptible(&av7110->dcomlock)) | ||
478 | return -ERESTARTSYS; | ||
479 | |||
480 | ret = __av7110_send_fw_cmd(av7110, buf, length); | ||
481 | mutex_unlock(&av7110->dcomlock); | ||
482 | if (ret && ret!=-ERESTARTSYS) | ||
483 | printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", | ||
484 | __func__, ret); | ||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...) | ||
489 | { | ||
490 | va_list args; | ||
491 | u16 buf[num + 2]; | ||
492 | int i, ret; | ||
493 | |||
494 | // dprintk(4, "%p\n", av7110); | ||
495 | |||
496 | buf[0] = ((type << 8) | com); | ||
497 | buf[1] = num; | ||
498 | |||
499 | if (num) { | ||
500 | va_start(args, num); | ||
501 | for (i = 0; i < num; i++) | ||
502 | buf[i + 2] = va_arg(args, u32); | ||
503 | va_end(args); | ||
504 | } | ||
505 | |||
506 | ret = av7110_send_fw_cmd(av7110, buf, num + 2); | ||
507 | if (ret && ret != -ERESTARTSYS) | ||
508 | printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret); | ||
509 | return ret; | ||
510 | } | ||
511 | |||
512 | #if 0 | ||
513 | int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len) | ||
514 | { | ||
515 | int i, ret; | ||
516 | u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom), | ||
517 | 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
518 | |||
519 | dprintk(4, "%p\n", av7110); | ||
520 | |||
521 | for(i = 0; i < len && i < 32; i++) | ||
522 | { | ||
523 | if(i % 2 == 0) | ||
524 | cmd[(i / 2) + 2] = (u16)(buf[i]) << 8; | ||
525 | else | ||
526 | cmd[(i / 2) + 2] |= buf[i]; | ||
527 | } | ||
528 | |||
529 | ret = av7110_send_fw_cmd(av7110, cmd, 18); | ||
530 | if (ret && ret != -ERESTARTSYS) | ||
531 | printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret); | ||
532 | return ret; | ||
533 | } | ||
534 | #endif /* 0 */ | ||
535 | |||
536 | int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | ||
537 | int request_buf_len, u16 *reply_buf, int reply_buf_len) | ||
538 | { | ||
539 | int err; | ||
540 | s16 i; | ||
541 | unsigned long start; | ||
542 | #ifdef COM_DEBUG | ||
543 | u32 stat; | ||
544 | #endif | ||
545 | |||
546 | dprintk(4, "%p\n", av7110); | ||
547 | |||
548 | if (!av7110->arm_ready) { | ||
549 | dprintk(1, "arm not ready.\n"); | ||
550 | return -1; | ||
551 | } | ||
552 | |||
553 | if (mutex_lock_interruptible(&av7110->dcomlock)) | ||
554 | return -ERESTARTSYS; | ||
555 | |||
556 | if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) { | ||
557 | mutex_unlock(&av7110->dcomlock); | ||
558 | printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err); | ||
559 | return err; | ||
560 | } | ||
561 | |||
562 | start = jiffies; | ||
563 | while (1) { | ||
564 | err = time_after(jiffies, start + ARM_WAIT_FREE); | ||
565 | if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) | ||
566 | break; | ||
567 | if (err) { | ||
568 | printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__); | ||
569 | mutex_unlock(&av7110->dcomlock); | ||
570 | return -ETIMEDOUT; | ||
571 | } | ||
572 | #ifdef _NOHANDSHAKE | ||
573 | msleep(1); | ||
574 | #endif | ||
575 | } | ||
576 | |||
577 | #ifndef _NOHANDSHAKE | ||
578 | start = jiffies; | ||
579 | while (1) { | ||
580 | err = time_after(jiffies, start + ARM_WAIT_SHAKE); | ||
581 | if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) | ||
582 | break; | ||
583 | if (err) { | ||
584 | printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__); | ||
585 | mutex_unlock(&av7110->dcomlock); | ||
586 | return -ETIMEDOUT; | ||
587 | } | ||
588 | msleep(1); | ||
589 | } | ||
590 | #endif | ||
591 | |||
592 | #ifdef COM_DEBUG | ||
593 | stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); | ||
594 | if (stat & GPMQOver) { | ||
595 | printk(KERN_ERR "%s: GPMQOver\n", __func__); | ||
596 | mutex_unlock(&av7110->dcomlock); | ||
597 | return -1; | ||
598 | } | ||
599 | else if (stat & OSDQOver) { | ||
600 | printk(KERN_ERR "%s: OSDQOver\n", __func__); | ||
601 | mutex_unlock(&av7110->dcomlock); | ||
602 | return -1; | ||
603 | } | ||
604 | #endif | ||
605 | |||
606 | for (i = 0; i < reply_buf_len; i++) | ||
607 | reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2); | ||
608 | |||
609 | mutex_unlock(&av7110->dcomlock); | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length) | ||
614 | { | ||
615 | int ret; | ||
616 | ret = av7110_fw_request(av7110, &tag, 0, buf, length); | ||
617 | if (ret) | ||
618 | printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret); | ||
619 | return ret; | ||
620 | } | ||
621 | |||
622 | |||
623 | /**************************************************************************** | ||
624 | * Firmware commands | ||
625 | ****************************************************************************/ | ||
626 | |||
627 | /* get version of the firmware ROM, RTSL, video ucode and ARM application */ | ||
628 | int av7110_firmversion(struct av7110 *av7110) | ||
629 | { | ||
630 | u16 buf[20]; | ||
631 | u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion); | ||
632 | |||
633 | dprintk(4, "%p\n", av7110); | ||
634 | |||
635 | if (av7110_fw_query(av7110, tag, buf, 16)) { | ||
636 | printk("dvb-ttpci: failed to boot firmware @ card %d\n", | ||
637 | av7110->dvb_adapter.num); | ||
638 | return -EIO; | ||
639 | } | ||
640 | |||
641 | av7110->arm_fw = (buf[0] << 16) + buf[1]; | ||
642 | av7110->arm_rtsl = (buf[2] << 16) + buf[3]; | ||
643 | av7110->arm_vid = (buf[4] << 16) + buf[5]; | ||
644 | av7110->arm_app = (buf[6] << 16) + buf[7]; | ||
645 | av7110->avtype = (buf[8] << 16) + buf[9]; | ||
646 | |||
647 | printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n", | ||
648 | av7110->dvb_adapter.num, av7110->arm_fw, | ||
649 | av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); | ||
650 | |||
651 | /* print firmware capabilities */ | ||
652 | if (FW_CI_LL_SUPPORT(av7110->arm_app)) | ||
653 | printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n", | ||
654 | av7110->dvb_adapter.num); | ||
655 | else | ||
656 | printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n", | ||
657 | av7110->dvb_adapter.num); | ||
658 | |||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | |||
663 | int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst) | ||
664 | { | ||
665 | int i, ret; | ||
666 | u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC), | ||
667 | 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
668 | |||
669 | dprintk(4, "%p\n", av7110); | ||
670 | |||
671 | if (len > 10) | ||
672 | len = 10; | ||
673 | |||
674 | buf[1] = len + 2; | ||
675 | buf[2] = len; | ||
676 | |||
677 | if (burst != -1) | ||
678 | buf[3] = burst ? 0x01 : 0x00; | ||
679 | else | ||
680 | buf[3] = 0xffff; | ||
681 | |||
682 | for (i = 0; i < len; i++) | ||
683 | buf[i + 4] = msg[i]; | ||
684 | |||
685 | ret = av7110_send_fw_cmd(av7110, buf, 18); | ||
686 | if (ret && ret!=-ERESTARTSYS) | ||
687 | printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret); | ||
688 | return ret; | ||
689 | } | ||
690 | |||
691 | |||
692 | #ifdef CONFIG_DVB_AV7110_OSD | ||
693 | |||
694 | static inline int SetColorBlend(struct av7110 *av7110, u8 windownr) | ||
695 | { | ||
696 | return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr); | ||
697 | } | ||
698 | |||
699 | static inline int SetBlend_(struct av7110 *av7110, u8 windownr, | ||
700 | enum av7110_osd_palette_type colordepth, u16 index, u8 blending) | ||
701 | { | ||
702 | return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4, | ||
703 | windownr, colordepth, index, blending); | ||
704 | } | ||
705 | |||
706 | static inline int SetColor_(struct av7110 *av7110, u8 windownr, | ||
707 | enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo) | ||
708 | { | ||
709 | return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5, | ||
710 | windownr, colordepth, index, colorhi, colorlo); | ||
711 | } | ||
712 | |||
713 | static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize, | ||
714 | u16 colorfg, u16 colorbg) | ||
715 | { | ||
716 | return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4, | ||
717 | windownr, fontsize, colorfg, colorbg); | ||
718 | } | ||
719 | |||
720 | static int FlushText(struct av7110 *av7110) | ||
721 | { | ||
722 | unsigned long start; | ||
723 | int err; | ||
724 | |||
725 | if (mutex_lock_interruptible(&av7110->dcomlock)) | ||
726 | return -ERESTARTSYS; | ||
727 | start = jiffies; | ||
728 | while (1) { | ||
729 | err = time_after(jiffies, start + ARM_WAIT_OSD); | ||
730 | if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) | ||
731 | break; | ||
732 | if (err) { | ||
733 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", | ||
734 | __func__); | ||
735 | mutex_unlock(&av7110->dcomlock); | ||
736 | return -ETIMEDOUT; | ||
737 | } | ||
738 | msleep(1); | ||
739 | } | ||
740 | mutex_unlock(&av7110->dcomlock); | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf) | ||
745 | { | ||
746 | int i, ret; | ||
747 | unsigned long start; | ||
748 | int length = strlen(buf) + 1; | ||
749 | u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y }; | ||
750 | |||
751 | if (mutex_lock_interruptible(&av7110->dcomlock)) | ||
752 | return -ERESTARTSYS; | ||
753 | |||
754 | start = jiffies; | ||
755 | while (1) { | ||
756 | ret = time_after(jiffies, start + ARM_WAIT_OSD); | ||
757 | if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) | ||
758 | break; | ||
759 | if (ret) { | ||
760 | printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", | ||
761 | __func__); | ||
762 | mutex_unlock(&av7110->dcomlock); | ||
763 | return -ETIMEDOUT; | ||
764 | } | ||
765 | msleep(1); | ||
766 | } | ||
767 | #ifndef _NOHANDSHAKE | ||
768 | start = jiffies; | ||
769 | while (1) { | ||
770 | ret = time_after(jiffies, start + ARM_WAIT_SHAKE); | ||
771 | if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) | ||
772 | break; | ||
773 | if (ret) { | ||
774 | printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", | ||
775 | __func__); | ||
776 | mutex_unlock(&av7110->dcomlock); | ||
777 | return -ETIMEDOUT; | ||
778 | } | ||
779 | msleep(1); | ||
780 | } | ||
781 | #endif | ||
782 | for (i = 0; i < length / 2; i++) | ||
783 | wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, | ||
784 | swab16(*(u16 *)(buf + 2 * i)), 2); | ||
785 | if (length & 1) | ||
786 | wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2); | ||
787 | ret = __av7110_send_fw_cmd(av7110, cbuf, 5); | ||
788 | mutex_unlock(&av7110->dcomlock); | ||
789 | if (ret && ret!=-ERESTARTSYS) | ||
790 | printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret); | ||
791 | return ret; | ||
792 | } | ||
793 | |||
794 | static inline int DrawLine(struct av7110 *av7110, u8 windownr, | ||
795 | u16 x, u16 y, u16 dx, u16 dy, u16 color) | ||
796 | { | ||
797 | return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6, | ||
798 | windownr, x, y, dx, dy, color); | ||
799 | } | ||
800 | |||
801 | static inline int DrawBlock(struct av7110 *av7110, u8 windownr, | ||
802 | u16 x, u16 y, u16 dx, u16 dy, u16 color) | ||
803 | { | ||
804 | return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6, | ||
805 | windownr, x, y, dx, dy, color); | ||
806 | } | ||
807 | |||
808 | static inline int HideWindow(struct av7110 *av7110, u8 windownr) | ||
809 | { | ||
810 | return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr); | ||
811 | } | ||
812 | |||
813 | static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y) | ||
814 | { | ||
815 | return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y); | ||
816 | } | ||
817 | |||
818 | static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y) | ||
819 | { | ||
820 | return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y); | ||
821 | } | ||
822 | |||
823 | static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr) | ||
824 | { | ||
825 | return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr); | ||
826 | } | ||
827 | |||
828 | static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr, | ||
829 | osd_raw_window_t disptype, | ||
830 | u16 width, u16 height) | ||
831 | { | ||
832 | return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4, | ||
833 | windownr, disptype, width, height); | ||
834 | } | ||
835 | |||
836 | |||
837 | static enum av7110_osd_palette_type bpp2pal[8] = { | ||
838 | Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit | ||
839 | }; | ||
840 | static osd_raw_window_t bpp2bit[8] = { | ||
841 | OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8 | ||
842 | }; | ||
843 | |||
844 | static inline int WaitUntilBmpLoaded(struct av7110 *av7110) | ||
845 | { | ||
846 | int ret = wait_event_timeout(av7110->bmpq, | ||
847 | av7110->bmp_state != BMP_LOADING, 10*HZ); | ||
848 | if (ret == 0) { | ||
849 | printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n", | ||
850 | ret, av7110->bmp_state); | ||
851 | av7110->bmp_state = BMP_NONE; | ||
852 | return -ETIMEDOUT; | ||
853 | } | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static inline int LoadBitmap(struct av7110 *av7110, | ||
858 | u16 dx, u16 dy, int inc, u8 __user * data) | ||
859 | { | ||
860 | u16 format; | ||
861 | int bpp; | ||
862 | int i; | ||
863 | int d, delta; | ||
864 | u8 c; | ||
865 | int ret; | ||
866 | |||
867 | dprintk(4, "%p\n", av7110); | ||
868 | |||
869 | format = bpp2bit[av7110->osdbpp[av7110->osdwin]]; | ||
870 | |||
871 | av7110->bmp_state = BMP_LOADING; | ||
872 | if (format == OSD_BITMAP8) { | ||
873 | bpp=8; delta = 1; | ||
874 | } else if (format == OSD_BITMAP4) { | ||
875 | bpp=4; delta = 2; | ||
876 | } else if (format == OSD_BITMAP2) { | ||
877 | bpp=2; delta = 4; | ||
878 | } else if (format == OSD_BITMAP1) { | ||
879 | bpp=1; delta = 8; | ||
880 | } else { | ||
881 | av7110->bmp_state = BMP_NONE; | ||
882 | return -EINVAL; | ||
883 | } | ||
884 | av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8; | ||
885 | av7110->bmpp = 0; | ||
886 | if (av7110->bmplen > 32768) { | ||
887 | av7110->bmp_state = BMP_NONE; | ||
888 | return -EINVAL; | ||
889 | } | ||
890 | for (i = 0; i < dy; i++) { | ||
891 | if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) { | ||
892 | av7110->bmp_state = BMP_NONE; | ||
893 | return -EINVAL; | ||
894 | } | ||
895 | } | ||
896 | if (format != OSD_BITMAP8) { | ||
897 | for (i = 0; i < dx * dy / delta; i++) { | ||
898 | c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1]; | ||
899 | for (d = delta - 2; d >= 0; d--) { | ||
900 | c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d] | ||
901 | << ((delta - d - 1) * bpp)); | ||
902 | ((u8 *)av7110->bmpbuf)[1024 + i] = c; | ||
903 | } | ||
904 | } | ||
905 | } | ||
906 | av7110->bmplen += 1024; | ||
907 | dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen); | ||
908 | ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy); | ||
909 | if (!ret) | ||
910 | ret = WaitUntilBmpLoaded(av7110); | ||
911 | return ret; | ||
912 | } | ||
913 | |||
914 | static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y) | ||
915 | { | ||
916 | dprintk(4, "%p\n", av7110); | ||
917 | |||
918 | return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0); | ||
919 | } | ||
920 | |||
921 | static inline int ReleaseBitmap(struct av7110 *av7110) | ||
922 | { | ||
923 | dprintk(4, "%p\n", av7110); | ||
924 | |||
925 | if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e) | ||
926 | return -1; | ||
927 | if (av7110->bmp_state == BMP_LOADING) | ||
928 | dprintk(1,"ReleaseBitmap called while BMP_LOADING\n"); | ||
929 | av7110->bmp_state = BMP_NONE; | ||
930 | return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0); | ||
931 | } | ||
932 | |||
933 | static u32 RGB2YUV(u16 R, u16 G, u16 B) | ||
934 | { | ||
935 | u16 y, u, v; | ||
936 | u16 Y, Cr, Cb; | ||
937 | |||
938 | y = R * 77 + G * 150 + B * 29; /* Luma=0.299R+0.587G+0.114B 0..65535 */ | ||
939 | u = 2048 + B * 8 -(y >> 5); /* Cr 0..4095 */ | ||
940 | v = 2048 + R * 8 -(y >> 5); /* Cb 0..4095 */ | ||
941 | |||
942 | Y = y / 256; | ||
943 | Cb = u / 16; | ||
944 | Cr = v / 16; | ||
945 | |||
946 | return Cr | (Cb << 16) | (Y << 8); | ||
947 | } | ||
948 | |||
949 | static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend) | ||
950 | { | ||
951 | int ret; | ||
952 | |||
953 | u16 ch, cl; | ||
954 | u32 yuv; | ||
955 | |||
956 | yuv = blend ? RGB2YUV(r,g,b) : 0; | ||
957 | cl = (yuv & 0xffff); | ||
958 | ch = ((yuv >> 16) & 0xffff); | ||
959 | ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], | ||
960 | color, ch, cl); | ||
961 | if (!ret) | ||
962 | ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], | ||
963 | color, ((blend >> 4) & 0x0f)); | ||
964 | return ret; | ||
965 | } | ||
966 | |||
967 | static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last) | ||
968 | { | ||
969 | int i; | ||
970 | int length = last - first + 1; | ||
971 | |||
972 | if (length * 4 > DATA_BUFF3_SIZE) | ||
973 | return -EINVAL; | ||
974 | |||
975 | for (i = 0; i < length; i++) { | ||
976 | u32 color, blend, yuv; | ||
977 | |||
978 | if (get_user(color, colors + i)) | ||
979 | return -EFAULT; | ||
980 | blend = (color & 0xF0000000) >> 4; | ||
981 | yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF, | ||
982 | (color >> 16) & 0xFF) | blend : 0; | ||
983 | yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); | ||
984 | wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4); | ||
985 | } | ||
986 | return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4, | ||
987 | av7110->osdwin, | ||
988 | bpp2pal[av7110->osdbpp[av7110->osdwin]], | ||
989 | first, last); | ||
990 | } | ||
991 | |||
992 | static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, | ||
993 | int x1, int y1, int inc, u8 __user * data) | ||
994 | { | ||
995 | uint w, h, bpp, bpl, size, lpb, bnum, brest; | ||
996 | int i; | ||
997 | int rc,release_rc; | ||
998 | |||
999 | w = x1 - x0 + 1; | ||
1000 | h = y1 - y0 + 1; | ||
1001 | if (inc <= 0) | ||
1002 | inc = w; | ||
1003 | if (w <= 0 || w > 720 || h <= 0 || h > 576) | ||
1004 | return -EINVAL; | ||
1005 | bpp = av7110->osdbpp[av7110->osdwin] + 1; | ||
1006 | bpl = ((w * bpp + 7) & ~7) / 8; | ||
1007 | size = h * bpl; | ||
1008 | lpb = (32 * 1024) / bpl; | ||
1009 | bnum = size / (lpb * bpl); | ||
1010 | brest = size - bnum * lpb * bpl; | ||
1011 | |||
1012 | if (av7110->bmp_state == BMP_LOADING) { | ||
1013 | /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */ | ||
1014 | BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e); | ||
1015 | rc = WaitUntilBmpLoaded(av7110); | ||
1016 | if (rc) | ||
1017 | return rc; | ||
1018 | /* just continue. This should work for all fw versions | ||
1019 | * if bnum==1 && !brest && LoadBitmap was successful | ||
1020 | */ | ||
1021 | } | ||
1022 | |||
1023 | rc = 0; | ||
1024 | for (i = 0; i < bnum; i++) { | ||
1025 | rc = LoadBitmap(av7110, w, lpb, inc, data); | ||
1026 | if (rc) | ||
1027 | break; | ||
1028 | rc = BlitBitmap(av7110, x0, y0 + i * lpb); | ||
1029 | if (rc) | ||
1030 | break; | ||
1031 | data += lpb * inc; | ||
1032 | } | ||
1033 | if (!rc && brest) { | ||
1034 | rc = LoadBitmap(av7110, w, brest / bpl, inc, data); | ||
1035 | if (!rc) | ||
1036 | rc = BlitBitmap(av7110, x0, y0 + bnum * lpb); | ||
1037 | } | ||
1038 | release_rc = ReleaseBitmap(av7110); | ||
1039 | if (!rc) | ||
1040 | rc = release_rc; | ||
1041 | if (rc) | ||
1042 | dprintk(1,"returns %d\n",rc); | ||
1043 | return rc; | ||
1044 | } | ||
1045 | |||
1046 | int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) | ||
1047 | { | ||
1048 | int ret; | ||
1049 | |||
1050 | if (mutex_lock_interruptible(&av7110->osd_mutex)) | ||
1051 | return -ERESTARTSYS; | ||
1052 | |||
1053 | switch (dc->cmd) { | ||
1054 | case OSD_Close: | ||
1055 | ret = DestroyOSDWindow(av7110, av7110->osdwin); | ||
1056 | break; | ||
1057 | case OSD_Open: | ||
1058 | av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7; | ||
1059 | ret = CreateOSDWindow(av7110, av7110->osdwin, | ||
1060 | bpp2bit[av7110->osdbpp[av7110->osdwin]], | ||
1061 | dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); | ||
1062 | if (ret) | ||
1063 | break; | ||
1064 | if (!dc->data) { | ||
1065 | ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); | ||
1066 | if (ret) | ||
1067 | break; | ||
1068 | ret = SetColorBlend(av7110, av7110->osdwin); | ||
1069 | } | ||
1070 | break; | ||
1071 | case OSD_Show: | ||
1072 | ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0); | ||
1073 | break; | ||
1074 | case OSD_Hide: | ||
1075 | ret = HideWindow(av7110, av7110->osdwin); | ||
1076 | break; | ||
1077 | case OSD_Clear: | ||
1078 | ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0); | ||
1079 | break; | ||
1080 | case OSD_Fill: | ||
1081 | ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color); | ||
1082 | break; | ||
1083 | case OSD_SetColor: | ||
1084 | ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); | ||
1085 | break; | ||
1086 | case OSD_SetPalette: | ||
1087 | if (FW_VERSION(av7110->arm_app) >= 0x2618) | ||
1088 | ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0); | ||
1089 | else { | ||
1090 | int i, len = dc->x0-dc->color+1; | ||
1091 | u8 __user *colors = (u8 __user *)dc->data; | ||
1092 | u8 r, g = 0, b = 0, blend = 0; | ||
1093 | ret = 0; | ||
1094 | for (i = 0; i<len; i++) { | ||
1095 | if (get_user(r, colors + i * 4) || | ||
1096 | get_user(g, colors + i * 4 + 1) || | ||
1097 | get_user(b, colors + i * 4 + 2) || | ||
1098 | get_user(blend, colors + i * 4 + 3)) { | ||
1099 | ret = -EFAULT; | ||
1100 | break; | ||
1101 | } | ||
1102 | ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend); | ||
1103 | if (ret) | ||
1104 | break; | ||
1105 | } | ||
1106 | } | ||
1107 | break; | ||
1108 | case OSD_SetPixel: | ||
1109 | ret = DrawLine(av7110, av7110->osdwin, | ||
1110 | dc->x0, dc->y0, 0, 0, dc->color); | ||
1111 | break; | ||
1112 | case OSD_SetRow: | ||
1113 | dc->y1 = dc->y0; | ||
1114 | /* fall through */ | ||
1115 | case OSD_SetBlock: | ||
1116 | ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data); | ||
1117 | break; | ||
1118 | case OSD_FillRow: | ||
1119 | ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, | ||
1120 | dc->x1-dc->x0+1, dc->y1, dc->color); | ||
1121 | break; | ||
1122 | case OSD_FillBlock: | ||
1123 | ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, | ||
1124 | dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color); | ||
1125 | break; | ||
1126 | case OSD_Line: | ||
1127 | ret = DrawLine(av7110, av7110->osdwin, | ||
1128 | dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color); | ||
1129 | break; | ||
1130 | case OSD_Text: | ||
1131 | { | ||
1132 | char textbuf[240]; | ||
1133 | |||
1134 | if (strncpy_from_user(textbuf, dc->data, 240) < 0) { | ||
1135 | ret = -EFAULT; | ||
1136 | break; | ||
1137 | } | ||
1138 | textbuf[239] = 0; | ||
1139 | if (dc->x1 > 3) | ||
1140 | dc->x1 = 3; | ||
1141 | ret = SetFont(av7110, av7110->osdwin, dc->x1, | ||
1142 | (u16) (dc->color & 0xffff), (u16) (dc->color >> 16)); | ||
1143 | if (!ret) | ||
1144 | ret = FlushText(av7110); | ||
1145 | if (!ret) | ||
1146 | ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf); | ||
1147 | break; | ||
1148 | } | ||
1149 | case OSD_SetWindow: | ||
1150 | if (dc->x0 < 1 || dc->x0 > 7) | ||
1151 | ret = -EINVAL; | ||
1152 | else { | ||
1153 | av7110->osdwin = dc->x0; | ||
1154 | ret = 0; | ||
1155 | } | ||
1156 | break; | ||
1157 | case OSD_MoveWindow: | ||
1158 | ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); | ||
1159 | if (!ret) | ||
1160 | ret = SetColorBlend(av7110, av7110->osdwin); | ||
1161 | break; | ||
1162 | case OSD_OpenRaw: | ||
1163 | if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) { | ||
1164 | ret = -EINVAL; | ||
1165 | break; | ||
1166 | } | ||
1167 | if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) | ||
1168 | av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1; | ||
1169 | else | ||
1170 | av7110->osdbpp[av7110->osdwin] = 0; | ||
1171 | ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color, | ||
1172 | dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); | ||
1173 | if (ret) | ||
1174 | break; | ||
1175 | if (!dc->data) { | ||
1176 | ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); | ||
1177 | if (!ret) | ||
1178 | ret = SetColorBlend(av7110, av7110->osdwin); | ||
1179 | } | ||
1180 | break; | ||
1181 | default: | ||
1182 | ret = -EINVAL; | ||
1183 | break; | ||
1184 | } | ||
1185 | |||
1186 | mutex_unlock(&av7110->osd_mutex); | ||
1187 | if (ret==-ERESTARTSYS) | ||
1188 | dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd); | ||
1189 | else if (ret) | ||
1190 | dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret); | ||
1191 | |||
1192 | return ret; | ||
1193 | } | ||
1194 | |||
1195 | int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap) | ||
1196 | { | ||
1197 | switch (cap->cmd) { | ||
1198 | case OSD_CAP_MEMSIZE: | ||
1199 | if (FW_4M_SDRAM(av7110->arm_app)) | ||
1200 | cap->val = 1000000; | ||
1201 | else | ||
1202 | cap->val = 92000; | ||
1203 | return 0; | ||
1204 | default: | ||
1205 | return -EINVAL; | ||
1206 | } | ||
1207 | } | ||
1208 | #endif /* CONFIG_DVB_AV7110_OSD */ | ||
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h deleted file mode 100644 index 1634aba5cb84..000000000000 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ /dev/null | |||
@@ -1,495 +0,0 @@ | |||
1 | #ifndef _AV7110_HW_H_ | ||
2 | #define _AV7110_HW_H_ | ||
3 | |||
4 | #include "av7110.h" | ||
5 | |||
6 | /* DEBI transfer mode defs */ | ||
7 | |||
8 | #define DEBINOSWAP 0x000e0000 | ||
9 | #define DEBISWAB 0x001e0000 | ||
10 | #define DEBISWAP 0x002e0000 | ||
11 | |||
12 | #define ARM_WAIT_FREE (HZ) | ||
13 | #define ARM_WAIT_SHAKE (HZ/5) | ||
14 | #define ARM_WAIT_OSD (HZ) | ||
15 | |||
16 | |||
17 | enum av7110_bootstate | ||
18 | { | ||
19 | BOOTSTATE_BUFFER_EMPTY = 0, | ||
20 | BOOTSTATE_BUFFER_FULL = 1, | ||
21 | BOOTSTATE_AV7110_BOOT_COMPLETE = 2 | ||
22 | }; | ||
23 | |||
24 | enum av7110_type_rec_play_format | ||
25 | { RP_None, | ||
26 | AudioPES, | ||
27 | AudioMp2, | ||
28 | AudioPCM, | ||
29 | VideoPES, | ||
30 | AV_PES | ||
31 | }; | ||
32 | |||
33 | enum av7110_osd_palette_type | ||
34 | { | ||
35 | NoPalet = 0, /* No palette */ | ||
36 | Pal1Bit = 2, /* 2 colors for 1 Bit Palette */ | ||
37 | Pal2Bit = 4, /* 4 colors for 2 bit palette */ | ||
38 | Pal4Bit = 16, /* 16 colors for 4 bit palette */ | ||
39 | Pal8Bit = 256 /* 256 colors for 16 bit palette */ | ||
40 | }; | ||
41 | |||
42 | /* switch defines */ | ||
43 | #define SB_GPIO 3 | ||
44 | #define SB_OFF SAA7146_GPIO_OUTLO /* SlowBlank off (TV-Mode) */ | ||
45 | #define SB_ON SAA7146_GPIO_INPUT /* SlowBlank on (AV-Mode) */ | ||
46 | #define SB_WIDE SAA7146_GPIO_OUTHI /* SlowBlank 6V (16/9-Mode) (not implemented) */ | ||
47 | |||
48 | #define FB_GPIO 1 | ||
49 | #define FB_OFF SAA7146_GPIO_LO /* FastBlank off (CVBS-Mode) */ | ||
50 | #define FB_ON SAA7146_GPIO_OUTHI /* FastBlank on (RGB-Mode) */ | ||
51 | #define FB_LOOP SAA7146_GPIO_INPUT /* FastBlank loop-through (PC graphics ???) */ | ||
52 | |||
53 | enum av7110_video_output_mode | ||
54 | { | ||
55 | NO_OUT = 0, /* disable analog output */ | ||
56 | CVBS_RGB_OUT = 1, | ||
57 | CVBS_YC_OUT = 2, | ||
58 | YC_OUT = 3 | ||
59 | }; | ||
60 | |||
61 | /* firmware internal msg q status: */ | ||
62 | #define GPMQFull 0x0001 /* Main Message Queue Full */ | ||
63 | #define GPMQOver 0x0002 /* Main Message Queue Overflow */ | ||
64 | #define HPQFull 0x0004 /* High Priority Msg Queue Full */ | ||
65 | #define HPQOver 0x0008 | ||
66 | #define OSDQFull 0x0010 /* OSD Queue Full */ | ||
67 | #define OSDQOver 0x0020 | ||
68 | #define GPMQBusy 0x0040 /* Queue not empty, FW >= 261d */ | ||
69 | #define HPQBusy 0x0080 | ||
70 | #define OSDQBusy 0x0100 | ||
71 | |||
72 | /* hw section filter flags */ | ||
73 | #define SECTION_EIT 0x01 | ||
74 | #define SECTION_SINGLE 0x00 | ||
75 | #define SECTION_CYCLE 0x02 | ||
76 | #define SECTION_CONTINUOS 0x04 | ||
77 | #define SECTION_MODE 0x06 | ||
78 | #define SECTION_IPMPE 0x0C /* size up to 4k */ | ||
79 | #define SECTION_HIGH_SPEED 0x1C /* larger buffer */ | ||
80 | #define DATA_PIPING_FLAG 0x20 /* for Data Piping Filter */ | ||
81 | |||
82 | #define PBUFSIZE_NONE 0x0000 | ||
83 | #define PBUFSIZE_1P 0x0100 | ||
84 | #define PBUFSIZE_2P 0x0200 | ||
85 | #define PBUFSIZE_1K 0x0300 | ||
86 | #define PBUFSIZE_2K 0x0400 | ||
87 | #define PBUFSIZE_4K 0x0500 | ||
88 | #define PBUFSIZE_8K 0x0600 | ||
89 | #define PBUFSIZE_16K 0x0700 | ||
90 | #define PBUFSIZE_32K 0x0800 | ||
91 | |||
92 | |||
93 | /* firmware command codes */ | ||
94 | enum av7110_osd_command { | ||
95 | WCreate, | ||
96 | WDestroy, | ||
97 | WMoveD, | ||
98 | WMoveA, | ||
99 | WHide, | ||
100 | WTop, | ||
101 | DBox, | ||
102 | DLine, | ||
103 | DText, | ||
104 | Set_Font, | ||
105 | SetColor, | ||
106 | SetBlend, | ||
107 | SetWBlend, | ||
108 | SetCBlend, | ||
109 | SetNonBlend, | ||
110 | LoadBmp, | ||
111 | BlitBmp, | ||
112 | ReleaseBmp, | ||
113 | SetWTrans, | ||
114 | SetWNoTrans, | ||
115 | Set_Palette | ||
116 | }; | ||
117 | |||
118 | enum av7110_pid_command { | ||
119 | MultiPID, | ||
120 | VideoPID, | ||
121 | AudioPID, | ||
122 | InitFilt, | ||
123 | FiltError, | ||
124 | NewVersion, | ||
125 | CacheError, | ||
126 | AddPIDFilter, | ||
127 | DelPIDFilter, | ||
128 | Scan, | ||
129 | SetDescr, | ||
130 | SetIR, | ||
131 | FlushTSQueue | ||
132 | }; | ||
133 | |||
134 | enum av7110_mpeg_command { | ||
135 | SelAudChannels | ||
136 | }; | ||
137 | |||
138 | enum av7110_audio_command { | ||
139 | AudioDAC, | ||
140 | CabADAC, | ||
141 | ON22K, | ||
142 | OFF22K, | ||
143 | MainSwitch, | ||
144 | ADSwitch, | ||
145 | SendDiSEqC, | ||
146 | SetRegister, | ||
147 | SpdifSwitch | ||
148 | }; | ||
149 | |||
150 | enum av7110_request_command { | ||
151 | AudioState, | ||
152 | AudioBuffState, | ||
153 | VideoState1, | ||
154 | VideoState2, | ||
155 | VideoState3, | ||
156 | CrashCounter, | ||
157 | ReqVersion, | ||
158 | ReqVCXO, | ||
159 | ReqRegister, | ||
160 | ReqSecFilterError, | ||
161 | ReqSTC | ||
162 | }; | ||
163 | |||
164 | enum av7110_encoder_command { | ||
165 | SetVidMode, | ||
166 | SetTestMode, | ||
167 | LoadVidCode, | ||
168 | SetMonitorType, | ||
169 | SetPanScanType, | ||
170 | SetFreezeMode, | ||
171 | SetWSSConfig | ||
172 | }; | ||
173 | |||
174 | enum av7110_rec_play_state { | ||
175 | __Record, | ||
176 | __Stop, | ||
177 | __Play, | ||
178 | __Pause, | ||
179 | __Slow, | ||
180 | __FF_IP, | ||
181 | __Scan_I, | ||
182 | __Continue | ||
183 | }; | ||
184 | |||
185 | enum av7110_fw_cmd_misc { | ||
186 | AV7110_FW_VIDEO_ZOOM = 1, | ||
187 | AV7110_FW_VIDEO_COMMAND, | ||
188 | AV7110_FW_AUDIO_COMMAND | ||
189 | }; | ||
190 | |||
191 | enum av7110_command_type { | ||
192 | COMTYPE_NOCOM, | ||
193 | COMTYPE_PIDFILTER, | ||
194 | COMTYPE_MPEGDECODER, | ||
195 | COMTYPE_OSD, | ||
196 | COMTYPE_BMP, | ||
197 | COMTYPE_ENCODER, | ||
198 | COMTYPE_AUDIODAC, | ||
199 | COMTYPE_REQUEST, | ||
200 | COMTYPE_SYSTEM, | ||
201 | COMTYPE_REC_PLAY, | ||
202 | COMTYPE_COMMON_IF, | ||
203 | COMTYPE_PID_FILTER, | ||
204 | COMTYPE_PES, | ||
205 | COMTYPE_TS, | ||
206 | COMTYPE_VIDEO, | ||
207 | COMTYPE_AUDIO, | ||
208 | COMTYPE_CI_LL, | ||
209 | COMTYPE_MISC = 0x80 | ||
210 | }; | ||
211 | |||
212 | #define VID_NONE_PREF 0x00 /* No aspect ration processing preferred */ | ||
213 | #define VID_PAN_SCAN_PREF 0x01 /* Pan and Scan Display preferred */ | ||
214 | #define VID_VERT_COMP_PREF 0x02 /* Vertical compression display preferred */ | ||
215 | #define VID_VC_AND_PS_PREF 0x03 /* PanScan and vertical Compression if allowed */ | ||
216 | #define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */ | ||
217 | |||
218 | /* MPEG video decoder commands */ | ||
219 | #define AV_VIDEO_CMD_STOP 0x000e | ||
220 | #define AV_VIDEO_CMD_PLAY 0x000d | ||
221 | #define AV_VIDEO_CMD_FREEZE 0x0102 | ||
222 | #define AV_VIDEO_CMD_FFWD 0x0016 | ||
223 | #define AV_VIDEO_CMD_SLOW 0x0022 | ||
224 | |||
225 | /* MPEG audio decoder commands */ | ||
226 | #define AUDIO_CMD_MUTE 0x0001 | ||
227 | #define AUDIO_CMD_UNMUTE 0x0002 | ||
228 | #define AUDIO_CMD_PCM16 0x0010 | ||
229 | #define AUDIO_CMD_STEREO 0x0080 | ||
230 | #define AUDIO_CMD_MONO_L 0x0100 | ||
231 | #define AUDIO_CMD_MONO_R 0x0200 | ||
232 | #define AUDIO_CMD_SYNC_OFF 0x000e | ||
233 | #define AUDIO_CMD_SYNC_ON 0x000f | ||
234 | |||
235 | /* firmware data interface codes */ | ||
236 | #define DATA_NONE 0x00 | ||
237 | #define DATA_FSECTION 0x01 | ||
238 | #define DATA_IPMPE 0x02 | ||
239 | #define DATA_MPEG_RECORD 0x03 | ||
240 | #define DATA_DEBUG_MESSAGE 0x04 | ||
241 | #define DATA_COMMON_INTERFACE 0x05 | ||
242 | #define DATA_MPEG_PLAY 0x06 | ||
243 | #define DATA_BMP_LOAD 0x07 | ||
244 | #define DATA_IRCOMMAND 0x08 | ||
245 | #define DATA_PIPING 0x09 | ||
246 | #define DATA_STREAMING 0x0a | ||
247 | #define DATA_CI_GET 0x0b | ||
248 | #define DATA_CI_PUT 0x0c | ||
249 | #define DATA_MPEG_VIDEO_EVENT 0x0d | ||
250 | |||
251 | #define DATA_PES_RECORD 0x10 | ||
252 | #define DATA_PES_PLAY 0x11 | ||
253 | #define DATA_TS_RECORD 0x12 | ||
254 | #define DATA_TS_PLAY 0x13 | ||
255 | |||
256 | /* ancient CI command codes, only two are actually still used | ||
257 | * by the link level CI firmware */ | ||
258 | #define CI_CMD_ERROR 0x00 | ||
259 | #define CI_CMD_ACK 0x01 | ||
260 | #define CI_CMD_SYSTEM_READY 0x02 | ||
261 | #define CI_CMD_KEYPRESS 0x03 | ||
262 | #define CI_CMD_ON_TUNED 0x04 | ||
263 | #define CI_CMD_ON_SWITCH_PROGRAM 0x05 | ||
264 | #define CI_CMD_SECTION_ARRIVED 0x06 | ||
265 | #define CI_CMD_SECTION_TIMEOUT 0x07 | ||
266 | #define CI_CMD_TIME 0x08 | ||
267 | #define CI_CMD_ENTER_MENU 0x09 | ||
268 | #define CI_CMD_FAST_PSI 0x0a | ||
269 | #define CI_CMD_GET_SLOT_INFO 0x0b | ||
270 | |||
271 | #define CI_MSG_NONE 0x00 | ||
272 | #define CI_MSG_CI_INFO 0x01 | ||
273 | #define CI_MSG_MENU 0x02 | ||
274 | #define CI_MSG_LIST 0x03 | ||
275 | #define CI_MSG_TEXT 0x04 | ||
276 | #define CI_MSG_REQUEST_INPUT 0x05 | ||
277 | #define CI_MSG_INPUT_COMPLETE 0x06 | ||
278 | #define CI_MSG_LIST_MORE 0x07 | ||
279 | #define CI_MSG_MENU_MORE 0x08 | ||
280 | #define CI_MSG_CLOSE_MMI_IMM 0x09 | ||
281 | #define CI_MSG_SECTION_REQUEST 0x0a | ||
282 | #define CI_MSG_CLOSE_FILTER 0x0b | ||
283 | #define CI_PSI_COMPLETE 0x0c | ||
284 | #define CI_MODULE_READY 0x0d | ||
285 | #define CI_SWITCH_PRG_REPLY 0x0e | ||
286 | #define CI_MSG_TEXT_MORE 0x0f | ||
287 | |||
288 | #define CI_MSG_CA_PMT 0xe0 | ||
289 | #define CI_MSG_ERROR 0xf0 | ||
290 | |||
291 | |||
292 | /* base address of the dual ported RAM which serves as communication | ||
293 | * area between PCI bus and av7110, | ||
294 | * as seen by the DEBI bus of the saa7146 */ | ||
295 | #define DPRAM_BASE 0x4000 | ||
296 | |||
297 | /* boot protocol area */ | ||
298 | #define AV7110_BOOT_STATE (DPRAM_BASE + 0x3F8) | ||
299 | #define AV7110_BOOT_SIZE (DPRAM_BASE + 0x3FA) | ||
300 | #define AV7110_BOOT_BASE (DPRAM_BASE + 0x3FC) | ||
301 | #define AV7110_BOOT_BLOCK (DPRAM_BASE + 0x400) | ||
302 | #define AV7110_BOOT_MAX_SIZE 0xc00 | ||
303 | |||
304 | /* firmware command protocol area */ | ||
305 | #define IRQ_STATE (DPRAM_BASE + 0x0F4) | ||
306 | #define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6) | ||
307 | #define MSGSTATE (DPRAM_BASE + 0x0F8) | ||
308 | #define COMMAND (DPRAM_BASE + 0x0FC) | ||
309 | #define COM_BUFF (DPRAM_BASE + 0x100) | ||
310 | #define COM_BUFF_SIZE 0x20 | ||
311 | |||
312 | /* various data buffers */ | ||
313 | #define BUFF1_BASE (DPRAM_BASE + 0x120) | ||
314 | #define BUFF1_SIZE 0xE0 | ||
315 | |||
316 | #define DATA_BUFF0_BASE (DPRAM_BASE + 0x200) | ||
317 | #define DATA_BUFF0_SIZE 0x0800 | ||
318 | |||
319 | #define DATA_BUFF1_BASE (DATA_BUFF0_BASE+DATA_BUFF0_SIZE) | ||
320 | #define DATA_BUFF1_SIZE 0x0800 | ||
321 | |||
322 | #define DATA_BUFF2_BASE (DATA_BUFF1_BASE+DATA_BUFF1_SIZE) | ||
323 | #define DATA_BUFF2_SIZE 0x0800 | ||
324 | |||
325 | #define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE) | ||
326 | #define DATA_BUFF3_SIZE 0x0400 | ||
327 | |||
328 | #define Reserved (DPRAM_BASE + 0x1E00) | ||
329 | #define Reserved_SIZE 0x1C0 | ||
330 | |||
331 | |||
332 | /* firmware status area */ | ||
333 | #define STATUS_BASE (DPRAM_BASE + 0x1FC0) | ||
334 | #define STATUS_LOOPS (STATUS_BASE + 0x08) | ||
335 | |||
336 | #define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C) | ||
337 | /* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */ | ||
338 | #define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E) | ||
339 | |||
340 | /* firmware data protocol area */ | ||
341 | #define RX_TYPE (DPRAM_BASE + 0x1FE8) | ||
342 | #define RX_LEN (DPRAM_BASE + 0x1FEA) | ||
343 | #define TX_TYPE (DPRAM_BASE + 0x1FEC) | ||
344 | #define TX_LEN (DPRAM_BASE + 0x1FEE) | ||
345 | |||
346 | #define RX_BUFF (DPRAM_BASE + 0x1FF4) | ||
347 | #define TX_BUFF (DPRAM_BASE + 0x1FF6) | ||
348 | |||
349 | #define HANDSHAKE_REG (DPRAM_BASE + 0x1FF8) | ||
350 | #define COM_IF_LOCK (DPRAM_BASE + 0x1FFA) | ||
351 | |||
352 | #define IRQ_RX (DPRAM_BASE + 0x1FFC) | ||
353 | #define IRQ_TX (DPRAM_BASE + 0x1FFE) | ||
354 | |||
355 | /* used by boot protocol to load firmware into av7110 DRAM */ | ||
356 | #define DRAM_START_CODE 0x2e000404 | ||
357 | #define DRAM_MAX_CODE_SIZE 0x00100000 | ||
358 | |||
359 | /* saa7146 gpio lines */ | ||
360 | #define RESET_LINE 2 | ||
361 | #define DEBI_DONE_LINE 1 | ||
362 | #define ARM_IRQ_LINE 0 | ||
363 | |||
364 | |||
365 | |||
366 | extern int av7110_bootarm(struct av7110 *av7110); | ||
367 | extern int av7110_firmversion(struct av7110 *av7110); | ||
368 | #define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000) | ||
369 | #define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000) | ||
370 | #define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF) | ||
371 | |||
372 | extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags); | ||
373 | extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...); | ||
374 | extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | ||
375 | int request_buf_len, u16 *reply_buf, int reply_buf_len); | ||
376 | |||
377 | |||
378 | /* DEBI (saa7146 data extension bus interface) access */ | ||
379 | extern int av7110_debiwrite(struct av7110 *av7110, u32 config, | ||
380 | int addr, u32 val, int count); | ||
381 | extern u32 av7110_debiread(struct av7110 *av7110, u32 config, | ||
382 | int addr, int count); | ||
383 | |||
384 | |||
385 | /* DEBI during interrupt */ | ||
386 | /* single word writes */ | ||
387 | static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) | ||
388 | { | ||
389 | av7110_debiwrite(av7110, config, addr, val, count); | ||
390 | } | ||
391 | |||
392 | /* buffer writes */ | ||
393 | static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, | ||
394 | const u8 *val, int count) | ||
395 | { | ||
396 | memcpy(av7110->debi_virt, val, count); | ||
397 | av7110_debiwrite(av7110, config, addr, 0, count); | ||
398 | } | ||
399 | |||
400 | static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) | ||
401 | { | ||
402 | u32 res; | ||
403 | |||
404 | res=av7110_debiread(av7110, config, addr, count); | ||
405 | if (count<=4) | ||
406 | memcpy(av7110->debi_virt, (char *) &res, count); | ||
407 | return res; | ||
408 | } | ||
409 | |||
410 | /* DEBI outside interrupts, only for count <= 4! */ | ||
411 | static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) | ||
412 | { | ||
413 | unsigned long flags; | ||
414 | |||
415 | spin_lock_irqsave(&av7110->debilock, flags); | ||
416 | av7110_debiwrite(av7110, config, addr, val, count); | ||
417 | spin_unlock_irqrestore(&av7110->debilock, flags); | ||
418 | } | ||
419 | |||
420 | static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) | ||
421 | { | ||
422 | unsigned long flags; | ||
423 | u32 res; | ||
424 | |||
425 | spin_lock_irqsave(&av7110->debilock, flags); | ||
426 | res=av7110_debiread(av7110, config, addr, count); | ||
427 | spin_unlock_irqrestore(&av7110->debilock, flags); | ||
428 | return res; | ||
429 | } | ||
430 | |||
431 | /* handle mailbox registers of the dual ported RAM */ | ||
432 | static inline void ARM_ResetMailBox(struct av7110 *av7110) | ||
433 | { | ||
434 | unsigned long flags; | ||
435 | |||
436 | spin_lock_irqsave(&av7110->debilock, flags); | ||
437 | av7110_debiread(av7110, DEBINOSWAP, IRQ_RX, 2); | ||
438 | av7110_debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2); | ||
439 | spin_unlock_irqrestore(&av7110->debilock, flags); | ||
440 | } | ||
441 | |||
442 | static inline void ARM_ClearMailBox(struct av7110 *av7110) | ||
443 | { | ||
444 | iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); | ||
445 | } | ||
446 | |||
447 | static inline void ARM_ClearIrq(struct av7110 *av7110) | ||
448 | { | ||
449 | irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); | ||
450 | } | ||
451 | |||
452 | /**************************************************************************** | ||
453 | * Firmware commands | ||
454 | ****************************************************************************/ | ||
455 | |||
456 | static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data) | ||
457 | { | ||
458 | return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data); | ||
459 | } | ||
460 | |||
461 | static inline int av7710_set_video_mode(struct av7110 *av7110, int mode) | ||
462 | { | ||
463 | return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode); | ||
464 | } | ||
465 | |||
466 | static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg) | ||
467 | { | ||
468 | return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4, | ||
469 | (com>>16), (com&0xffff), | ||
470 | (arg>>16), (arg&0xffff)); | ||
471 | } | ||
472 | |||
473 | static inline int audcom(struct av7110 *av7110, u32 com) | ||
474 | { | ||
475 | return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2, | ||
476 | (com>>16), (com&0xffff)); | ||
477 | } | ||
478 | |||
479 | static inline int Set22K(struct av7110 *av7110, int state) | ||
480 | { | ||
481 | return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0); | ||
482 | } | ||
483 | |||
484 | |||
485 | extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst); | ||
486 | |||
487 | |||
488 | #ifdef CONFIG_DVB_AV7110_OSD | ||
489 | extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc); | ||
490 | extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap); | ||
491 | #endif /* CONFIG_DVB_AV7110_OSD */ | ||
492 | |||
493 | |||
494 | |||
495 | #endif /* _AV7110_HW_H_ */ | ||
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c deleted file mode 100644 index 699ef8b5b99a..000000000000 --- a/drivers/media/dvb/ttpci/av7110_ipack.c +++ /dev/null | |||
@@ -1,403 +0,0 @@ | |||
1 | #include "dvb_filter.h" | ||
2 | #include "av7110_ipack.h" | ||
3 | #include <linux/string.h> /* for memcpy() */ | ||
4 | #include <linux/vmalloc.h> | ||
5 | |||
6 | |||
7 | void av7110_ipack_reset(struct ipack *p) | ||
8 | { | ||
9 | p->found = 0; | ||
10 | p->cid = 0; | ||
11 | p->plength = 0; | ||
12 | p->flag1 = 0; | ||
13 | p->flag2 = 0; | ||
14 | p->hlength = 0; | ||
15 | p->mpeg = 0; | ||
16 | p->check = 0; | ||
17 | p->which = 0; | ||
18 | p->done = 0; | ||
19 | p->count = 0; | ||
20 | } | ||
21 | |||
22 | |||
23 | int av7110_ipack_init(struct ipack *p, int size, | ||
24 | void (*func)(u8 *buf, int size, void *priv)) | ||
25 | { | ||
26 | if (!(p->buf = vmalloc(size*sizeof(u8)))) { | ||
27 | printk(KERN_WARNING "Couldn't allocate memory for ipack\n"); | ||
28 | return -ENOMEM; | ||
29 | } | ||
30 | p->size = size; | ||
31 | p->func = func; | ||
32 | p->repack_subids = 0; | ||
33 | av7110_ipack_reset(p); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | |||
38 | void av7110_ipack_free(struct ipack *p) | ||
39 | { | ||
40 | vfree(p->buf); | ||
41 | } | ||
42 | |||
43 | |||
44 | static void send_ipack(struct ipack *p) | ||
45 | { | ||
46 | int off; | ||
47 | struct dvb_audio_info ai; | ||
48 | int ac3_off = 0; | ||
49 | int streamid = 0; | ||
50 | int nframes = 0; | ||
51 | int f = 0; | ||
52 | |||
53 | switch (p->mpeg) { | ||
54 | case 2: | ||
55 | if (p->count < 10) | ||
56 | return; | ||
57 | p->buf[3] = p->cid; | ||
58 | p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); | ||
59 | p->buf[5] = (u8)((p->count - 6) & 0x00ff); | ||
60 | if (p->repack_subids && p->cid == PRIVATE_STREAM1) { | ||
61 | off = 9 + p->buf[8]; | ||
62 | streamid = p->buf[off]; | ||
63 | if ((streamid & 0xf8) == 0x80) { | ||
64 | ai.off = 0; | ||
65 | ac3_off = ((p->buf[off + 2] << 8)| | ||
66 | p->buf[off + 3]); | ||
67 | if (ac3_off < p->count) | ||
68 | f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off, | ||
69 | p->count - ac3_off, &ai, 0); | ||
70 | if (!f) { | ||
71 | nframes = (p->count - off - 3 - ac3_off) / | ||
72 | ai.framesize + 1; | ||
73 | p->buf[off + 2] = (ac3_off >> 8) & 0xff; | ||
74 | p->buf[off + 3] = (ac3_off) & 0xff; | ||
75 | p->buf[off + 1] = nframes; | ||
76 | ac3_off += nframes * ai.framesize - p->count; | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | p->func(p->buf, p->count, p->data); | ||
81 | |||
82 | p->buf[6] = 0x80; | ||
83 | p->buf[7] = 0x00; | ||
84 | p->buf[8] = 0x00; | ||
85 | p->count = 9; | ||
86 | if (p->repack_subids && p->cid == PRIVATE_STREAM1 | ||
87 | && (streamid & 0xf8) == 0x80) { | ||
88 | p->count += 4; | ||
89 | p->buf[9] = streamid; | ||
90 | p->buf[10] = (ac3_off >> 8) & 0xff; | ||
91 | p->buf[11] = (ac3_off) & 0xff; | ||
92 | p->buf[12] = 0; | ||
93 | } | ||
94 | break; | ||
95 | |||
96 | case 1: | ||
97 | if (p->count < 8) | ||
98 | return; | ||
99 | p->buf[3] = p->cid; | ||
100 | p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); | ||
101 | p->buf[5] = (u8)((p->count - 6) & 0x00ff); | ||
102 | p->func(p->buf, p->count, p->data); | ||
103 | |||
104 | p->buf[6] = 0x0f; | ||
105 | p->count = 7; | ||
106 | break; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | |||
111 | void av7110_ipack_flush(struct ipack *p) | ||
112 | { | ||
113 | if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6) | ||
114 | return; | ||
115 | p->plength = p->found - 6; | ||
116 | p->found = 0; | ||
117 | send_ipack(p); | ||
118 | av7110_ipack_reset(p); | ||
119 | } | ||
120 | |||
121 | |||
122 | static void write_ipack(struct ipack *p, const u8 *data, int count) | ||
123 | { | ||
124 | u8 headr[3] = { 0x00, 0x00, 0x01 }; | ||
125 | |||
126 | if (p->count < 6) { | ||
127 | memcpy(p->buf, headr, 3); | ||
128 | p->count = 6; | ||
129 | } | ||
130 | |||
131 | if (p->count + count < p->size){ | ||
132 | memcpy(p->buf+p->count, data, count); | ||
133 | p->count += count; | ||
134 | } else { | ||
135 | int rest = p->size - p->count; | ||
136 | memcpy(p->buf+p->count, data, rest); | ||
137 | p->count += rest; | ||
138 | send_ipack(p); | ||
139 | if (count - rest > 0) | ||
140 | write_ipack(p, data + rest, count - rest); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p) | ||
146 | { | ||
147 | int l; | ||
148 | int c = 0; | ||
149 | |||
150 | while (c < count && (p->mpeg == 0 || | ||
151 | (p->mpeg == 1 && p->found < 7) || | ||
152 | (p->mpeg == 2 && p->found < 9)) | ||
153 | && (p->found < 5 || !p->done)) { | ||
154 | switch (p->found) { | ||
155 | case 0: | ||
156 | case 1: | ||
157 | if (buf[c] == 0x00) | ||
158 | p->found++; | ||
159 | else | ||
160 | p->found = 0; | ||
161 | c++; | ||
162 | break; | ||
163 | case 2: | ||
164 | if (buf[c] == 0x01) | ||
165 | p->found++; | ||
166 | else if (buf[c] == 0) | ||
167 | p->found = 2; | ||
168 | else | ||
169 | p->found = 0; | ||
170 | c++; | ||
171 | break; | ||
172 | case 3: | ||
173 | p->cid = 0; | ||
174 | switch (buf[c]) { | ||
175 | case PROG_STREAM_MAP: | ||
176 | case PRIVATE_STREAM2: | ||
177 | case PROG_STREAM_DIR: | ||
178 | case ECM_STREAM : | ||
179 | case EMM_STREAM : | ||
180 | case PADDING_STREAM : | ||
181 | case DSM_CC_STREAM : | ||
182 | case ISO13522_STREAM: | ||
183 | p->done = 1; | ||
184 | /* fall through */ | ||
185 | case PRIVATE_STREAM1: | ||
186 | case VIDEO_STREAM_S ... VIDEO_STREAM_E: | ||
187 | case AUDIO_STREAM_S ... AUDIO_STREAM_E: | ||
188 | p->found++; | ||
189 | p->cid = buf[c]; | ||
190 | c++; | ||
191 | break; | ||
192 | default: | ||
193 | p->found = 0; | ||
194 | break; | ||
195 | } | ||
196 | break; | ||
197 | |||
198 | case 4: | ||
199 | if (count-c > 1) { | ||
200 | p->plen[0] = buf[c]; | ||
201 | c++; | ||
202 | p->plen[1] = buf[c]; | ||
203 | c++; | ||
204 | p->found += 2; | ||
205 | p->plength = (p->plen[0] << 8) | p->plen[1]; | ||
206 | } else { | ||
207 | p->plen[0] = buf[c]; | ||
208 | p->found++; | ||
209 | return count; | ||
210 | } | ||
211 | break; | ||
212 | case 5: | ||
213 | p->plen[1] = buf[c]; | ||
214 | c++; | ||
215 | p->found++; | ||
216 | p->plength = (p->plen[0] << 8) | p->plen[1]; | ||
217 | break; | ||
218 | case 6: | ||
219 | if (!p->done) { | ||
220 | p->flag1 = buf[c]; | ||
221 | c++; | ||
222 | p->found++; | ||
223 | if ((p->flag1 & 0xc0) == 0x80) | ||
224 | p->mpeg = 2; | ||
225 | else { | ||
226 | p->hlength = 0; | ||
227 | p->which = 0; | ||
228 | p->mpeg = 1; | ||
229 | p->flag2 = 0; | ||
230 | } | ||
231 | } | ||
232 | break; | ||
233 | |||
234 | case 7: | ||
235 | if (!p->done && p->mpeg == 2) { | ||
236 | p->flag2 = buf[c]; | ||
237 | c++; | ||
238 | p->found++; | ||
239 | } | ||
240 | break; | ||
241 | |||
242 | case 8: | ||
243 | if (!p->done && p->mpeg == 2) { | ||
244 | p->hlength = buf[c]; | ||
245 | c++; | ||
246 | p->found++; | ||
247 | } | ||
248 | break; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | if (c == count) | ||
253 | return count; | ||
254 | |||
255 | if (!p->plength) | ||
256 | p->plength = MMAX_PLENGTH - 6; | ||
257 | |||
258 | if (p->done || ((p->mpeg == 2 && p->found >= 9) || | ||
259 | (p->mpeg == 1 && p->found >= 7))) { | ||
260 | switch (p->cid) { | ||
261 | case AUDIO_STREAM_S ... AUDIO_STREAM_E: | ||
262 | case VIDEO_STREAM_S ... VIDEO_STREAM_E: | ||
263 | case PRIVATE_STREAM1: | ||
264 | if (p->mpeg == 2 && p->found == 9) { | ||
265 | write_ipack(p, &p->flag1, 1); | ||
266 | write_ipack(p, &p->flag2, 1); | ||
267 | write_ipack(p, &p->hlength, 1); | ||
268 | } | ||
269 | |||
270 | if (p->mpeg == 1 && p->found == 7) | ||
271 | write_ipack(p, &p->flag1, 1); | ||
272 | |||
273 | if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && | ||
274 | p->found < 14) { | ||
275 | while (c < count && p->found < 14) { | ||
276 | p->pts[p->found - 9] = buf[c]; | ||
277 | write_ipack(p, buf + c, 1); | ||
278 | c++; | ||
279 | p->found++; | ||
280 | } | ||
281 | if (c == count) | ||
282 | return count; | ||
283 | } | ||
284 | |||
285 | if (p->mpeg == 1 && p->which < 2000) { | ||
286 | |||
287 | if (p->found == 7) { | ||
288 | p->check = p->flag1; | ||
289 | p->hlength = 1; | ||
290 | } | ||
291 | |||
292 | while (!p->which && c < count && | ||
293 | p->check == 0xff){ | ||
294 | p->check = buf[c]; | ||
295 | write_ipack(p, buf + c, 1); | ||
296 | c++; | ||
297 | p->found++; | ||
298 | p->hlength++; | ||
299 | } | ||
300 | |||
301 | if (c == count) | ||
302 | return count; | ||
303 | |||
304 | if ((p->check & 0xc0) == 0x40 && !p->which) { | ||
305 | p->check = buf[c]; | ||
306 | write_ipack(p, buf + c, 1); | ||
307 | c++; | ||
308 | p->found++; | ||
309 | p->hlength++; | ||
310 | |||
311 | p->which = 1; | ||
312 | if (c == count) | ||
313 | return count; | ||
314 | p->check = buf[c]; | ||
315 | write_ipack(p, buf + c, 1); | ||
316 | c++; | ||
317 | p->found++; | ||
318 | p->hlength++; | ||
319 | p->which = 2; | ||
320 | if (c == count) | ||
321 | return count; | ||
322 | } | ||
323 | |||
324 | if (p->which == 1) { | ||
325 | p->check = buf[c]; | ||
326 | write_ipack(p, buf + c, 1); | ||
327 | c++; | ||
328 | p->found++; | ||
329 | p->hlength++; | ||
330 | p->which = 2; | ||
331 | if (c == count) | ||
332 | return count; | ||
333 | } | ||
334 | |||
335 | if ((p->check & 0x30) && p->check != 0xff) { | ||
336 | p->flag2 = (p->check & 0xf0) << 2; | ||
337 | p->pts[0] = p->check; | ||
338 | p->which = 3; | ||
339 | } | ||
340 | |||
341 | if (c == count) | ||
342 | return count; | ||
343 | if (p->which > 2){ | ||
344 | if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) { | ||
345 | while (c < count && p->which < 7) { | ||
346 | p->pts[p->which - 2] = buf[c]; | ||
347 | write_ipack(p, buf + c, 1); | ||
348 | c++; | ||
349 | p->found++; | ||
350 | p->which++; | ||
351 | p->hlength++; | ||
352 | } | ||
353 | if (c == count) | ||
354 | return count; | ||
355 | } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) { | ||
356 | while (c < count && p->which < 12) { | ||
357 | if (p->which < 7) | ||
358 | p->pts[p->which - 2] = buf[c]; | ||
359 | write_ipack(p, buf + c, 1); | ||
360 | c++; | ||
361 | p->found++; | ||
362 | p->which++; | ||
363 | p->hlength++; | ||
364 | } | ||
365 | if (c == count) | ||
366 | return count; | ||
367 | } | ||
368 | p->which = 2000; | ||
369 | } | ||
370 | |||
371 | } | ||
372 | |||
373 | while (c < count && p->found < p->plength + 6) { | ||
374 | l = count - c; | ||
375 | if (l + p->found > p->plength + 6) | ||
376 | l = p->plength + 6 - p->found; | ||
377 | write_ipack(p, buf + c, l); | ||
378 | p->found += l; | ||
379 | c += l; | ||
380 | } | ||
381 | break; | ||
382 | } | ||
383 | |||
384 | |||
385 | if (p->done) { | ||
386 | if (p->found + count - c < p->plength + 6) { | ||
387 | p->found += count - c; | ||
388 | c = count; | ||
389 | } else { | ||
390 | c += p->plength + 6 - p->found; | ||
391 | p->found = p->plength + 6; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | if (p->plength && p->found == p->plength + 6) { | ||
396 | send_ipack(p); | ||
397 | av7110_ipack_reset(p); | ||
398 | if (c < count) | ||
399 | av7110_ipack_instant_repack(buf + c, count - c, p); | ||
400 | } | ||
401 | } | ||
402 | return count; | ||
403 | } | ||
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.h b/drivers/media/dvb/ttpci/av7110_ipack.h deleted file mode 100644 index becf94d3fdfa..000000000000 --- a/drivers/media/dvb/ttpci/av7110_ipack.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #ifndef _AV7110_IPACK_H_ | ||
2 | #define _AV7110_IPACK_H_ | ||
3 | |||
4 | extern int av7110_ipack_init(struct ipack *p, int size, | ||
5 | void (*func)(u8 *buf, int size, void *priv)); | ||
6 | |||
7 | extern void av7110_ipack_reset(struct ipack *p); | ||
8 | extern int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p); | ||
9 | extern void av7110_ipack_free(struct ipack * p); | ||
10 | extern void av7110_ipack_flush(struct ipack *p); | ||
11 | |||
12 | #endif | ||
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c deleted file mode 100644 index 908f272fe26c..000000000000 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ /dev/null | |||
@@ -1,415 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the remote control of SAA7146 based AV7110 cards | ||
3 | * | ||
4 | * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de> | ||
5 | * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/proc_fs.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/bitops.h> | ||
31 | |||
32 | #include "av7110.h" | ||
33 | #include "av7110_hw.h" | ||
34 | |||
35 | |||
36 | #define AV_CNT 4 | ||
37 | |||
38 | #define IR_RC5 0 | ||
39 | #define IR_RCMM 1 | ||
40 | #define IR_RC5_EXT 2 /* internal only */ | ||
41 | |||
42 | #define IR_ALL 0xffffffff | ||
43 | |||
44 | #define UP_TIMEOUT (HZ*7/25) | ||
45 | |||
46 | |||
47 | /* Note: enable ir debugging by or'ing debug with 16 */ | ||
48 | |||
49 | static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM}; | ||
50 | module_param_array(ir_protocol, int, NULL, 0644); | ||
51 | MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)"); | ||
52 | |||
53 | static int ir_inversion[AV_CNT]; | ||
54 | module_param_array(ir_inversion, int, NULL, 0644); | ||
55 | MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted"); | ||
56 | |||
57 | static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL }; | ||
58 | module_param_array(ir_device_mask, uint, NULL, 0644); | ||
59 | MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)"); | ||
60 | |||
61 | |||
62 | static int av_cnt; | ||
63 | static struct av7110 *av_list[AV_CNT]; | ||
64 | |||
65 | static u16 default_key_map [256] = { | ||
66 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, | ||
67 | KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, | ||
68 | KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
69 | KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0, | ||
70 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
71 | 0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0, | ||
72 | 0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0, | ||
73 | KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0, | ||
74 | KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0, | ||
75 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW, | ||
76 | KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0, | ||
77 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
78 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
79 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
80 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
81 | 0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN, | ||
82 | 0, 0, 0, 0, KEY_EPG, 0, 0, 0, | ||
83 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
84 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
85 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR | ||
86 | }; | ||
87 | |||
88 | |||
89 | /* key-up timer */ | ||
90 | static void av7110_emit_keyup(unsigned long parm) | ||
91 | { | ||
92 | struct infrared *ir = (struct infrared *) parm; | ||
93 | |||
94 | if (!ir || !test_bit(ir->last_key, ir->input_dev->key)) | ||
95 | return; | ||
96 | |||
97 | input_report_key(ir->input_dev, ir->last_key, 0); | ||
98 | input_sync(ir->input_dev); | ||
99 | } | ||
100 | |||
101 | |||
102 | /* tasklet */ | ||
103 | static void av7110_emit_key(unsigned long parm) | ||
104 | { | ||
105 | struct infrared *ir = (struct infrared *) parm; | ||
106 | u32 ircom = ir->ir_command; | ||
107 | u8 data; | ||
108 | u8 addr; | ||
109 | u16 toggle; | ||
110 | u16 keycode; | ||
111 | |||
112 | /* extract device address and data */ | ||
113 | switch (ir->protocol) { | ||
114 | case IR_RC5: /* RC5: 5 bits device address, 6 bits data */ | ||
115 | data = ircom & 0x3f; | ||
116 | addr = (ircom >> 6) & 0x1f; | ||
117 | toggle = ircom & 0x0800; | ||
118 | break; | ||
119 | |||
120 | case IR_RCMM: /* RCMM: ? bits device address, ? bits data */ | ||
121 | data = ircom & 0xff; | ||
122 | addr = (ircom >> 8) & 0x1f; | ||
123 | toggle = ircom & 0x8000; | ||
124 | break; | ||
125 | |||
126 | case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */ | ||
127 | data = ircom & 0x3f; | ||
128 | addr = (ircom >> 6) & 0x1f; | ||
129 | /* invert 7th data bit for backward compatibility with RC5 keymaps */ | ||
130 | if (!(ircom & 0x1000)) | ||
131 | data |= 0x40; | ||
132 | toggle = ircom & 0x0800; | ||
133 | break; | ||
134 | |||
135 | default: | ||
136 | printk("%s invalid protocol %x\n", __func__, ir->protocol); | ||
137 | return; | ||
138 | } | ||
139 | |||
140 | input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data); | ||
141 | input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); | ||
142 | |||
143 | keycode = ir->key_map[data]; | ||
144 | |||
145 | dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n", | ||
146 | __func__, ircom, addr, data, keycode); | ||
147 | |||
148 | /* check device address */ | ||
149 | if (!(ir->device_mask & (1 << addr))) | ||
150 | return; | ||
151 | |||
152 | if (!keycode) { | ||
153 | printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n", | ||
154 | __func__, ircom, addr, data); | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | if (timer_pending(&ir->keyup_timer)) { | ||
159 | del_timer(&ir->keyup_timer); | ||
160 | if (ir->last_key != keycode || toggle != ir->last_toggle) { | ||
161 | ir->delay_timer_finished = 0; | ||
162 | input_event(ir->input_dev, EV_KEY, ir->last_key, 0); | ||
163 | input_event(ir->input_dev, EV_KEY, keycode, 1); | ||
164 | input_sync(ir->input_dev); | ||
165 | } else if (ir->delay_timer_finished) { | ||
166 | input_event(ir->input_dev, EV_KEY, keycode, 2); | ||
167 | input_sync(ir->input_dev); | ||
168 | } | ||
169 | } else { | ||
170 | ir->delay_timer_finished = 0; | ||
171 | input_event(ir->input_dev, EV_KEY, keycode, 1); | ||
172 | input_sync(ir->input_dev); | ||
173 | } | ||
174 | |||
175 | ir->last_key = keycode; | ||
176 | ir->last_toggle = toggle; | ||
177 | |||
178 | ir->keyup_timer.expires = jiffies + UP_TIMEOUT; | ||
179 | add_timer(&ir->keyup_timer); | ||
180 | |||
181 | } | ||
182 | |||
183 | |||
184 | /* register with input layer */ | ||
185 | static void input_register_keys(struct infrared *ir) | ||
186 | { | ||
187 | int i; | ||
188 | |||
189 | set_bit(EV_KEY, ir->input_dev->evbit); | ||
190 | set_bit(EV_REP, ir->input_dev->evbit); | ||
191 | set_bit(EV_MSC, ir->input_dev->evbit); | ||
192 | |||
193 | set_bit(MSC_RAW, ir->input_dev->mscbit); | ||
194 | set_bit(MSC_SCAN, ir->input_dev->mscbit); | ||
195 | |||
196 | memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); | ||
197 | |||
198 | for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) { | ||
199 | if (ir->key_map[i] > KEY_MAX) | ||
200 | ir->key_map[i] = 0; | ||
201 | else if (ir->key_map[i] > KEY_RESERVED) | ||
202 | set_bit(ir->key_map[i], ir->input_dev->keybit); | ||
203 | } | ||
204 | |||
205 | ir->input_dev->keycode = ir->key_map; | ||
206 | ir->input_dev->keycodesize = sizeof(ir->key_map[0]); | ||
207 | ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); | ||
208 | } | ||
209 | |||
210 | |||
211 | /* called by the input driver after rep[REP_DELAY] ms */ | ||
212 | static void input_repeat_key(unsigned long parm) | ||
213 | { | ||
214 | struct infrared *ir = (struct infrared *) parm; | ||
215 | |||
216 | ir->delay_timer_finished = 1; | ||
217 | } | ||
218 | |||
219 | |||
220 | /* check for configuration changes */ | ||
221 | int av7110_check_ir_config(struct av7110 *av7110, int force) | ||
222 | { | ||
223 | int i; | ||
224 | int modified = force; | ||
225 | int ret = -ENODEV; | ||
226 | |||
227 | for (i = 0; i < av_cnt; i++) | ||
228 | if (av7110 == av_list[i]) | ||
229 | break; | ||
230 | |||
231 | if (i < av_cnt && av7110) { | ||
232 | if ((av7110->ir.protocol & 1) != ir_protocol[i] || | ||
233 | av7110->ir.inversion != ir_inversion[i]) | ||
234 | modified = true; | ||
235 | |||
236 | if (modified) { | ||
237 | /* protocol */ | ||
238 | if (ir_protocol[i]) { | ||
239 | ir_protocol[i] = 1; | ||
240 | av7110->ir.protocol = IR_RCMM; | ||
241 | av7110->ir.ir_config = 0x0001; | ||
242 | } else if (FW_VERSION(av7110->arm_app) >= 0x2620) { | ||
243 | av7110->ir.protocol = IR_RC5_EXT; | ||
244 | av7110->ir.ir_config = 0x0002; | ||
245 | } else { | ||
246 | av7110->ir.protocol = IR_RC5; | ||
247 | av7110->ir.ir_config = 0x0000; | ||
248 | } | ||
249 | /* inversion */ | ||
250 | if (ir_inversion[i]) { | ||
251 | ir_inversion[i] = 1; | ||
252 | av7110->ir.ir_config |= 0x8000; | ||
253 | } | ||
254 | av7110->ir.inversion = ir_inversion[i]; | ||
255 | /* update ARM */ | ||
256 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, | ||
257 | av7110->ir.ir_config); | ||
258 | } else | ||
259 | ret = 0; | ||
260 | |||
261 | /* address */ | ||
262 | if (av7110->ir.device_mask != ir_device_mask[i]) | ||
263 | av7110->ir.device_mask = ir_device_mask[i]; | ||
264 | } | ||
265 | |||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | |||
270 | /* /proc/av7110_ir interface */ | ||
271 | static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer, | ||
272 | size_t count, loff_t *pos) | ||
273 | { | ||
274 | char *page; | ||
275 | u32 ir_config; | ||
276 | int size = sizeof ir_config + sizeof av_list[0]->ir.key_map; | ||
277 | int i; | ||
278 | |||
279 | if (count < size) | ||
280 | return -EINVAL; | ||
281 | |||
282 | page = vmalloc(size); | ||
283 | if (!page) | ||
284 | return -ENOMEM; | ||
285 | |||
286 | if (copy_from_user(page, buffer, size)) { | ||
287 | vfree(page); | ||
288 | return -EFAULT; | ||
289 | } | ||
290 | |||
291 | memcpy(&ir_config, page, sizeof ir_config); | ||
292 | |||
293 | for (i = 0; i < av_cnt; i++) { | ||
294 | /* keymap */ | ||
295 | memcpy(av_list[i]->ir.key_map, page + sizeof ir_config, | ||
296 | sizeof(av_list[i]->ir.key_map)); | ||
297 | /* protocol, inversion, address */ | ||
298 | ir_protocol[i] = ir_config & 0x0001; | ||
299 | ir_inversion[i] = ir_config & 0x8000 ? 1 : 0; | ||
300 | if (ir_config & 0x4000) | ||
301 | ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f); | ||
302 | else | ||
303 | ir_device_mask[i] = IR_ALL; | ||
304 | /* update configuration */ | ||
305 | av7110_check_ir_config(av_list[i], false); | ||
306 | input_register_keys(&av_list[i]->ir); | ||
307 | } | ||
308 | vfree(page); | ||
309 | return count; | ||
310 | } | ||
311 | |||
312 | static const struct file_operations av7110_ir_proc_fops = { | ||
313 | .owner = THIS_MODULE, | ||
314 | .write = av7110_ir_proc_write, | ||
315 | .llseek = noop_llseek, | ||
316 | }; | ||
317 | |||
318 | /* interrupt handler */ | ||
319 | static void ir_handler(struct av7110 *av7110, u32 ircom) | ||
320 | { | ||
321 | dprintk(4, "ir command = %08x\n", ircom); | ||
322 | av7110->ir.ir_command = ircom; | ||
323 | tasklet_schedule(&av7110->ir.ir_tasklet); | ||
324 | } | ||
325 | |||
326 | |||
327 | int __devinit av7110_ir_init(struct av7110 *av7110) | ||
328 | { | ||
329 | struct input_dev *input_dev; | ||
330 | static struct proc_dir_entry *e; | ||
331 | int err; | ||
332 | |||
333 | if (av_cnt >= ARRAY_SIZE(av_list)) | ||
334 | return -ENOSPC; | ||
335 | |||
336 | av_list[av_cnt++] = av7110; | ||
337 | av7110_check_ir_config(av7110, true); | ||
338 | |||
339 | init_timer(&av7110->ir.keyup_timer); | ||
340 | av7110->ir.keyup_timer.function = av7110_emit_keyup; | ||
341 | av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir; | ||
342 | |||
343 | input_dev = input_allocate_device(); | ||
344 | if (!input_dev) | ||
345 | return -ENOMEM; | ||
346 | |||
347 | av7110->ir.input_dev = input_dev; | ||
348 | snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys), | ||
349 | "pci-%s/ir0", pci_name(av7110->dev->pci)); | ||
350 | |||
351 | input_dev->name = "DVB on-card IR receiver"; | ||
352 | |||
353 | input_dev->phys = av7110->ir.input_phys; | ||
354 | input_dev->id.bustype = BUS_PCI; | ||
355 | input_dev->id.version = 2; | ||
356 | if (av7110->dev->pci->subsystem_vendor) { | ||
357 | input_dev->id.vendor = av7110->dev->pci->subsystem_vendor; | ||
358 | input_dev->id.product = av7110->dev->pci->subsystem_device; | ||
359 | } else { | ||
360 | input_dev->id.vendor = av7110->dev->pci->vendor; | ||
361 | input_dev->id.product = av7110->dev->pci->device; | ||
362 | } | ||
363 | input_dev->dev.parent = &av7110->dev->pci->dev; | ||
364 | /* initial keymap */ | ||
365 | memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map); | ||
366 | input_register_keys(&av7110->ir); | ||
367 | err = input_register_device(input_dev); | ||
368 | if (err) { | ||
369 | input_free_device(input_dev); | ||
370 | return err; | ||
371 | } | ||
372 | input_dev->timer.function = input_repeat_key; | ||
373 | input_dev->timer.data = (unsigned long) &av7110->ir; | ||
374 | |||
375 | if (av_cnt == 1) { | ||
376 | e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops); | ||
377 | if (e) | ||
378 | e->size = 4 + 256 * sizeof(u16); | ||
379 | } | ||
380 | |||
381 | tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); | ||
382 | av7110->ir.ir_handler = ir_handler; | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | |||
388 | void __devexit av7110_ir_exit(struct av7110 *av7110) | ||
389 | { | ||
390 | int i; | ||
391 | |||
392 | if (av_cnt == 0) | ||
393 | return; | ||
394 | |||
395 | del_timer_sync(&av7110->ir.keyup_timer); | ||
396 | av7110->ir.ir_handler = NULL; | ||
397 | tasklet_kill(&av7110->ir.ir_tasklet); | ||
398 | |||
399 | for (i = 0; i < av_cnt; i++) | ||
400 | if (av_list[i] == av7110) { | ||
401 | av_list[i] = av_list[av_cnt-1]; | ||
402 | av_list[av_cnt-1] = NULL; | ||
403 | break; | ||
404 | } | ||
405 | |||
406 | if (av_cnt == 1) | ||
407 | remove_proc_entry("av7110_ir", NULL); | ||
408 | |||
409 | input_unregister_device(av7110->ir.input_dev); | ||
410 | |||
411 | av_cnt--; | ||
412 | } | ||
413 | |||
414 | //MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>"); | ||
415 | //MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c deleted file mode 100644 index 1b2d15140a1d..000000000000 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ /dev/null | |||
@@ -1,966 +0,0 @@ | |||
1 | /* | ||
2 | * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module | ||
3 | * | ||
4 | * Copyright (C) 1999-2002 Ralph Metzler | ||
5 | * & Marcus Metzler for convergence integrated media GmbH | ||
6 | * | ||
7 | * originally based on code by: | ||
8 | * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
23 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
24 | * | ||
25 | * the project's page is at http://www.linuxtv.org/ | ||
26 | */ | ||
27 | |||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
29 | |||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/fs.h> | ||
34 | #include <linux/timer.h> | ||
35 | #include <linux/poll.h> | ||
36 | |||
37 | #include "av7110.h" | ||
38 | #include "av7110_hw.h" | ||
39 | #include "av7110_av.h" | ||
40 | |||
41 | int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) | ||
42 | { | ||
43 | u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff }; | ||
44 | struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg }; | ||
45 | |||
46 | switch (av7110->adac_type) { | ||
47 | case DVB_ADAC_MSP34x0: | ||
48 | msgs.addr = 0x40; | ||
49 | break; | ||
50 | case DVB_ADAC_MSP34x5: | ||
51 | msgs.addr = 0x42; | ||
52 | break; | ||
53 | default: | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { | ||
58 | dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n", | ||
59 | av7110->dvb_adapter.num, reg, val); | ||
60 | return -EIO; | ||
61 | } | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) | ||
66 | { | ||
67 | u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; | ||
68 | u8 msg2[2]; | ||
69 | struct i2c_msg msgs[2] = { | ||
70 | { .flags = 0 , .len = 3, .buf = msg1 }, | ||
71 | { .flags = I2C_M_RD, .len = 2, .buf = msg2 } | ||
72 | }; | ||
73 | |||
74 | switch (av7110->adac_type) { | ||
75 | case DVB_ADAC_MSP34x0: | ||
76 | msgs[0].addr = 0x40; | ||
77 | msgs[1].addr = 0x40; | ||
78 | break; | ||
79 | case DVB_ADAC_MSP34x5: | ||
80 | msgs[0].addr = 0x42; | ||
81 | msgs[1].addr = 0x42; | ||
82 | break; | ||
83 | default: | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { | ||
88 | dprintk(1, "dvb-ttpci: failed @ card %d, %u\n", | ||
89 | av7110->dvb_adapter.num, reg); | ||
90 | return -EIO; | ||
91 | } | ||
92 | *val = (msg2[0] << 8) | msg2[1]; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static struct v4l2_input inputs[4] = { | ||
97 | { | ||
98 | .index = 0, | ||
99 | .name = "DVB", | ||
100 | .type = V4L2_INPUT_TYPE_CAMERA, | ||
101 | .audioset = 1, | ||
102 | .tuner = 0, /* ignored */ | ||
103 | .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, | ||
104 | .status = 0, | ||
105 | .capabilities = V4L2_IN_CAP_STD, | ||
106 | }, { | ||
107 | .index = 1, | ||
108 | .name = "Television", | ||
109 | .type = V4L2_INPUT_TYPE_TUNER, | ||
110 | .audioset = 1, | ||
111 | .tuner = 0, | ||
112 | .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, | ||
113 | .status = 0, | ||
114 | .capabilities = V4L2_IN_CAP_STD, | ||
115 | }, { | ||
116 | .index = 2, | ||
117 | .name = "Video", | ||
118 | .type = V4L2_INPUT_TYPE_CAMERA, | ||
119 | .audioset = 0, | ||
120 | .tuner = 0, | ||
121 | .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, | ||
122 | .status = 0, | ||
123 | .capabilities = V4L2_IN_CAP_STD, | ||
124 | }, { | ||
125 | .index = 3, | ||
126 | .name = "Y/C", | ||
127 | .type = V4L2_INPUT_TYPE_CAMERA, | ||
128 | .audioset = 0, | ||
129 | .tuner = 0, | ||
130 | .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, | ||
131 | .status = 0, | ||
132 | .capabilities = V4L2_IN_CAP_STD, | ||
133 | } | ||
134 | }; | ||
135 | |||
136 | static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data) | ||
137 | { | ||
138 | struct av7110 *av7110 = dev->ext_priv; | ||
139 | u8 buf[] = { 0x00, reg, data }; | ||
140 | struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; | ||
141 | |||
142 | dprintk(4, "dev: %p\n", dev); | ||
143 | |||
144 | if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1)) | ||
145 | return -1; | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) | ||
150 | { | ||
151 | struct av7110 *av7110 = dev->ext_priv; | ||
152 | struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; | ||
153 | |||
154 | dprintk(4, "dev: %p\n", dev); | ||
155 | |||
156 | if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1)) | ||
157 | return -1; | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq) | ||
162 | { | ||
163 | u32 div; | ||
164 | u8 config; | ||
165 | u8 buf[4]; | ||
166 | |||
167 | dprintk(4, "freq: 0x%08x\n", freq); | ||
168 | |||
169 | /* magic number: 614. tuning with the frequency given by v4l2 | ||
170 | is always off by 614*62.5 = 38375 kHz...*/ | ||
171 | div = freq + 614; | ||
172 | |||
173 | buf[0] = (div >> 8) & 0x7f; | ||
174 | buf[1] = div & 0xff; | ||
175 | buf[2] = 0x8e; | ||
176 | |||
177 | if (freq < (u32) (16 * 168.25)) | ||
178 | config = 0xa0; | ||
179 | else if (freq < (u32) (16 * 447.25)) | ||
180 | config = 0x90; | ||
181 | else | ||
182 | config = 0x30; | ||
183 | config &= ~0x02; | ||
184 | |||
185 | buf[3] = config; | ||
186 | |||
187 | return tuner_write(dev, 0x61, buf); | ||
188 | } | ||
189 | |||
190 | static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) | ||
191 | { | ||
192 | struct av7110 *av7110 = (struct av7110*)dev->ext_priv; | ||
193 | u32 div; | ||
194 | u8 data[4]; | ||
195 | |||
196 | div = (freq + 38900000 + 31250) / 62500; | ||
197 | |||
198 | data[0] = (div >> 8) & 0x7f; | ||
199 | data[1] = div & 0xff; | ||
200 | data[2] = 0xce; | ||
201 | |||
202 | if (freq < 45000000) | ||
203 | return -EINVAL; | ||
204 | else if (freq < 137000000) | ||
205 | data[3] = 0x01; | ||
206 | else if (freq < 403000000) | ||
207 | data[3] = 0x02; | ||
208 | else if (freq < 860000000) | ||
209 | data[3] = 0x04; | ||
210 | else | ||
211 | return -EINVAL; | ||
212 | |||
213 | if (av7110->fe->ops.i2c_gate_ctrl) | ||
214 | av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1); | ||
215 | return tuner_write(dev, 0x63, data); | ||
216 | } | ||
217 | |||
218 | |||
219 | |||
220 | static struct saa7146_standard analog_standard[]; | ||
221 | static struct saa7146_standard dvb_standard[]; | ||
222 | static struct saa7146_standard standard[]; | ||
223 | |||
224 | static struct v4l2_audio msp3400_v4l2_audio = { | ||
225 | .index = 0, | ||
226 | .name = "Television", | ||
227 | .capability = V4L2_AUDCAP_STEREO | ||
228 | }; | ||
229 | |||
230 | static int av7110_dvb_c_switch(struct saa7146_fh *fh) | ||
231 | { | ||
232 | struct saa7146_dev *dev = fh->dev; | ||
233 | struct saa7146_vv *vv = dev->vv_data; | ||
234 | struct av7110 *av7110 = (struct av7110*)dev->ext_priv; | ||
235 | u16 adswitch; | ||
236 | int source, sync, err; | ||
237 | |||
238 | dprintk(4, "%p\n", av7110); | ||
239 | |||
240 | if ((vv->video_status & STATUS_OVERLAY) != 0) { | ||
241 | vv->ov_suspend = vv->video_fh; | ||
242 | err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ | ||
243 | if (err != 0) { | ||
244 | dprintk(2, "suspending video failed\n"); | ||
245 | vv->ov_suspend = NULL; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | if (0 != av7110->current_input) { | ||
250 | dprintk(1, "switching to analog TV:\n"); | ||
251 | adswitch = 1; | ||
252 | source = SAA7146_HPS_SOURCE_PORT_B; | ||
253 | sync = SAA7146_HPS_SYNC_PORT_B; | ||
254 | memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2); | ||
255 | |||
256 | switch (av7110->current_input) { | ||
257 | case 1: | ||
258 | dprintk(1, "switching SAA7113 to Analog Tuner Input\n"); | ||
259 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source | ||
260 | msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source | ||
261 | msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source | ||
262 | msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono | ||
263 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone | ||
264 | msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume | ||
265 | |||
266 | if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { | ||
267 | if (ves1820_writereg(dev, 0x09, 0x0f, 0x60)) | ||
268 | dprintk(1, "setting band in demodulator failed\n"); | ||
269 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { | ||
270 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9819 pin9(STD) | ||
271 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9819 pin30(VIF) | ||
272 | } | ||
273 | if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1) | ||
274 | dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); | ||
275 | break; | ||
276 | case 2: | ||
277 | dprintk(1, "switching SAA7113 to Video AV CVBS Input\n"); | ||
278 | if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1) | ||
279 | dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); | ||
280 | break; | ||
281 | case 3: | ||
282 | dprintk(1, "switching SAA7113 to Video AV Y/C Input\n"); | ||
283 | if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1) | ||
284 | dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); | ||
285 | break; | ||
286 | default: | ||
287 | dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input\n"); | ||
288 | } | ||
289 | } else { | ||
290 | adswitch = 0; | ||
291 | source = SAA7146_HPS_SOURCE_PORT_A; | ||
292 | sync = SAA7146_HPS_SYNC_PORT_A; | ||
293 | memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2); | ||
294 | dprintk(1, "switching DVB mode\n"); | ||
295 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source | ||
296 | msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source | ||
297 | msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source | ||
298 | msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono | ||
299 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone | ||
300 | msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume | ||
301 | |||
302 | if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { | ||
303 | if (ves1820_writereg(dev, 0x09, 0x0f, 0x20)) | ||
304 | dprintk(1, "setting band in demodulator failed\n"); | ||
305 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { | ||
306 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) | ||
307 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /* hmm, this does not do anything!? */ | ||
312 | if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch)) | ||
313 | dprintk(1, "ADSwitch error\n"); | ||
314 | |||
315 | saa7146_set_hps_source_and_sync(dev, source, sync); | ||
316 | |||
317 | if (vv->ov_suspend != NULL) { | ||
318 | saa7146_start_preview(vv->ov_suspend); | ||
319 | vv->ov_suspend = NULL; | ||
320 | } | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) | ||
326 | { | ||
327 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
328 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
329 | u16 stereo_det; | ||
330 | s8 stereo; | ||
331 | |||
332 | dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index); | ||
333 | |||
334 | if (!av7110->analog_tuner_flags || t->index != 0) | ||
335 | return -EINVAL; | ||
336 | |||
337 | memset(t, 0, sizeof(*t)); | ||
338 | strcpy((char *)t->name, "Television"); | ||
339 | |||
340 | t->type = V4L2_TUNER_ANALOG_TV; | ||
341 | t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | | ||
342 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; | ||
343 | t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ | ||
344 | t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ | ||
345 | /* FIXME: add the real signal strength here */ | ||
346 | t->signal = 0xffff; | ||
347 | t->afc = 0; | ||
348 | |||
349 | /* FIXME: standard / stereo detection is still broken */ | ||
350 | msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det); | ||
351 | dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det); | ||
352 | msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det); | ||
353 | dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det); | ||
354 | stereo = (s8)(stereo_det >> 8); | ||
355 | if (stereo > 0x10) { | ||
356 | /* stereo */ | ||
357 | t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; | ||
358 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
359 | } else if (stereo < -0x10) { | ||
360 | /* bilingual */ | ||
361 | t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
362 | t->audmode = V4L2_TUNER_MODE_LANG1; | ||
363 | } else /* mono */ | ||
364 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t) | ||
370 | { | ||
371 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
372 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
373 | u16 fm_matrix, src; | ||
374 | dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index); | ||
375 | |||
376 | if (!av7110->analog_tuner_flags || av7110->current_input != 1) | ||
377 | return -EINVAL; | ||
378 | |||
379 | switch (t->audmode) { | ||
380 | case V4L2_TUNER_MODE_STEREO: | ||
381 | dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"); | ||
382 | fm_matrix = 0x3001; /* stereo */ | ||
383 | src = 0x0020; | ||
384 | break; | ||
385 | case V4L2_TUNER_MODE_LANG1_LANG2: | ||
386 | dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"); | ||
387 | fm_matrix = 0x3000; /* bilingual */ | ||
388 | src = 0x0020; | ||
389 | break; | ||
390 | case V4L2_TUNER_MODE_LANG1: | ||
391 | dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"); | ||
392 | fm_matrix = 0x3000; /* mono */ | ||
393 | src = 0x0000; | ||
394 | break; | ||
395 | case V4L2_TUNER_MODE_LANG2: | ||
396 | dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"); | ||
397 | fm_matrix = 0x3000; /* mono */ | ||
398 | src = 0x0010; | ||
399 | break; | ||
400 | default: /* case V4L2_TUNER_MODE_MONO: */ | ||
401 | dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n"); | ||
402 | fm_matrix = 0x3000; /* mono */ | ||
403 | src = 0x0030; | ||
404 | break; | ||
405 | } | ||
406 | msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix); | ||
407 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, src); | ||
408 | msp_writereg(av7110, MSP_WR_DSP, 0x0009, src); | ||
409 | msp_writereg(av7110, MSP_WR_DSP, 0x000a, src); | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) | ||
414 | { | ||
415 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
416 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
417 | |||
418 | dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x\n", f->frequency); | ||
419 | |||
420 | if (!av7110->analog_tuner_flags || av7110->current_input != 1) | ||
421 | return -EINVAL; | ||
422 | |||
423 | memset(f, 0, sizeof(*f)); | ||
424 | f->type = V4L2_TUNER_ANALOG_TV; | ||
425 | f->frequency = av7110->current_freq; | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f) | ||
430 | { | ||
431 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
432 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
433 | |||
434 | dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x\n", f->frequency); | ||
435 | |||
436 | if (!av7110->analog_tuner_flags || av7110->current_input != 1) | ||
437 | return -EINVAL; | ||
438 | |||
439 | if (V4L2_TUNER_ANALOG_TV != f->type) | ||
440 | return -EINVAL; | ||
441 | |||
442 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */ | ||
443 | msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0); | ||
444 | |||
445 | /* tune in desired frequency */ | ||
446 | if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) | ||
447 | ves1820_set_tv_freq(dev, f->frequency); | ||
448 | else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) | ||
449 | stv0297_set_tv_freq(dev, f->frequency); | ||
450 | av7110->current_freq = f->frequency; | ||
451 | |||
452 | msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */ | ||
453 | msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000); | ||
454 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */ | ||
455 | msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */ | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | ||
460 | { | ||
461 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
462 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
463 | |||
464 | dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); | ||
465 | |||
466 | if (av7110->analog_tuner_flags) { | ||
467 | if (i->index >= 4) | ||
468 | return -EINVAL; | ||
469 | } else { | ||
470 | if (i->index != 0) | ||
471 | return -EINVAL; | ||
472 | } | ||
473 | |||
474 | memcpy(i, &inputs[i->index], sizeof(struct v4l2_input)); | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) | ||
480 | { | ||
481 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
482 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
483 | |||
484 | *input = av7110->current_input; | ||
485 | dprintk(2, "VIDIOC_G_INPUT: %d\n", *input); | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | static int vidioc_s_input(struct file *file, void *fh, unsigned int input) | ||
490 | { | ||
491 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
492 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
493 | |||
494 | dprintk(2, "VIDIOC_S_INPUT: %d\n", input); | ||
495 | |||
496 | if (!av7110->analog_tuner_flags) | ||
497 | return input ? -EINVAL : 0; | ||
498 | |||
499 | if (input >= 4) | ||
500 | return -EINVAL; | ||
501 | |||
502 | av7110->current_input = input; | ||
503 | return av7110_dvb_c_switch(fh); | ||
504 | } | ||
505 | |||
506 | static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) | ||
507 | { | ||
508 | dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); | ||
509 | if (a->index != 0) | ||
510 | return -EINVAL; | ||
511 | *a = msp3400_v4l2_audio; | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) | ||
516 | { | ||
517 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
518 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
519 | |||
520 | dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); | ||
521 | if (a->index != 0) | ||
522 | return -EINVAL; | ||
523 | if (av7110->current_input >= 2) | ||
524 | return -EINVAL; | ||
525 | *a = msp3400_v4l2_audio; | ||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) | ||
530 | { | ||
531 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
532 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
533 | |||
534 | dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); | ||
535 | if (av7110->current_input >= 2) | ||
536 | return -EINVAL; | ||
537 | return a->index ? -EINVAL : 0; | ||
538 | } | ||
539 | |||
540 | static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, | ||
541 | struct v4l2_sliced_vbi_cap *cap) | ||
542 | { | ||
543 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
544 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
545 | |||
546 | dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); | ||
547 | if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) | ||
548 | return -EINVAL; | ||
549 | if (FW_VERSION(av7110->arm_app) >= 0x2623) { | ||
550 | cap->service_set = V4L2_SLICED_WSS_625; | ||
551 | cap->service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
552 | } | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, | ||
557 | struct v4l2_format *f) | ||
558 | { | ||
559 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
560 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
561 | |||
562 | dprintk(2, "VIDIOC_G_FMT:\n"); | ||
563 | if (FW_VERSION(av7110->arm_app) < 0x2623) | ||
564 | return -EINVAL; | ||
565 | memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); | ||
566 | if (av7110->wssMode) { | ||
567 | f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; | ||
568 | f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
569 | f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); | ||
570 | } | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, | ||
575 | struct v4l2_format *f) | ||
576 | { | ||
577 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
578 | struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; | ||
579 | |||
580 | dprintk(2, "VIDIOC_S_FMT\n"); | ||
581 | if (FW_VERSION(av7110->arm_app) < 0x2623) | ||
582 | return -EINVAL; | ||
583 | if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && | ||
584 | f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { | ||
585 | memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced)); | ||
586 | /* WSS controlled by firmware */ | ||
587 | av7110->wssMode = 0; | ||
588 | av7110->wssData = 0; | ||
589 | return av7110_fw_cmd(av7110, COMTYPE_ENCODER, | ||
590 | SetWSSConfig, 1, 0); | ||
591 | } else { | ||
592 | memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced)); | ||
593 | f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; | ||
594 | f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
595 | f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); | ||
596 | /* WSS controlled by userspace */ | ||
597 | av7110->wssMode = 1; | ||
598 | av7110->wssData = 0; | ||
599 | } | ||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | static int av7110_vbi_reset(struct file *file) | ||
604 | { | ||
605 | struct saa7146_fh *fh = file->private_data; | ||
606 | struct saa7146_dev *dev = fh->dev; | ||
607 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | ||
608 | |||
609 | dprintk(2, "%s\n", __func__); | ||
610 | av7110->wssMode = 0; | ||
611 | av7110->wssData = 0; | ||
612 | if (FW_VERSION(av7110->arm_app) < 0x2623) | ||
613 | return 0; | ||
614 | else | ||
615 | return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); | ||
616 | } | ||
617 | |||
618 | static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) | ||
619 | { | ||
620 | struct saa7146_fh *fh = file->private_data; | ||
621 | struct saa7146_dev *dev = fh->dev; | ||
622 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | ||
623 | struct v4l2_sliced_vbi_data d; | ||
624 | int rc; | ||
625 | |||
626 | dprintk(2, "%s\n", __func__); | ||
627 | if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d) | ||
628 | return -EINVAL; | ||
629 | if (copy_from_user(&d, data, count)) | ||
630 | return -EFAULT; | ||
631 | if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) | ||
632 | return -EINVAL; | ||
633 | if (d.id) | ||
634 | av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; | ||
635 | else | ||
636 | av7110->wssData = 0x8000; | ||
637 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData); | ||
638 | return (rc < 0) ? rc : count; | ||
639 | } | ||
640 | |||
641 | /**************************************************************************** | ||
642 | * INITIALIZATION | ||
643 | ****************************************************************************/ | ||
644 | |||
645 | static u8 saa7113_init_regs[] = { | ||
646 | 0x02, 0xd0, | ||
647 | 0x03, 0x23, | ||
648 | 0x04, 0x00, | ||
649 | 0x05, 0x00, | ||
650 | 0x06, 0xe9, | ||
651 | 0x07, 0x0d, | ||
652 | 0x08, 0x98, | ||
653 | 0x09, 0x02, | ||
654 | 0x0a, 0x80, | ||
655 | 0x0b, 0x40, | ||
656 | 0x0c, 0x40, | ||
657 | 0x0d, 0x00, | ||
658 | 0x0e, 0x01, | ||
659 | 0x0f, 0x7c, | ||
660 | 0x10, 0x48, | ||
661 | 0x11, 0x0c, | ||
662 | 0x12, 0x8b, | ||
663 | 0x13, 0x1a, | ||
664 | 0x14, 0x00, | ||
665 | 0x15, 0x00, | ||
666 | 0x16, 0x00, | ||
667 | 0x17, 0x00, | ||
668 | 0x18, 0x00, | ||
669 | 0x19, 0x00, | ||
670 | 0x1a, 0x00, | ||
671 | 0x1b, 0x00, | ||
672 | 0x1c, 0x00, | ||
673 | 0x1d, 0x00, | ||
674 | 0x1e, 0x00, | ||
675 | |||
676 | 0x41, 0x77, | ||
677 | 0x42, 0x77, | ||
678 | 0x43, 0x77, | ||
679 | 0x44, 0x77, | ||
680 | 0x45, 0x77, | ||
681 | 0x46, 0x77, | ||
682 | 0x47, 0x77, | ||
683 | 0x48, 0x77, | ||
684 | 0x49, 0x77, | ||
685 | 0x4a, 0x77, | ||
686 | 0x4b, 0x77, | ||
687 | 0x4c, 0x77, | ||
688 | 0x4d, 0x77, | ||
689 | 0x4e, 0x77, | ||
690 | 0x4f, 0x77, | ||
691 | 0x50, 0x77, | ||
692 | 0x51, 0x77, | ||
693 | 0x52, 0x77, | ||
694 | 0x53, 0x77, | ||
695 | 0x54, 0x77, | ||
696 | 0x55, 0x77, | ||
697 | 0x56, 0x77, | ||
698 | 0x57, 0xff, | ||
699 | |||
700 | 0xff | ||
701 | }; | ||
702 | |||
703 | |||
704 | static struct saa7146_ext_vv av7110_vv_data_st; | ||
705 | static struct saa7146_ext_vv av7110_vv_data_c; | ||
706 | |||
707 | int av7110_init_analog_module(struct av7110 *av7110) | ||
708 | { | ||
709 | u16 version1, version2; | ||
710 | |||
711 | if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 && | ||
712 | i2c_writereg(av7110, 0x80, 0x0, 0) == 1) { | ||
713 | pr_info("DVB-C analog module @ card %d detected, initializing MSP3400\n", | ||
714 | av7110->dvb_adapter.num); | ||
715 | av7110->adac_type = DVB_ADAC_MSP34x0; | ||
716 | } else if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1 && | ||
717 | i2c_writereg(av7110, 0x84, 0x0, 0) == 1) { | ||
718 | pr_info("DVB-C analog module @ card %d detected, initializing MSP3415\n", | ||
719 | av7110->dvb_adapter.num); | ||
720 | av7110->adac_type = DVB_ADAC_MSP34x5; | ||
721 | } else | ||
722 | return -ENODEV; | ||
723 | |||
724 | msleep(100); // the probing above resets the msp... | ||
725 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); | ||
726 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); | ||
727 | dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n", | ||
728 | av7110->dvb_adapter.num, version1, version2); | ||
729 | msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); | ||
730 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone | ||
731 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source | ||
732 | msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source | ||
733 | msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume | ||
734 | msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source | ||
735 | msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume | ||
736 | msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART | ||
737 | |||
738 | if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) { | ||
739 | pr_info("saa7113 not accessible\n"); | ||
740 | } else { | ||
741 | u8 *i = saa7113_init_regs; | ||
742 | |||
743 | if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) { | ||
744 | /* Fujitsu/Siemens DVB-Cable */ | ||
745 | av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820; | ||
746 | } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) { | ||
747 | /* Hauppauge/TT DVB-C premium */ | ||
748 | av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820; | ||
749 | } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) { | ||
750 | /* Hauppauge/TT DVB-C premium */ | ||
751 | av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297; | ||
752 | } | ||
753 | |||
754 | /* setup for DVB by default */ | ||
755 | if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { | ||
756 | if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20)) | ||
757 | dprintk(1, "setting band in demodulator failed\n"); | ||
758 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { | ||
759 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) | ||
760 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) | ||
761 | } | ||
762 | |||
763 | /* init the saa7113 */ | ||
764 | while (*i != 0xff) { | ||
765 | if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) { | ||
766 | dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num); | ||
767 | break; | ||
768 | } | ||
769 | i += 2; | ||
770 | } | ||
771 | /* setup msp for analog sound: B/G Dual-FM */ | ||
772 | msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV | ||
773 | msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1 | ||
774 | msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1 | ||
775 | msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1 | ||
776 | msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1 | ||
777 | msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1 | ||
778 | msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1 | ||
779 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2 | ||
780 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2 | ||
781 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2 | ||
782 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2 | ||
783 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2 | ||
784 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2 | ||
785 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2 | ||
786 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2 | ||
787 | msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2 | ||
788 | msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG | ||
789 | msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz | ||
790 | msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI | ||
791 | msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz | ||
792 | msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI | ||
793 | msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2 | ||
794 | } | ||
795 | |||
796 | memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2); | ||
797 | /* set dd1 stream a & b */ | ||
798 | saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000); | ||
799 | saa7146_write(av7110->dev, DD1_INIT, 0x03000700); | ||
800 | saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
801 | |||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | int av7110_init_v4l(struct av7110 *av7110) | ||
806 | { | ||
807 | struct saa7146_dev* dev = av7110->dev; | ||
808 | struct saa7146_ext_vv *vv_data; | ||
809 | int ret; | ||
810 | |||
811 | /* special case DVB-C: these cards have an analog tuner | ||
812 | plus need some special handling, so we have separate | ||
813 | saa7146_ext_vv data for these... */ | ||
814 | if (av7110->analog_tuner_flags) | ||
815 | vv_data = &av7110_vv_data_c; | ||
816 | else | ||
817 | vv_data = &av7110_vv_data_st; | ||
818 | ret = saa7146_vv_init(dev, vv_data); | ||
819 | |||
820 | if (ret) { | ||
821 | ERR("cannot init capture device. skipping\n"); | ||
822 | return -ENODEV; | ||
823 | } | ||
824 | vv_data->vid_ops.vidioc_enum_input = vidioc_enum_input; | ||
825 | vv_data->vid_ops.vidioc_g_input = vidioc_g_input; | ||
826 | vv_data->vid_ops.vidioc_s_input = vidioc_s_input; | ||
827 | vv_data->vid_ops.vidioc_g_tuner = vidioc_g_tuner; | ||
828 | vv_data->vid_ops.vidioc_s_tuner = vidioc_s_tuner; | ||
829 | vv_data->vid_ops.vidioc_g_frequency = vidioc_g_frequency; | ||
830 | vv_data->vid_ops.vidioc_s_frequency = vidioc_s_frequency; | ||
831 | vv_data->vid_ops.vidioc_enumaudio = vidioc_enumaudio; | ||
832 | vv_data->vid_ops.vidioc_g_audio = vidioc_g_audio; | ||
833 | vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio; | ||
834 | vv_data->vid_ops.vidioc_g_fmt_vbi_cap = NULL; | ||
835 | |||
836 | vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner; | ||
837 | vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner; | ||
838 | vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency; | ||
839 | vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency; | ||
840 | vv_data->vbi_ops.vidioc_g_fmt_vbi_cap = NULL; | ||
841 | vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap; | ||
842 | vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out; | ||
843 | vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out; | ||
844 | |||
845 | if (FW_VERSION(av7110->arm_app) < 0x2623) | ||
846 | vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT; | ||
847 | |||
848 | if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { | ||
849 | ERR("cannot register capture device. skipping\n"); | ||
850 | saa7146_vv_release(dev); | ||
851 | return -ENODEV; | ||
852 | } | ||
853 | if (FW_VERSION(av7110->arm_app) >= 0x2623) { | ||
854 | if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) | ||
855 | ERR("cannot register vbi v4l2 device. skipping\n"); | ||
856 | } | ||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | int av7110_exit_v4l(struct av7110 *av7110) | ||
861 | { | ||
862 | struct saa7146_dev* dev = av7110->dev; | ||
863 | |||
864 | saa7146_unregister_device(&av7110->v4l_dev, av7110->dev); | ||
865 | saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); | ||
866 | |||
867 | saa7146_vv_release(dev); | ||
868 | |||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | |||
873 | |||
874 | /* FIXME: these values are experimental values that look better than the | ||
875 | values from the latest "official" driver -- at least for me... (MiHu) */ | ||
876 | static struct saa7146_standard standard[] = { | ||
877 | { | ||
878 | .name = "PAL", .id = V4L2_STD_PAL_BG, | ||
879 | .v_offset = 0x15, .v_field = 288, | ||
880 | .h_offset = 0x48, .h_pixels = 708, | ||
881 | .v_max_out = 576, .h_max_out = 768, | ||
882 | }, { | ||
883 | .name = "NTSC", .id = V4L2_STD_NTSC, | ||
884 | .v_offset = 0x10, .v_field = 244, | ||
885 | .h_offset = 0x40, .h_pixels = 708, | ||
886 | .v_max_out = 480, .h_max_out = 640, | ||
887 | } | ||
888 | }; | ||
889 | |||
890 | static struct saa7146_standard analog_standard[] = { | ||
891 | { | ||
892 | .name = "PAL", .id = V4L2_STD_PAL_BG, | ||
893 | .v_offset = 0x1b, .v_field = 288, | ||
894 | .h_offset = 0x08, .h_pixels = 708, | ||
895 | .v_max_out = 576, .h_max_out = 768, | ||
896 | }, { | ||
897 | .name = "NTSC", .id = V4L2_STD_NTSC, | ||
898 | .v_offset = 0x10, .v_field = 244, | ||
899 | .h_offset = 0x40, .h_pixels = 708, | ||
900 | .v_max_out = 480, .h_max_out = 640, | ||
901 | } | ||
902 | }; | ||
903 | |||
904 | static struct saa7146_standard dvb_standard[] = { | ||
905 | { | ||
906 | .name = "PAL", .id = V4L2_STD_PAL_BG, | ||
907 | .v_offset = 0x14, .v_field = 288, | ||
908 | .h_offset = 0x48, .h_pixels = 708, | ||
909 | .v_max_out = 576, .h_max_out = 768, | ||
910 | }, { | ||
911 | .name = "NTSC", .id = V4L2_STD_NTSC, | ||
912 | .v_offset = 0x10, .v_field = 244, | ||
913 | .h_offset = 0x40, .h_pixels = 708, | ||
914 | .v_max_out = 480, .h_max_out = 640, | ||
915 | } | ||
916 | }; | ||
917 | |||
918 | static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) | ||
919 | { | ||
920 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | ||
921 | |||
922 | if (std->id & V4L2_STD_PAL) { | ||
923 | av7110->vidmode = AV7110_VIDEO_MODE_PAL; | ||
924 | av7110_set_vidmode(av7110, av7110->vidmode); | ||
925 | } | ||
926 | else if (std->id & V4L2_STD_NTSC) { | ||
927 | av7110->vidmode = AV7110_VIDEO_MODE_NTSC; | ||
928 | av7110_set_vidmode(av7110, av7110->vidmode); | ||
929 | } | ||
930 | else | ||
931 | return -1; | ||
932 | |||
933 | return 0; | ||
934 | } | ||
935 | |||
936 | |||
937 | static struct saa7146_ext_vv av7110_vv_data_st = { | ||
938 | .inputs = 1, | ||
939 | .audios = 1, | ||
940 | .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO, | ||
941 | .flags = 0, | ||
942 | |||
943 | .stds = &standard[0], | ||
944 | .num_stds = ARRAY_SIZE(standard), | ||
945 | .std_callback = &std_callback, | ||
946 | |||
947 | .vbi_fops.open = av7110_vbi_reset, | ||
948 | .vbi_fops.release = av7110_vbi_reset, | ||
949 | .vbi_fops.write = av7110_vbi_write, | ||
950 | }; | ||
951 | |||
952 | static struct saa7146_ext_vv av7110_vv_data_c = { | ||
953 | .inputs = 1, | ||
954 | .audios = 1, | ||
955 | .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO, | ||
956 | .flags = SAA7146_USE_PORT_B_FOR_VBI, | ||
957 | |||
958 | .stds = &standard[0], | ||
959 | .num_stds = ARRAY_SIZE(standard), | ||
960 | .std_callback = &std_callback, | ||
961 | |||
962 | .vbi_fops.open = av7110_vbi_reset, | ||
963 | .vbi_fops.release = av7110_vbi_reset, | ||
964 | .vbi_fops.write = av7110_vbi_write, | ||
965 | }; | ||
966 | |||
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c deleted file mode 100644 index 12ddb53c58dc..000000000000 --- a/drivers/media/dvb/ttpci/budget-av.c +++ /dev/null | |||
@@ -1,1640 +0,0 @@ | |||
1 | /* | ||
2 | * budget-av.c: driver for the SAA7146 based Budget DVB cards | ||
3 | * with analog video in | ||
4 | * | ||
5 | * Compiled from various sources by Michael Hunold <michael@mihu.de> | ||
6 | * | ||
7 | * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & | ||
8 | * Andrew de Quincey <adq_dvb@lidskialf.net> | ||
9 | * | ||
10 | * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> | ||
11 | * | ||
12 | * Copyright (C) 1999-2002 Ralph Metzler | ||
13 | * & Marcus Metzler for convergence integrated media GmbH | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * as published by the Free Software Foundation; either version 2 | ||
18 | * of the License, or (at your option) any later version. | ||
19 | * | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * | ||
27 | * You should have received a copy of the GNU General Public License | ||
28 | * along with this program; if not, write to the Free Software | ||
29 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
30 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
31 | * | ||
32 | * | ||
33 | * the project's page is at http://www.linuxtv.org/ | ||
34 | */ | ||
35 | |||
36 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
37 | |||
38 | #include "budget.h" | ||
39 | #include "stv0299.h" | ||
40 | #include "stb0899_drv.h" | ||
41 | #include "stb0899_reg.h" | ||
42 | #include "stb0899_cfg.h" | ||
43 | #include "tda8261.h" | ||
44 | #include "tda8261_cfg.h" | ||
45 | #include "tda1002x.h" | ||
46 | #include "tda1004x.h" | ||
47 | #include "tua6100.h" | ||
48 | #include "dvb-pll.h" | ||
49 | #include <media/saa7146_vv.h> | ||
50 | #include <linux/module.h> | ||
51 | #include <linux/errno.h> | ||
52 | #include <linux/slab.h> | ||
53 | #include <linux/interrupt.h> | ||
54 | #include <linux/input.h> | ||
55 | #include <linux/spinlock.h> | ||
56 | |||
57 | #include "dvb_ca_en50221.h" | ||
58 | |||
59 | #define DEBICICAM 0x02420000 | ||
60 | |||
61 | #define SLOTSTATUS_NONE 1 | ||
62 | #define SLOTSTATUS_PRESENT 2 | ||
63 | #define SLOTSTATUS_RESET 4 | ||
64 | #define SLOTSTATUS_READY 8 | ||
65 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | ||
66 | |||
67 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
68 | |||
69 | struct budget_av { | ||
70 | struct budget budget; | ||
71 | struct video_device *vd; | ||
72 | int cur_input; | ||
73 | int has_saa7113; | ||
74 | struct tasklet_struct ciintf_irq_tasklet; | ||
75 | int slot_status; | ||
76 | struct dvb_ca_en50221 ca; | ||
77 | u8 reinitialise_demod:1; | ||
78 | }; | ||
79 | |||
80 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); | ||
81 | |||
82 | |||
83 | /* GPIO Connections: | ||
84 | * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! | ||
85 | * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory | ||
86 | * 2 - CI Card Enable (Active Low) | ||
87 | * 3 - CI Card Detect | ||
88 | */ | ||
89 | |||
90 | /**************************************************************************** | ||
91 | * INITIALIZATION | ||
92 | ****************************************************************************/ | ||
93 | |||
94 | static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg) | ||
95 | { | ||
96 | u8 mm1[] = { 0x00 }; | ||
97 | u8 mm2[] = { 0x00 }; | ||
98 | struct i2c_msg msgs[2]; | ||
99 | |||
100 | msgs[0].flags = 0; | ||
101 | msgs[1].flags = I2C_M_RD; | ||
102 | msgs[0].addr = msgs[1].addr = id / 2; | ||
103 | mm1[0] = reg; | ||
104 | msgs[0].len = 1; | ||
105 | msgs[1].len = 1; | ||
106 | msgs[0].buf = mm1; | ||
107 | msgs[1].buf = mm2; | ||
108 | |||
109 | i2c_transfer(i2c, msgs, 2); | ||
110 | |||
111 | return mm2[0]; | ||
112 | } | ||
113 | |||
114 | static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len) | ||
115 | { | ||
116 | u8 mm1[] = { reg }; | ||
117 | struct i2c_msg msgs[2] = { | ||
118 | {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1}, | ||
119 | {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len} | ||
120 | }; | ||
121 | |||
122 | if (i2c_transfer(i2c, msgs, 2) != 2) | ||
123 | return -EIO; | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val) | ||
129 | { | ||
130 | u8 msg[2] = { reg, val }; | ||
131 | struct i2c_msg msgs; | ||
132 | |||
133 | msgs.flags = 0; | ||
134 | msgs.addr = id / 2; | ||
135 | msgs.len = 2; | ||
136 | msgs.buf = msg; | ||
137 | return i2c_transfer(i2c, &msgs, 1); | ||
138 | } | ||
139 | |||
140 | static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) | ||
141 | { | ||
142 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
143 | int result; | ||
144 | |||
145 | if (slot != 0) | ||
146 | return -EINVAL; | ||
147 | |||
148 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | ||
149 | udelay(1); | ||
150 | |||
151 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); | ||
152 | if (result == -ETIMEDOUT) { | ||
153 | ciintf_slot_shutdown(ca, slot); | ||
154 | pr_info("cam ejected 1\n"); | ||
155 | } | ||
156 | return result; | ||
157 | } | ||
158 | |||
159 | static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) | ||
160 | { | ||
161 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
162 | int result; | ||
163 | |||
164 | if (slot != 0) | ||
165 | return -EINVAL; | ||
166 | |||
167 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | ||
168 | udelay(1); | ||
169 | |||
170 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); | ||
171 | if (result == -ETIMEDOUT) { | ||
172 | ciintf_slot_shutdown(ca, slot); | ||
173 | pr_info("cam ejected 2\n"); | ||
174 | } | ||
175 | return result; | ||
176 | } | ||
177 | |||
178 | static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) | ||
179 | { | ||
180 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
181 | int result; | ||
182 | |||
183 | if (slot != 0) | ||
184 | return -EINVAL; | ||
185 | |||
186 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
187 | udelay(1); | ||
188 | |||
189 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); | ||
190 | if (result == -ETIMEDOUT) { | ||
191 | ciintf_slot_shutdown(ca, slot); | ||
192 | pr_info("cam ejected 3\n"); | ||
193 | return -ETIMEDOUT; | ||
194 | } | ||
195 | return result; | ||
196 | } | ||
197 | |||
198 | static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) | ||
199 | { | ||
200 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
201 | int result; | ||
202 | |||
203 | if (slot != 0) | ||
204 | return -EINVAL; | ||
205 | |||
206 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
207 | udelay(1); | ||
208 | |||
209 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); | ||
210 | if (result == -ETIMEDOUT) { | ||
211 | ciintf_slot_shutdown(ca, slot); | ||
212 | pr_info("cam ejected 5\n"); | ||
213 | } | ||
214 | return result; | ||
215 | } | ||
216 | |||
217 | static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | ||
218 | { | ||
219 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
220 | struct saa7146_dev *saa = budget_av->budget.dev; | ||
221 | |||
222 | if (slot != 0) | ||
223 | return -EINVAL; | ||
224 | |||
225 | dprintk(1, "ciintf_slot_reset\n"); | ||
226 | budget_av->slot_status = SLOTSTATUS_RESET; | ||
227 | |||
228 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | ||
229 | |||
230 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ | ||
231 | msleep(2); | ||
232 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */ | ||
233 | msleep(20); /* 20 ms Vcc settling time */ | ||
234 | |||
235 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ | ||
236 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | ||
237 | msleep(20); | ||
238 | |||
239 | /* reinitialise the frontend if necessary */ | ||
240 | if (budget_av->reinitialise_demod) | ||
241 | dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | ||
247 | { | ||
248 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
249 | struct saa7146_dev *saa = budget_av->budget.dev; | ||
250 | |||
251 | if (slot != 0) | ||
252 | return -EINVAL; | ||
253 | |||
254 | dprintk(1, "ciintf_slot_shutdown\n"); | ||
255 | |||
256 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | ||
257 | budget_av->slot_status = SLOTSTATUS_NONE; | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | ||
263 | { | ||
264 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
265 | struct saa7146_dev *saa = budget_av->budget.dev; | ||
266 | |||
267 | if (slot != 0) | ||
268 | return -EINVAL; | ||
269 | |||
270 | dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); | ||
271 | |||
272 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) | ||
278 | { | ||
279 | struct budget_av *budget_av = (struct budget_av *) ca->data; | ||
280 | struct saa7146_dev *saa = budget_av->budget.dev; | ||
281 | int result; | ||
282 | |||
283 | if (slot != 0) | ||
284 | return -EINVAL; | ||
285 | |||
286 | /* test the card detect line - needs to be done carefully | ||
287 | * since it never goes high for some CAMs on this interface (e.g. topuptv) */ | ||
288 | if (budget_av->slot_status == SLOTSTATUS_NONE) { | ||
289 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | ||
290 | udelay(1); | ||
291 | if (saa7146_read(saa, PSR) & MASK_06) { | ||
292 | if (budget_av->slot_status == SLOTSTATUS_NONE) { | ||
293 | budget_av->slot_status = SLOTSTATUS_PRESENT; | ||
294 | pr_info("cam inserted A\n"); | ||
295 | } | ||
296 | } | ||
297 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
298 | } | ||
299 | |||
300 | /* We also try and read from IO memory to work round the above detection bug. If | ||
301 | * there is no CAM, we will get a timeout. Only done if there is no cam | ||
302 | * present, since this test actually breaks some cams :( | ||
303 | * | ||
304 | * if the CI interface is not open, we also do the above test since we | ||
305 | * don't care if the cam has problems - we'll be resetting it on open() anyway */ | ||
306 | if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { | ||
307 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
308 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); | ||
309 | if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) { | ||
310 | budget_av->slot_status = SLOTSTATUS_PRESENT; | ||
311 | pr_info("cam inserted B\n"); | ||
312 | } else if (result < 0) { | ||
313 | if (budget_av->slot_status != SLOTSTATUS_NONE) { | ||
314 | ciintf_slot_shutdown(ca, slot); | ||
315 | pr_info("cam ejected 5\n"); | ||
316 | return 0; | ||
317 | } | ||
318 | } | ||
319 | } | ||
320 | |||
321 | /* read from attribute memory in reset/ready state to know when the CAM is ready */ | ||
322 | if (budget_av->slot_status == SLOTSTATUS_RESET) { | ||
323 | result = ciintf_read_attribute_mem(ca, slot, 0); | ||
324 | if (result == 0x1d) { | ||
325 | budget_av->slot_status = SLOTSTATUS_READY; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | /* work out correct return code */ | ||
330 | if (budget_av->slot_status != SLOTSTATUS_NONE) { | ||
331 | if (budget_av->slot_status & SLOTSTATUS_READY) { | ||
332 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
333 | } | ||
334 | return DVB_CA_EN50221_POLL_CAM_PRESENT; | ||
335 | } | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int ciintf_init(struct budget_av *budget_av) | ||
340 | { | ||
341 | struct saa7146_dev *saa = budget_av->budget.dev; | ||
342 | int result; | ||
343 | |||
344 | memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); | ||
345 | |||
346 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
347 | saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); | ||
348 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); | ||
349 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
350 | |||
351 | /* Enable DEBI pins */ | ||
352 | saa7146_write(saa, MC1, MASK_27 | MASK_11); | ||
353 | |||
354 | /* register CI interface */ | ||
355 | budget_av->ca.owner = THIS_MODULE; | ||
356 | budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem; | ||
357 | budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem; | ||
358 | budget_av->ca.read_cam_control = ciintf_read_cam_control; | ||
359 | budget_av->ca.write_cam_control = ciintf_write_cam_control; | ||
360 | budget_av->ca.slot_reset = ciintf_slot_reset; | ||
361 | budget_av->ca.slot_shutdown = ciintf_slot_shutdown; | ||
362 | budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; | ||
363 | budget_av->ca.poll_slot_status = ciintf_poll_slot_status; | ||
364 | budget_av->ca.data = budget_av; | ||
365 | budget_av->budget.ci_present = 1; | ||
366 | budget_av->slot_status = SLOTSTATUS_NONE; | ||
367 | |||
368 | if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, | ||
369 | &budget_av->ca, 0, 1)) != 0) { | ||
370 | pr_err("ci initialisation failed\n"); | ||
371 | goto error; | ||
372 | } | ||
373 | |||
374 | pr_info("ci interface initialised\n"); | ||
375 | return 0; | ||
376 | |||
377 | error: | ||
378 | saa7146_write(saa, MC1, MASK_27); | ||
379 | return result; | ||
380 | } | ||
381 | |||
382 | static void ciintf_deinit(struct budget_av *budget_av) | ||
383 | { | ||
384 | struct saa7146_dev *saa = budget_av->budget.dev; | ||
385 | |||
386 | saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); | ||
387 | saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); | ||
388 | saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); | ||
389 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | ||
390 | |||
391 | /* release the CA device */ | ||
392 | dvb_ca_en50221_release(&budget_av->ca); | ||
393 | |||
394 | /* disable DEBI pins */ | ||
395 | saa7146_write(saa, MC1, MASK_27); | ||
396 | } | ||
397 | |||
398 | |||
399 | static const u8 saa7113_tab[] = { | ||
400 | 0x01, 0x08, | ||
401 | 0x02, 0xc0, | ||
402 | 0x03, 0x33, | ||
403 | 0x04, 0x00, | ||
404 | 0x05, 0x00, | ||
405 | 0x06, 0xeb, | ||
406 | 0x07, 0xe0, | ||
407 | 0x08, 0x28, | ||
408 | 0x09, 0x00, | ||
409 | 0x0a, 0x80, | ||
410 | 0x0b, 0x47, | ||
411 | 0x0c, 0x40, | ||
412 | 0x0d, 0x00, | ||
413 | 0x0e, 0x01, | ||
414 | 0x0f, 0x44, | ||
415 | |||
416 | 0x10, 0x08, | ||
417 | 0x11, 0x0c, | ||
418 | 0x12, 0x7b, | ||
419 | 0x13, 0x00, | ||
420 | 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, | ||
421 | |||
422 | 0x57, 0xff, | ||
423 | 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07, | ||
424 | 0x5b, 0x83, 0x5e, 0x00, | ||
425 | 0xff | ||
426 | }; | ||
427 | |||
428 | static int saa7113_init(struct budget_av *budget_av) | ||
429 | { | ||
430 | struct budget *budget = &budget_av->budget; | ||
431 | struct saa7146_dev *saa = budget->dev; | ||
432 | const u8 *data = saa7113_tab; | ||
433 | |||
434 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); | ||
435 | msleep(200); | ||
436 | |||
437 | if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { | ||
438 | dprintk(1, "saa7113 not found on KNC card\n"); | ||
439 | return -ENODEV; | ||
440 | } | ||
441 | |||
442 | dprintk(1, "saa7113 detected and initializing\n"); | ||
443 | |||
444 | while (*data != 0xff) { | ||
445 | i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1)); | ||
446 | data += 2; | ||
447 | } | ||
448 | |||
449 | dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f)); | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int saa7113_setinput(struct budget_av *budget_av, int input) | ||
455 | { | ||
456 | struct budget *budget = &budget_av->budget; | ||
457 | |||
458 | if (1 != budget_av->has_saa7113) | ||
459 | return -ENODEV; | ||
460 | |||
461 | if (input == 1) { | ||
462 | i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7); | ||
463 | i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80); | ||
464 | } else if (input == 0) { | ||
465 | i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0); | ||
466 | i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00); | ||
467 | } else | ||
468 | return -EINVAL; | ||
469 | |||
470 | budget_av->cur_input = input; | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | |||
475 | static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) | ||
476 | { | ||
477 | u8 aclk = 0; | ||
478 | u8 bclk = 0; | ||
479 | u8 m1; | ||
480 | |||
481 | aclk = 0xb5; | ||
482 | if (srate < 2000000) | ||
483 | bclk = 0x86; | ||
484 | else if (srate < 5000000) | ||
485 | bclk = 0x89; | ||
486 | else if (srate < 15000000) | ||
487 | bclk = 0x8f; | ||
488 | else if (srate < 45000000) | ||
489 | bclk = 0x95; | ||
490 | |||
491 | m1 = 0x14; | ||
492 | if (srate < 4000000) | ||
493 | m1 = 0x10; | ||
494 | |||
495 | stv0299_writereg(fe, 0x13, aclk); | ||
496 | stv0299_writereg(fe, 0x14, bclk); | ||
497 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
498 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
499 | stv0299_writereg(fe, 0x21, (ratio) & 0xf0); | ||
500 | stv0299_writereg(fe, 0x0f, 0x80 | m1); | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe) | ||
506 | { | ||
507 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
508 | u32 div; | ||
509 | u8 buf[4]; | ||
510 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
511 | struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; | ||
512 | |||
513 | if ((c->frequency < 950000) || (c->frequency > 2150000)) | ||
514 | return -EINVAL; | ||
515 | |||
516 | div = (c->frequency + (125 - 1)) / 125; /* round correctly */ | ||
517 | buf[0] = (div >> 8) & 0x7f; | ||
518 | buf[1] = div & 0xff; | ||
519 | buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
520 | buf[3] = 0x20; | ||
521 | |||
522 | if (c->symbol_rate < 4000000) | ||
523 | buf[3] |= 1; | ||
524 | |||
525 | if (c->frequency < 1250000) | ||
526 | buf[3] |= 0; | ||
527 | else if (c->frequency < 1550000) | ||
528 | buf[3] |= 0x40; | ||
529 | else if (c->frequency < 2050000) | ||
530 | buf[3] |= 0x80; | ||
531 | else if (c->frequency < 2150000) | ||
532 | buf[3] |= 0xC0; | ||
533 | |||
534 | if (fe->ops.i2c_gate_ctrl) | ||
535 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
536 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | ||
537 | return -EIO; | ||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | static u8 typhoon_cinergy1200s_inittab[] = { | ||
542 | 0x01, 0x15, | ||
543 | 0x02, 0x30, | ||
544 | 0x03, 0x00, | ||
545 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
546 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
547 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
548 | 0x07, 0x00, /* DAC LSB */ | ||
549 | 0x08, 0x40, /* DiSEqC off */ | ||
550 | 0x09, 0x00, /* FIFO */ | ||
551 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
552 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
553 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
554 | 0x10, 0x3f, // AGC2 0x3d | ||
555 | 0x11, 0x84, | ||
556 | 0x12, 0xb9, | ||
557 | 0x15, 0xc9, // lock detector threshold | ||
558 | 0x16, 0x00, | ||
559 | 0x17, 0x00, | ||
560 | 0x18, 0x00, | ||
561 | 0x19, 0x00, | ||
562 | 0x1a, 0x00, | ||
563 | 0x1f, 0x50, | ||
564 | 0x20, 0x00, | ||
565 | 0x21, 0x00, | ||
566 | 0x22, 0x00, | ||
567 | 0x23, 0x00, | ||
568 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
569 | 0x29, 0x1e, // 1/2 threshold | ||
570 | 0x2a, 0x14, // 2/3 threshold | ||
571 | 0x2b, 0x0f, // 3/4 threshold | ||
572 | 0x2c, 0x09, // 5/6 threshold | ||
573 | 0x2d, 0x05, // 7/8 threshold | ||
574 | 0x2e, 0x01, | ||
575 | 0x31, 0x1f, // test all FECs | ||
576 | 0x32, 0x19, // viterbi and synchro search | ||
577 | 0x33, 0xfc, // rs control | ||
578 | 0x34, 0x93, // error control | ||
579 | 0x0f, 0x92, | ||
580 | 0xff, 0xff | ||
581 | }; | ||
582 | |||
583 | static struct stv0299_config typhoon_config = { | ||
584 | .demod_address = 0x68, | ||
585 | .inittab = typhoon_cinergy1200s_inittab, | ||
586 | .mclk = 88000000UL, | ||
587 | .invert = 0, | ||
588 | .skip_reinit = 0, | ||
589 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
590 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
591 | .min_delay_ms = 100, | ||
592 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | ||
593 | }; | ||
594 | |||
595 | |||
596 | static struct stv0299_config cinergy_1200s_config = { | ||
597 | .demod_address = 0x68, | ||
598 | .inittab = typhoon_cinergy1200s_inittab, | ||
599 | .mclk = 88000000UL, | ||
600 | .invert = 0, | ||
601 | .skip_reinit = 0, | ||
602 | .lock_output = STV0299_LOCKOUTPUT_0, | ||
603 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
604 | .min_delay_ms = 100, | ||
605 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | ||
606 | }; | ||
607 | |||
608 | static struct stv0299_config cinergy_1200s_1894_0010_config = { | ||
609 | .demod_address = 0x68, | ||
610 | .inittab = typhoon_cinergy1200s_inittab, | ||
611 | .mclk = 88000000UL, | ||
612 | .invert = 1, | ||
613 | .skip_reinit = 0, | ||
614 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
615 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
616 | .min_delay_ms = 100, | ||
617 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | ||
618 | }; | ||
619 | |||
620 | static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe) | ||
621 | { | ||
622 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
623 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
624 | u8 buf[6]; | ||
625 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; | ||
626 | int i; | ||
627 | |||
628 | #define CU1216_IF 36125000 | ||
629 | #define TUNER_MUL 62500 | ||
630 | |||
631 | u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
632 | |||
633 | buf[0] = (div >> 8) & 0x7f; | ||
634 | buf[1] = div & 0xff; | ||
635 | buf[2] = 0xce; | ||
636 | buf[3] = (c->frequency < 150000000 ? 0x01 : | ||
637 | c->frequency < 445000000 ? 0x02 : 0x04); | ||
638 | buf[4] = 0xde; | ||
639 | buf[5] = 0x20; | ||
640 | |||
641 | if (fe->ops.i2c_gate_ctrl) | ||
642 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
643 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | ||
644 | return -EIO; | ||
645 | |||
646 | /* wait for the pll lock */ | ||
647 | msg.flags = I2C_M_RD; | ||
648 | msg.len = 1; | ||
649 | for (i = 0; i < 20; i++) { | ||
650 | if (fe->ops.i2c_gate_ctrl) | ||
651 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
652 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
653 | break; | ||
654 | msleep(10); | ||
655 | } | ||
656 | |||
657 | /* switch the charge pump to the lower current */ | ||
658 | msg.flags = 0; | ||
659 | msg.len = 2; | ||
660 | msg.buf = &buf[2]; | ||
661 | buf[2] &= ~0x40; | ||
662 | if (fe->ops.i2c_gate_ctrl) | ||
663 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
664 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | ||
665 | return -EIO; | ||
666 | |||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | static struct tda1002x_config philips_cu1216_config = { | ||
671 | .demod_address = 0x0c, | ||
672 | .invert = 1, | ||
673 | }; | ||
674 | |||
675 | static struct tda1002x_config philips_cu1216_config_altaddress = { | ||
676 | .demod_address = 0x0d, | ||
677 | .invert = 0, | ||
678 | }; | ||
679 | |||
680 | static struct tda10023_config philips_cu1216_tda10023_config = { | ||
681 | .demod_address = 0x0c, | ||
682 | .invert = 1, | ||
683 | }; | ||
684 | |||
685 | static int philips_tu1216_tuner_init(struct dvb_frontend *fe) | ||
686 | { | ||
687 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
688 | static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | ||
689 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; | ||
690 | |||
691 | // setup PLL configuration | ||
692 | if (fe->ops.i2c_gate_ctrl) | ||
693 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
694 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | ||
695 | return -EIO; | ||
696 | msleep(1); | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe) | ||
702 | { | ||
703 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
704 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
705 | u8 tuner_buf[4]; | ||
706 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = | ||
707 | sizeof(tuner_buf) }; | ||
708 | int tuner_frequency = 0; | ||
709 | u8 band, cp, filter; | ||
710 | |||
711 | // determine charge pump | ||
712 | tuner_frequency = c->frequency + 36166000; | ||
713 | if (tuner_frequency < 87000000) | ||
714 | return -EINVAL; | ||
715 | else if (tuner_frequency < 130000000) | ||
716 | cp = 3; | ||
717 | else if (tuner_frequency < 160000000) | ||
718 | cp = 5; | ||
719 | else if (tuner_frequency < 200000000) | ||
720 | cp = 6; | ||
721 | else if (tuner_frequency < 290000000) | ||
722 | cp = 3; | ||
723 | else if (tuner_frequency < 420000000) | ||
724 | cp = 5; | ||
725 | else if (tuner_frequency < 480000000) | ||
726 | cp = 6; | ||
727 | else if (tuner_frequency < 620000000) | ||
728 | cp = 3; | ||
729 | else if (tuner_frequency < 830000000) | ||
730 | cp = 5; | ||
731 | else if (tuner_frequency < 895000000) | ||
732 | cp = 7; | ||
733 | else | ||
734 | return -EINVAL; | ||
735 | |||
736 | // determine band | ||
737 | if (c->frequency < 49000000) | ||
738 | return -EINVAL; | ||
739 | else if (c->frequency < 161000000) | ||
740 | band = 1; | ||
741 | else if (c->frequency < 444000000) | ||
742 | band = 2; | ||
743 | else if (c->frequency < 861000000) | ||
744 | band = 4; | ||
745 | else | ||
746 | return -EINVAL; | ||
747 | |||
748 | // setup PLL filter | ||
749 | switch (c->bandwidth_hz) { | ||
750 | case 6000000: | ||
751 | filter = 0; | ||
752 | break; | ||
753 | |||
754 | case 7000000: | ||
755 | filter = 0; | ||
756 | break; | ||
757 | |||
758 | case 8000000: | ||
759 | filter = 1; | ||
760 | break; | ||
761 | |||
762 | default: | ||
763 | return -EINVAL; | ||
764 | } | ||
765 | |||
766 | // calculate divisor | ||
767 | // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6) | ||
768 | tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000; | ||
769 | |||
770 | // setup tuner buffer | ||
771 | tuner_buf[0] = (tuner_frequency >> 8) & 0x7f; | ||
772 | tuner_buf[1] = tuner_frequency & 0xff; | ||
773 | tuner_buf[2] = 0xca; | ||
774 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | ||
775 | |||
776 | if (fe->ops.i2c_gate_ctrl) | ||
777 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
778 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | ||
779 | return -EIO; | ||
780 | |||
781 | msleep(1); | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static int philips_tu1216_request_firmware(struct dvb_frontend *fe, | ||
786 | const struct firmware **fw, char *name) | ||
787 | { | ||
788 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
789 | |||
790 | return request_firmware(fw, name, &budget->dev->pci->dev); | ||
791 | } | ||
792 | |||
793 | static struct tda1004x_config philips_tu1216_config = { | ||
794 | |||
795 | .demod_address = 0x8, | ||
796 | .invert = 1, | ||
797 | .invert_oclk = 1, | ||
798 | .xtal_freq = TDA10046_XTAL_4M, | ||
799 | .agc_config = TDA10046_AGC_DEFAULT, | ||
800 | .if_freq = TDA10046_FREQ_3617, | ||
801 | .request_firmware = philips_tu1216_request_firmware, | ||
802 | }; | ||
803 | |||
804 | static u8 philips_sd1878_inittab[] = { | ||
805 | 0x01, 0x15, | ||
806 | 0x02, 0x30, | ||
807 | 0x03, 0x00, | ||
808 | 0x04, 0x7d, | ||
809 | 0x05, 0x35, | ||
810 | 0x06, 0x40, | ||
811 | 0x07, 0x00, | ||
812 | 0x08, 0x43, | ||
813 | 0x09, 0x02, | ||
814 | 0x0C, 0x51, | ||
815 | 0x0D, 0x82, | ||
816 | 0x0E, 0x23, | ||
817 | 0x10, 0x3f, | ||
818 | 0x11, 0x84, | ||
819 | 0x12, 0xb9, | ||
820 | 0x15, 0xc9, | ||
821 | 0x16, 0x19, | ||
822 | 0x17, 0x8c, | ||
823 | 0x18, 0x59, | ||
824 | 0x19, 0xf8, | ||
825 | 0x1a, 0xfe, | ||
826 | 0x1c, 0x7f, | ||
827 | 0x1d, 0x00, | ||
828 | 0x1e, 0x00, | ||
829 | 0x1f, 0x50, | ||
830 | 0x20, 0x00, | ||
831 | 0x21, 0x00, | ||
832 | 0x22, 0x00, | ||
833 | 0x23, 0x00, | ||
834 | 0x28, 0x00, | ||
835 | 0x29, 0x28, | ||
836 | 0x2a, 0x14, | ||
837 | 0x2b, 0x0f, | ||
838 | 0x2c, 0x09, | ||
839 | 0x2d, 0x09, | ||
840 | 0x31, 0x1f, | ||
841 | 0x32, 0x19, | ||
842 | 0x33, 0xfc, | ||
843 | 0x34, 0x93, | ||
844 | 0xff, 0xff | ||
845 | }; | ||
846 | |||
847 | static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, | ||
848 | u32 srate, u32 ratio) | ||
849 | { | ||
850 | u8 aclk = 0; | ||
851 | u8 bclk = 0; | ||
852 | u8 m1; | ||
853 | |||
854 | aclk = 0xb5; | ||
855 | if (srate < 2000000) | ||
856 | bclk = 0x86; | ||
857 | else if (srate < 5000000) | ||
858 | bclk = 0x89; | ||
859 | else if (srate < 15000000) | ||
860 | bclk = 0x8f; | ||
861 | else if (srate < 45000000) | ||
862 | bclk = 0x95; | ||
863 | |||
864 | m1 = 0x14; | ||
865 | if (srate < 4000000) | ||
866 | m1 = 0x10; | ||
867 | |||
868 | stv0299_writereg(fe, 0x0e, 0x23); | ||
869 | stv0299_writereg(fe, 0x0f, 0x94); | ||
870 | stv0299_writereg(fe, 0x10, 0x39); | ||
871 | stv0299_writereg(fe, 0x13, aclk); | ||
872 | stv0299_writereg(fe, 0x14, bclk); | ||
873 | stv0299_writereg(fe, 0x15, 0xc9); | ||
874 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
875 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
876 | stv0299_writereg(fe, 0x21, (ratio) & 0xf0); | ||
877 | stv0299_writereg(fe, 0x0f, 0x80 | m1); | ||
878 | |||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | static struct stv0299_config philips_sd1878_config = { | ||
883 | .demod_address = 0x68, | ||
884 | .inittab = philips_sd1878_inittab, | ||
885 | .mclk = 88000000UL, | ||
886 | .invert = 0, | ||
887 | .skip_reinit = 0, | ||
888 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
889 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
890 | .min_delay_ms = 100, | ||
891 | .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, | ||
892 | }; | ||
893 | |||
894 | /* KNC1 DVB-S (STB0899) Inittab */ | ||
895 | static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = { | ||
896 | |||
897 | { STB0899_DEV_ID , 0x81 }, | ||
898 | { STB0899_DISCNTRL1 , 0x32 }, | ||
899 | { STB0899_DISCNTRL2 , 0x80 }, | ||
900 | { STB0899_DISRX_ST0 , 0x04 }, | ||
901 | { STB0899_DISRX_ST1 , 0x00 }, | ||
902 | { STB0899_DISPARITY , 0x00 }, | ||
903 | { STB0899_DISSTATUS , 0x20 }, | ||
904 | { STB0899_DISF22 , 0x8c }, | ||
905 | { STB0899_DISF22RX , 0x9a }, | ||
906 | { STB0899_SYSREG , 0x0b }, | ||
907 | { STB0899_ACRPRESC , 0x11 }, | ||
908 | { STB0899_ACRDIV1 , 0x0a }, | ||
909 | { STB0899_ACRDIV2 , 0x05 }, | ||
910 | { STB0899_DACR1 , 0x00 }, | ||
911 | { STB0899_DACR2 , 0x00 }, | ||
912 | { STB0899_OUTCFG , 0x00 }, | ||
913 | { STB0899_MODECFG , 0x00 }, | ||
914 | { STB0899_IRQSTATUS_3 , 0x30 }, | ||
915 | { STB0899_IRQSTATUS_2 , 0x00 }, | ||
916 | { STB0899_IRQSTATUS_1 , 0x00 }, | ||
917 | { STB0899_IRQSTATUS_0 , 0x00 }, | ||
918 | { STB0899_IRQMSK_3 , 0xf3 }, | ||
919 | { STB0899_IRQMSK_2 , 0xfc }, | ||
920 | { STB0899_IRQMSK_1 , 0xff }, | ||
921 | { STB0899_IRQMSK_0 , 0xff }, | ||
922 | { STB0899_IRQCFG , 0x00 }, | ||
923 | { STB0899_I2CCFG , 0x88 }, | ||
924 | { STB0899_I2CRPT , 0x58 }, /* Repeater=8, Stop=disabled */ | ||
925 | { STB0899_IOPVALUE5 , 0x00 }, | ||
926 | { STB0899_IOPVALUE4 , 0x20 }, | ||
927 | { STB0899_IOPVALUE3 , 0xc9 }, | ||
928 | { STB0899_IOPVALUE2 , 0x90 }, | ||
929 | { STB0899_IOPVALUE1 , 0x40 }, | ||
930 | { STB0899_IOPVALUE0 , 0x00 }, | ||
931 | { STB0899_GPIO00CFG , 0x82 }, | ||
932 | { STB0899_GPIO01CFG , 0x82 }, | ||
933 | { STB0899_GPIO02CFG , 0x82 }, | ||
934 | { STB0899_GPIO03CFG , 0x82 }, | ||
935 | { STB0899_GPIO04CFG , 0x82 }, | ||
936 | { STB0899_GPIO05CFG , 0x82 }, | ||
937 | { STB0899_GPIO06CFG , 0x82 }, | ||
938 | { STB0899_GPIO07CFG , 0x82 }, | ||
939 | { STB0899_GPIO08CFG , 0x82 }, | ||
940 | { STB0899_GPIO09CFG , 0x82 }, | ||
941 | { STB0899_GPIO10CFG , 0x82 }, | ||
942 | { STB0899_GPIO11CFG , 0x82 }, | ||
943 | { STB0899_GPIO12CFG , 0x82 }, | ||
944 | { STB0899_GPIO13CFG , 0x82 }, | ||
945 | { STB0899_GPIO14CFG , 0x82 }, | ||
946 | { STB0899_GPIO15CFG , 0x82 }, | ||
947 | { STB0899_GPIO16CFG , 0x82 }, | ||
948 | { STB0899_GPIO17CFG , 0x82 }, | ||
949 | { STB0899_GPIO18CFG , 0x82 }, | ||
950 | { STB0899_GPIO19CFG , 0x82 }, | ||
951 | { STB0899_GPIO20CFG , 0x82 }, | ||
952 | { STB0899_SDATCFG , 0xb8 }, | ||
953 | { STB0899_SCLTCFG , 0xba }, | ||
954 | { STB0899_AGCRFCFG , 0x08 }, /* 0x1c */ | ||
955 | { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ | ||
956 | { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ | ||
957 | { STB0899_DIRCLKCFG , 0x82 }, | ||
958 | { STB0899_CLKOUT27CFG , 0x7e }, | ||
959 | { STB0899_STDBYCFG , 0x82 }, | ||
960 | { STB0899_CS0CFG , 0x82 }, | ||
961 | { STB0899_CS1CFG , 0x82 }, | ||
962 | { STB0899_DISEQCOCFG , 0x20 }, | ||
963 | { STB0899_GPIO32CFG , 0x82 }, | ||
964 | { STB0899_GPIO33CFG , 0x82 }, | ||
965 | { STB0899_GPIO34CFG , 0x82 }, | ||
966 | { STB0899_GPIO35CFG , 0x82 }, | ||
967 | { STB0899_GPIO36CFG , 0x82 }, | ||
968 | { STB0899_GPIO37CFG , 0x82 }, | ||
969 | { STB0899_GPIO38CFG , 0x82 }, | ||
970 | { STB0899_GPIO39CFG , 0x82 }, | ||
971 | { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | ||
972 | { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | ||
973 | { STB0899_FILTCTRL , 0x00 }, | ||
974 | { STB0899_SYSCTRL , 0x00 }, | ||
975 | { STB0899_STOPCLK1 , 0x20 }, | ||
976 | { STB0899_STOPCLK2 , 0x00 }, | ||
977 | { STB0899_INTBUFSTATUS , 0x00 }, | ||
978 | { STB0899_INTBUFCTRL , 0x0a }, | ||
979 | { 0xffff , 0xff }, | ||
980 | }; | ||
981 | |||
982 | static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = { | ||
983 | { STB0899_DEMOD , 0x00 }, | ||
984 | { STB0899_RCOMPC , 0xc9 }, | ||
985 | { STB0899_AGC1CN , 0x41 }, | ||
986 | { STB0899_AGC1REF , 0x08 }, | ||
987 | { STB0899_RTC , 0x7a }, | ||
988 | { STB0899_TMGCFG , 0x4e }, | ||
989 | { STB0899_AGC2REF , 0x33 }, | ||
990 | { STB0899_TLSR , 0x84 }, | ||
991 | { STB0899_CFD , 0xee }, | ||
992 | { STB0899_ACLC , 0x87 }, | ||
993 | { STB0899_BCLC , 0x94 }, | ||
994 | { STB0899_EQON , 0x41 }, | ||
995 | { STB0899_LDT , 0xdd }, | ||
996 | { STB0899_LDT2 , 0xc9 }, | ||
997 | { STB0899_EQUALREF , 0xb4 }, | ||
998 | { STB0899_TMGRAMP , 0x10 }, | ||
999 | { STB0899_TMGTHD , 0x30 }, | ||
1000 | { STB0899_IDCCOMP , 0xfb }, | ||
1001 | { STB0899_QDCCOMP , 0x03 }, | ||
1002 | { STB0899_POWERI , 0x3b }, | ||
1003 | { STB0899_POWERQ , 0x3d }, | ||
1004 | { STB0899_RCOMP , 0x81 }, | ||
1005 | { STB0899_AGCIQIN , 0x80 }, | ||
1006 | { STB0899_AGC2I1 , 0x04 }, | ||
1007 | { STB0899_AGC2I2 , 0xf5 }, | ||
1008 | { STB0899_TLIR , 0x25 }, | ||
1009 | { STB0899_RTF , 0x80 }, | ||
1010 | { STB0899_DSTATUS , 0x00 }, | ||
1011 | { STB0899_LDI , 0xca }, | ||
1012 | { STB0899_CFRM , 0xf1 }, | ||
1013 | { STB0899_CFRL , 0xf3 }, | ||
1014 | { STB0899_NIRM , 0x2a }, | ||
1015 | { STB0899_NIRL , 0x05 }, | ||
1016 | { STB0899_ISYMB , 0x17 }, | ||
1017 | { STB0899_QSYMB , 0xfa }, | ||
1018 | { STB0899_SFRH , 0x2f }, | ||
1019 | { STB0899_SFRM , 0x68 }, | ||
1020 | { STB0899_SFRL , 0x40 }, | ||
1021 | { STB0899_SFRUPH , 0x2f }, | ||
1022 | { STB0899_SFRUPM , 0x68 }, | ||
1023 | { STB0899_SFRUPL , 0x40 }, | ||
1024 | { STB0899_EQUAI1 , 0xfd }, | ||
1025 | { STB0899_EQUAQ1 , 0x04 }, | ||
1026 | { STB0899_EQUAI2 , 0x0f }, | ||
1027 | { STB0899_EQUAQ2 , 0xff }, | ||
1028 | { STB0899_EQUAI3 , 0xdf }, | ||
1029 | { STB0899_EQUAQ3 , 0xfa }, | ||
1030 | { STB0899_EQUAI4 , 0x37 }, | ||
1031 | { STB0899_EQUAQ4 , 0x0d }, | ||
1032 | { STB0899_EQUAI5 , 0xbd }, | ||
1033 | { STB0899_EQUAQ5 , 0xf7 }, | ||
1034 | { STB0899_DSTATUS2 , 0x00 }, | ||
1035 | { STB0899_VSTATUS , 0x00 }, | ||
1036 | { STB0899_VERROR , 0xff }, | ||
1037 | { STB0899_IQSWAP , 0x2a }, | ||
1038 | { STB0899_ECNT1M , 0x00 }, | ||
1039 | { STB0899_ECNT1L , 0x00 }, | ||
1040 | { STB0899_ECNT2M , 0x00 }, | ||
1041 | { STB0899_ECNT2L , 0x00 }, | ||
1042 | { STB0899_ECNT3M , 0x00 }, | ||
1043 | { STB0899_ECNT3L , 0x00 }, | ||
1044 | { STB0899_FECAUTO1 , 0x06 }, | ||
1045 | { STB0899_FECM , 0x01 }, | ||
1046 | { STB0899_VTH12 , 0xf0 }, | ||
1047 | { STB0899_VTH23 , 0xa0 }, | ||
1048 | { STB0899_VTH34 , 0x78 }, | ||
1049 | { STB0899_VTH56 , 0x4e }, | ||
1050 | { STB0899_VTH67 , 0x48 }, | ||
1051 | { STB0899_VTH78 , 0x38 }, | ||
1052 | { STB0899_PRVIT , 0xff }, | ||
1053 | { STB0899_VITSYNC , 0x19 }, | ||
1054 | { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | ||
1055 | { STB0899_TSULC , 0x42 }, | ||
1056 | { STB0899_RSLLC , 0x40 }, | ||
1057 | { STB0899_TSLPL , 0x12 }, | ||
1058 | { STB0899_TSCFGH , 0x0c }, | ||
1059 | { STB0899_TSCFGM , 0x00 }, | ||
1060 | { STB0899_TSCFGL , 0x0c }, | ||
1061 | { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ | ||
1062 | { STB0899_RSSYNCDEL , 0x00 }, | ||
1063 | { STB0899_TSINHDELH , 0x02 }, | ||
1064 | { STB0899_TSINHDELM , 0x00 }, | ||
1065 | { STB0899_TSINHDELL , 0x00 }, | ||
1066 | { STB0899_TSLLSTKM , 0x00 }, | ||
1067 | { STB0899_TSLLSTKL , 0x00 }, | ||
1068 | { STB0899_TSULSTKM , 0x00 }, | ||
1069 | { STB0899_TSULSTKL , 0xab }, | ||
1070 | { STB0899_PCKLENUL , 0x00 }, | ||
1071 | { STB0899_PCKLENLL , 0xcc }, | ||
1072 | { STB0899_RSPCKLEN , 0xcc }, | ||
1073 | { STB0899_TSSTATUS , 0x80 }, | ||
1074 | { STB0899_ERRCTRL1 , 0xb6 }, | ||
1075 | { STB0899_ERRCTRL2 , 0x96 }, | ||
1076 | { STB0899_ERRCTRL3 , 0x89 }, | ||
1077 | { STB0899_DMONMSK1 , 0x27 }, | ||
1078 | { STB0899_DMONMSK0 , 0x03 }, | ||
1079 | { STB0899_DEMAPVIT , 0x5c }, | ||
1080 | { STB0899_PLPARM , 0x1f }, | ||
1081 | { STB0899_PDELCTRL , 0x48 }, | ||
1082 | { STB0899_PDELCTRL2 , 0x00 }, | ||
1083 | { STB0899_BBHCTRL1 , 0x00 }, | ||
1084 | { STB0899_BBHCTRL2 , 0x00 }, | ||
1085 | { STB0899_HYSTTHRESH , 0x77 }, | ||
1086 | { STB0899_MATCSTM , 0x00 }, | ||
1087 | { STB0899_MATCSTL , 0x00 }, | ||
1088 | { STB0899_UPLCSTM , 0x00 }, | ||
1089 | { STB0899_UPLCSTL , 0x00 }, | ||
1090 | { STB0899_DFLCSTM , 0x00 }, | ||
1091 | { STB0899_DFLCSTL , 0x00 }, | ||
1092 | { STB0899_SYNCCST , 0x00 }, | ||
1093 | { STB0899_SYNCDCSTM , 0x00 }, | ||
1094 | { STB0899_SYNCDCSTL , 0x00 }, | ||
1095 | { STB0899_ISI_ENTRY , 0x00 }, | ||
1096 | { STB0899_ISI_BIT_EN , 0x00 }, | ||
1097 | { STB0899_MATSTRM , 0x00 }, | ||
1098 | { STB0899_MATSTRL , 0x00 }, | ||
1099 | { STB0899_UPLSTRM , 0x00 }, | ||
1100 | { STB0899_UPLSTRL , 0x00 }, | ||
1101 | { STB0899_DFLSTRM , 0x00 }, | ||
1102 | { STB0899_DFLSTRL , 0x00 }, | ||
1103 | { STB0899_SYNCSTR , 0x00 }, | ||
1104 | { STB0899_SYNCDSTRM , 0x00 }, | ||
1105 | { STB0899_SYNCDSTRL , 0x00 }, | ||
1106 | { STB0899_CFGPDELSTATUS1 , 0x10 }, | ||
1107 | { STB0899_CFGPDELSTATUS2 , 0x00 }, | ||
1108 | { STB0899_BBFERRORM , 0x00 }, | ||
1109 | { STB0899_BBFERRORL , 0x00 }, | ||
1110 | { STB0899_UPKTERRORM , 0x00 }, | ||
1111 | { STB0899_UPKTERRORL , 0x00 }, | ||
1112 | { 0xffff , 0xff }, | ||
1113 | }; | ||
1114 | |||
1115 | /* STB0899 demodulator config for the KNC1 and clones */ | ||
1116 | static struct stb0899_config knc1_dvbs2_config = { | ||
1117 | .init_dev = knc1_stb0899_s1_init_1, | ||
1118 | .init_s2_demod = stb0899_s2_init_2, | ||
1119 | .init_s1_demod = knc1_stb0899_s1_init_3, | ||
1120 | .init_s2_fec = stb0899_s2_init_4, | ||
1121 | .init_tst = stb0899_s1_init_5, | ||
1122 | |||
1123 | .postproc = NULL, | ||
1124 | |||
1125 | .demod_address = 0x68, | ||
1126 | // .ts_output_mode = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL */ | ||
1127 | .block_sync_mode = STB0899_SYNC_FORCED, /* DSS, SYNC_FORCED/UNSYNCED */ | ||
1128 | // .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */ | ||
1129 | |||
1130 | .xtal_freq = 27000000, | ||
1131 | .inversion = IQ_SWAP_OFF, /* 1 */ | ||
1132 | |||
1133 | .lo_clk = 76500000, | ||
1134 | .hi_clk = 90000000, | ||
1135 | |||
1136 | .esno_ave = STB0899_DVBS2_ESNO_AVE, | ||
1137 | .esno_quant = STB0899_DVBS2_ESNO_QUANT, | ||
1138 | .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, | ||
1139 | .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, | ||
1140 | .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, | ||
1141 | .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, | ||
1142 | .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, | ||
1143 | .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, | ||
1144 | .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | ||
1145 | |||
1146 | .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, | ||
1147 | .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | ||
1148 | .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, | ||
1149 | .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, | ||
1150 | |||
1151 | .tuner_get_frequency = tda8261_get_frequency, | ||
1152 | .tuner_set_frequency = tda8261_set_frequency, | ||
1153 | .tuner_set_bandwidth = NULL, | ||
1154 | .tuner_get_bandwidth = tda8261_get_bandwidth, | ||
1155 | .tuner_set_rfsiggain = NULL | ||
1156 | }; | ||
1157 | |||
1158 | /* | ||
1159 | * SD1878/SHA tuner config | ||
1160 | * 1F, Single I/P, Horizontal mount, High Sensitivity | ||
1161 | */ | ||
1162 | static const struct tda8261_config sd1878c_config = { | ||
1163 | // .name = "SD1878/SHA", | ||
1164 | .addr = 0x60, | ||
1165 | .step_size = TDA8261_STEP_1000 /* kHz */ | ||
1166 | }; | ||
1167 | |||
1168 | static u8 read_pwm(struct budget_av *budget_av) | ||
1169 | { | ||
1170 | u8 b = 0xff; | ||
1171 | u8 pwm; | ||
1172 | struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1}, | ||
1173 | {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} | ||
1174 | }; | ||
1175 | |||
1176 | if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2) | ||
1177 | || (pwm == 0xff)) | ||
1178 | pwm = 0x48; | ||
1179 | |||
1180 | return pwm; | ||
1181 | } | ||
1182 | |||
1183 | #define SUBID_DVBS_KNC1 0x0010 | ||
1184 | #define SUBID_DVBS_KNC1_PLUS 0x0011 | ||
1185 | #define SUBID_DVBS_TYPHOON 0x4f56 | ||
1186 | #define SUBID_DVBS_CINERGY1200 0x1154 | ||
1187 | #define SUBID_DVBS_CYNERGY1200N 0x1155 | ||
1188 | #define SUBID_DVBS_TV_STAR 0x0014 | ||
1189 | #define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015 | ||
1190 | #define SUBID_DVBS_TV_STAR_CI 0x0016 | ||
1191 | #define SUBID_DVBS2_KNC1 0x0018 | ||
1192 | #define SUBID_DVBS2_KNC1_OEM 0x0019 | ||
1193 | #define SUBID_DVBS_EASYWATCH_1 0x001a | ||
1194 | #define SUBID_DVBS_EASYWATCH_2 0x001b | ||
1195 | #define SUBID_DVBS2_EASYWATCH 0x001d | ||
1196 | #define SUBID_DVBS_EASYWATCH 0x001e | ||
1197 | |||
1198 | #define SUBID_DVBC_EASYWATCH 0x002a | ||
1199 | #define SUBID_DVBC_EASYWATCH_MK3 0x002c | ||
1200 | #define SUBID_DVBC_KNC1 0x0020 | ||
1201 | #define SUBID_DVBC_KNC1_PLUS 0x0021 | ||
1202 | #define SUBID_DVBC_KNC1_MK3 0x0022 | ||
1203 | #define SUBID_DVBC_KNC1_TDA10024 0x0028 | ||
1204 | #define SUBID_DVBC_KNC1_PLUS_MK3 0x0023 | ||
1205 | #define SUBID_DVBC_CINERGY1200 0x1156 | ||
1206 | #define SUBID_DVBC_CINERGY1200_MK3 0x1176 | ||
1207 | |||
1208 | #define SUBID_DVBT_EASYWATCH 0x003a | ||
1209 | #define SUBID_DVBT_KNC1_PLUS 0x0031 | ||
1210 | #define SUBID_DVBT_KNC1 0x0030 | ||
1211 | #define SUBID_DVBT_CINERGY1200 0x1157 | ||
1212 | |||
1213 | static void frontend_init(struct budget_av *budget_av) | ||
1214 | { | ||
1215 | struct saa7146_dev * saa = budget_av->budget.dev; | ||
1216 | struct dvb_frontend * fe = NULL; | ||
1217 | |||
1218 | /* Enable / PowerON Frontend */ | ||
1219 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
1220 | |||
1221 | /* Wait for PowerON */ | ||
1222 | msleep(100); | ||
1223 | |||
1224 | /* additional setup necessary for the PLUS cards */ | ||
1225 | switch (saa->pci->subsystem_device) { | ||
1226 | case SUBID_DVBS_KNC1_PLUS: | ||
1227 | case SUBID_DVBC_KNC1_PLUS: | ||
1228 | case SUBID_DVBT_KNC1_PLUS: | ||
1229 | case SUBID_DVBC_EASYWATCH: | ||
1230 | case SUBID_DVBC_KNC1_PLUS_MK3: | ||
1231 | case SUBID_DVBS2_KNC1: | ||
1232 | case SUBID_DVBS2_KNC1_OEM: | ||
1233 | case SUBID_DVBS2_EASYWATCH: | ||
1234 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); | ||
1235 | break; | ||
1236 | } | ||
1237 | |||
1238 | switch (saa->pci->subsystem_device) { | ||
1239 | |||
1240 | case SUBID_DVBS_KNC1: | ||
1241 | /* | ||
1242 | * maybe that setting is needed for other dvb-s cards as well, | ||
1243 | * but so far it has been only confirmed for this type | ||
1244 | */ | ||
1245 | budget_av->reinitialise_demod = 1; | ||
1246 | /* fall through */ | ||
1247 | case SUBID_DVBS_KNC1_PLUS: | ||
1248 | case SUBID_DVBS_EASYWATCH_1: | ||
1249 | if (saa->pci->subsystem_vendor == 0x1894) { | ||
1250 | fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config, | ||
1251 | &budget_av->budget.i2c_adap); | ||
1252 | if (fe) { | ||
1253 | dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap); | ||
1254 | } | ||
1255 | } else { | ||
1256 | fe = dvb_attach(stv0299_attach, &typhoon_config, | ||
1257 | &budget_av->budget.i2c_adap); | ||
1258 | if (fe) { | ||
1259 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1260 | } | ||
1261 | } | ||
1262 | break; | ||
1263 | |||
1264 | case SUBID_DVBS_TV_STAR: | ||
1265 | case SUBID_DVBS_TV_STAR_PLUS_X4: | ||
1266 | case SUBID_DVBS_TV_STAR_CI: | ||
1267 | case SUBID_DVBS_CYNERGY1200N: | ||
1268 | case SUBID_DVBS_EASYWATCH: | ||
1269 | case SUBID_DVBS_EASYWATCH_2: | ||
1270 | fe = dvb_attach(stv0299_attach, &philips_sd1878_config, | ||
1271 | &budget_av->budget.i2c_adap); | ||
1272 | if (fe) { | ||
1273 | dvb_attach(dvb_pll_attach, fe, 0x60, | ||
1274 | &budget_av->budget.i2c_adap, | ||
1275 | DVB_PLL_PHILIPS_SD1878_TDA8261); | ||
1276 | } | ||
1277 | break; | ||
1278 | |||
1279 | case SUBID_DVBS_TYPHOON: | ||
1280 | fe = dvb_attach(stv0299_attach, &typhoon_config, | ||
1281 | &budget_av->budget.i2c_adap); | ||
1282 | if (fe) { | ||
1283 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1284 | } | ||
1285 | break; | ||
1286 | case SUBID_DVBS2_KNC1: | ||
1287 | case SUBID_DVBS2_KNC1_OEM: | ||
1288 | case SUBID_DVBS2_EASYWATCH: | ||
1289 | budget_av->reinitialise_demod = 1; | ||
1290 | if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap))) | ||
1291 | dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap); | ||
1292 | |||
1293 | break; | ||
1294 | case SUBID_DVBS_CINERGY1200: | ||
1295 | fe = dvb_attach(stv0299_attach, &cinergy_1200s_config, | ||
1296 | &budget_av->budget.i2c_adap); | ||
1297 | if (fe) { | ||
1298 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1299 | } | ||
1300 | break; | ||
1301 | |||
1302 | case SUBID_DVBC_KNC1: | ||
1303 | case SUBID_DVBC_KNC1_PLUS: | ||
1304 | case SUBID_DVBC_CINERGY1200: | ||
1305 | case SUBID_DVBC_EASYWATCH: | ||
1306 | budget_av->reinitialise_demod = 1; | ||
1307 | budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | ||
1308 | fe = dvb_attach(tda10021_attach, &philips_cu1216_config, | ||
1309 | &budget_av->budget.i2c_adap, | ||
1310 | read_pwm(budget_av)); | ||
1311 | if (fe == NULL) | ||
1312 | fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress, | ||
1313 | &budget_av->budget.i2c_adap, | ||
1314 | read_pwm(budget_av)); | ||
1315 | if (fe) { | ||
1316 | fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | ||
1317 | } | ||
1318 | break; | ||
1319 | |||
1320 | case SUBID_DVBC_EASYWATCH_MK3: | ||
1321 | case SUBID_DVBC_CINERGY1200_MK3: | ||
1322 | case SUBID_DVBC_KNC1_MK3: | ||
1323 | case SUBID_DVBC_KNC1_TDA10024: | ||
1324 | case SUBID_DVBC_KNC1_PLUS_MK3: | ||
1325 | budget_av->reinitialise_demod = 1; | ||
1326 | budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | ||
1327 | fe = dvb_attach(tda10023_attach, | ||
1328 | &philips_cu1216_tda10023_config, | ||
1329 | &budget_av->budget.i2c_adap, | ||
1330 | read_pwm(budget_av)); | ||
1331 | if (fe) { | ||
1332 | fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | ||
1333 | } | ||
1334 | break; | ||
1335 | |||
1336 | case SUBID_DVBT_EASYWATCH: | ||
1337 | case SUBID_DVBT_KNC1: | ||
1338 | case SUBID_DVBT_KNC1_PLUS: | ||
1339 | case SUBID_DVBT_CINERGY1200: | ||
1340 | budget_av->reinitialise_demod = 1; | ||
1341 | fe = dvb_attach(tda10046_attach, &philips_tu1216_config, | ||
1342 | &budget_av->budget.i2c_adap); | ||
1343 | if (fe) { | ||
1344 | fe->ops.tuner_ops.init = philips_tu1216_tuner_init; | ||
1345 | fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params; | ||
1346 | } | ||
1347 | break; | ||
1348 | } | ||
1349 | |||
1350 | if (fe == NULL) { | ||
1351 | pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", | ||
1352 | saa->pci->vendor, | ||
1353 | saa->pci->device, | ||
1354 | saa->pci->subsystem_vendor, | ||
1355 | saa->pci->subsystem_device); | ||
1356 | return; | ||
1357 | } | ||
1358 | |||
1359 | budget_av->budget.dvb_frontend = fe; | ||
1360 | |||
1361 | if (dvb_register_frontend(&budget_av->budget.dvb_adapter, | ||
1362 | budget_av->budget.dvb_frontend)) { | ||
1363 | pr_err("Frontend registration failed!\n"); | ||
1364 | dvb_frontend_detach(budget_av->budget.dvb_frontend); | ||
1365 | budget_av->budget.dvb_frontend = NULL; | ||
1366 | } | ||
1367 | } | ||
1368 | |||
1369 | |||
1370 | static void budget_av_irq(struct saa7146_dev *dev, u32 * isr) | ||
1371 | { | ||
1372 | struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; | ||
1373 | |||
1374 | dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av); | ||
1375 | |||
1376 | if (*isr & MASK_10) | ||
1377 | ttpci_budget_irq10_handler(dev, isr); | ||
1378 | } | ||
1379 | |||
1380 | static int budget_av_detach(struct saa7146_dev *dev) | ||
1381 | { | ||
1382 | struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; | ||
1383 | int err; | ||
1384 | |||
1385 | dprintk(2, "dev: %p\n", dev); | ||
1386 | |||
1387 | if (1 == budget_av->has_saa7113) { | ||
1388 | saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); | ||
1389 | |||
1390 | msleep(200); | ||
1391 | |||
1392 | saa7146_unregister_device(&budget_av->vd, dev); | ||
1393 | |||
1394 | saa7146_vv_release(dev); | ||
1395 | } | ||
1396 | |||
1397 | if (budget_av->budget.ci_present) | ||
1398 | ciintf_deinit(budget_av); | ||
1399 | |||
1400 | if (budget_av->budget.dvb_frontend != NULL) { | ||
1401 | dvb_unregister_frontend(budget_av->budget.dvb_frontend); | ||
1402 | dvb_frontend_detach(budget_av->budget.dvb_frontend); | ||
1403 | } | ||
1404 | err = ttpci_budget_deinit(&budget_av->budget); | ||
1405 | |||
1406 | kfree(budget_av); | ||
1407 | |||
1408 | return err; | ||
1409 | } | ||
1410 | |||
1411 | #define KNC1_INPUTS 2 | ||
1412 | static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { | ||
1413 | { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, | ||
1414 | V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, | ||
1415 | { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, | ||
1416 | V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, | ||
1417 | }; | ||
1418 | |||
1419 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | ||
1420 | { | ||
1421 | dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index); | ||
1422 | if (i->index >= KNC1_INPUTS) | ||
1423 | return -EINVAL; | ||
1424 | memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); | ||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1428 | static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) | ||
1429 | { | ||
1430 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
1431 | struct budget_av *budget_av = (struct budget_av *)dev->ext_priv; | ||
1432 | |||
1433 | *i = budget_av->cur_input; | ||
1434 | |||
1435 | dprintk(1, "VIDIOC_G_INPUT %d\n", *i); | ||
1436 | return 0; | ||
1437 | } | ||
1438 | |||
1439 | static int vidioc_s_input(struct file *file, void *fh, unsigned int input) | ||
1440 | { | ||
1441 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
1442 | struct budget_av *budget_av = (struct budget_av *)dev->ext_priv; | ||
1443 | |||
1444 | dprintk(1, "VIDIOC_S_INPUT %d\n", input); | ||
1445 | return saa7113_setinput(budget_av, input); | ||
1446 | } | ||
1447 | |||
1448 | static struct saa7146_ext_vv vv_data; | ||
1449 | |||
1450 | static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) | ||
1451 | { | ||
1452 | struct budget_av *budget_av; | ||
1453 | u8 *mac; | ||
1454 | int err; | ||
1455 | |||
1456 | dprintk(2, "dev: %p\n", dev); | ||
1457 | |||
1458 | if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL))) | ||
1459 | return -ENOMEM; | ||
1460 | |||
1461 | budget_av->has_saa7113 = 0; | ||
1462 | budget_av->budget.ci_present = 0; | ||
1463 | |||
1464 | dev->ext_priv = budget_av; | ||
1465 | |||
1466 | err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE, | ||
1467 | adapter_nr); | ||
1468 | if (err) { | ||
1469 | kfree(budget_av); | ||
1470 | return err; | ||
1471 | } | ||
1472 | |||
1473 | /* knc1 initialization */ | ||
1474 | saa7146_write(dev, DD1_STREAM_B, 0x04000000); | ||
1475 | saa7146_write(dev, DD1_INIT, 0x07000600); | ||
1476 | saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); | ||
1477 | |||
1478 | if (saa7113_init(budget_av) == 0) { | ||
1479 | budget_av->has_saa7113 = 1; | ||
1480 | |||
1481 | if (0 != saa7146_vv_init(dev, &vv_data)) { | ||
1482 | /* fixme: proper cleanup here */ | ||
1483 | ERR("cannot init vv subsystem\n"); | ||
1484 | return err; | ||
1485 | } | ||
1486 | vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; | ||
1487 | vv_data.vid_ops.vidioc_g_input = vidioc_g_input; | ||
1488 | vv_data.vid_ops.vidioc_s_input = vidioc_s_input; | ||
1489 | |||
1490 | if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { | ||
1491 | /* fixme: proper cleanup here */ | ||
1492 | ERR("cannot register capture v4l2 device\n"); | ||
1493 | saa7146_vv_release(dev); | ||
1494 | return err; | ||
1495 | } | ||
1496 | |||
1497 | /* beware: this modifies dev->vv ... */ | ||
1498 | saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A, | ||
1499 | SAA7146_HPS_SYNC_PORT_A); | ||
1500 | |||
1501 | saa7113_setinput(budget_av, 0); | ||
1502 | } | ||
1503 | |||
1504 | /* fixme: find some sane values here... */ | ||
1505 | saa7146_write(dev, PCI_BT_V1, 0x1c00101f); | ||
1506 | |||
1507 | mac = budget_av->budget.dvb_adapter.proposed_mac; | ||
1508 | if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { | ||
1509 | pr_err("KNC1-%d: Could not read MAC from KNC1 card\n", | ||
1510 | budget_av->budget.dvb_adapter.num); | ||
1511 | memset(mac, 0, 6); | ||
1512 | } else { | ||
1513 | pr_info("KNC1-%d: MAC addr = %pM\n", | ||
1514 | budget_av->budget.dvb_adapter.num, mac); | ||
1515 | } | ||
1516 | |||
1517 | budget_av->budget.dvb_adapter.priv = budget_av; | ||
1518 | frontend_init(budget_av); | ||
1519 | ciintf_init(budget_av); | ||
1520 | |||
1521 | ttpci_budget_init_hooks(&budget_av->budget); | ||
1522 | |||
1523 | return 0; | ||
1524 | } | ||
1525 | |||
1526 | static struct saa7146_standard standard[] = { | ||
1527 | {.name = "PAL",.id = V4L2_STD_PAL, | ||
1528 | .v_offset = 0x17,.v_field = 288, | ||
1529 | .h_offset = 0x14,.h_pixels = 680, | ||
1530 | .v_max_out = 576,.h_max_out = 768 }, | ||
1531 | |||
1532 | {.name = "NTSC",.id = V4L2_STD_NTSC, | ||
1533 | .v_offset = 0x16,.v_field = 240, | ||
1534 | .h_offset = 0x06,.h_pixels = 708, | ||
1535 | .v_max_out = 480,.h_max_out = 640, }, | ||
1536 | }; | ||
1537 | |||
1538 | static struct saa7146_ext_vv vv_data = { | ||
1539 | .inputs = 2, | ||
1540 | .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113 | ||
1541 | .flags = 0, | ||
1542 | .stds = &standard[0], | ||
1543 | .num_stds = ARRAY_SIZE(standard), | ||
1544 | }; | ||
1545 | |||
1546 | static struct saa7146_extension budget_extension; | ||
1547 | |||
1548 | MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); | ||
1549 | MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2); | ||
1550 | MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2); | ||
1551 | MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); | ||
1552 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); | ||
1553 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); | ||
1554 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); | ||
1555 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); | ||
1556 | MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); | ||
1557 | MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); | ||
1558 | MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); | ||
1559 | MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T); | ||
1560 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | ||
1561 | MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); | ||
1562 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); | ||
1563 | MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3); | ||
1564 | MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024); | ||
1565 | MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3); | ||
1566 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); | ||
1567 | MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); | ||
1568 | MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); | ||
1569 | MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); | ||
1570 | MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3); | ||
1571 | MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); | ||
1572 | |||
1573 | static struct pci_device_id pci_tbl[] = { | ||
1574 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), | ||
1575 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), | ||
1576 | MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), | ||
1577 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), | ||
1578 | MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011), | ||
1579 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), | ||
1580 | MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015), | ||
1581 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), | ||
1582 | MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018), | ||
1583 | MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019), | ||
1584 | MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d), | ||
1585 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), | ||
1586 | MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), | ||
1587 | MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), | ||
1588 | MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), | ||
1589 | MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), | ||
1590 | MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a), | ||
1591 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | ||
1592 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | ||
1593 | MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), | ||
1594 | MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028), | ||
1595 | MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023), | ||
1596 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), | ||
1597 | MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), | ||
1598 | MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), | ||
1599 | MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155), | ||
1600 | MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), | ||
1601 | MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176), | ||
1602 | MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), | ||
1603 | { | ||
1604 | .vendor = 0, | ||
1605 | } | ||
1606 | }; | ||
1607 | |||
1608 | MODULE_DEVICE_TABLE(pci, pci_tbl); | ||
1609 | |||
1610 | static struct saa7146_extension budget_extension = { | ||
1611 | .name = "budget_av", | ||
1612 | .flags = SAA7146_USE_I2C_IRQ, | ||
1613 | |||
1614 | .pci_tbl = pci_tbl, | ||
1615 | |||
1616 | .module = THIS_MODULE, | ||
1617 | .attach = budget_av_attach, | ||
1618 | .detach = budget_av_detach, | ||
1619 | |||
1620 | .irq_mask = MASK_10, | ||
1621 | .irq_func = budget_av_irq, | ||
1622 | }; | ||
1623 | |||
1624 | static int __init budget_av_init(void) | ||
1625 | { | ||
1626 | return saa7146_register_extension(&budget_extension); | ||
1627 | } | ||
1628 | |||
1629 | static void __exit budget_av_exit(void) | ||
1630 | { | ||
1631 | saa7146_unregister_extension(&budget_extension); | ||
1632 | } | ||
1633 | |||
1634 | module_init(budget_av_init); | ||
1635 | module_exit(budget_av_exit); | ||
1636 | |||
1637 | MODULE_LICENSE("GPL"); | ||
1638 | MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); | ||
1639 | MODULE_DESCRIPTION("driver for the SAA7146 based so-called " | ||
1640 | "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); | ||
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c deleted file mode 100644 index 98e524178765..000000000000 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ /dev/null | |||
@@ -1,1591 +0,0 @@ | |||
1 | /* | ||
2 | * budget-ci.c: driver for the SAA7146 based Budget DVB cards | ||
3 | * | ||
4 | * Compiled from various sources by Michael Hunold <michael@mihu.de> | ||
5 | * | ||
6 | * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM> | ||
7 | * partially based on the Siemens DVB driver by Ralph+Marcus Metzler | ||
8 | * | ||
9 | * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
26 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
27 | * | ||
28 | * | ||
29 | * the project's page is at http://www.linuxtv.org/ | ||
30 | */ | ||
31 | |||
32 | #include <linux/module.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/spinlock.h> | ||
37 | #include <media/rc-core.h> | ||
38 | |||
39 | #include "budget.h" | ||
40 | |||
41 | #include "dvb_ca_en50221.h" | ||
42 | #include "stv0299.h" | ||
43 | #include "stv0297.h" | ||
44 | #include "tda1004x.h" | ||
45 | #include "stb0899_drv.h" | ||
46 | #include "stb0899_reg.h" | ||
47 | #include "stb0899_cfg.h" | ||
48 | #include "stb6100.h" | ||
49 | #include "stb6100_cfg.h" | ||
50 | #include "lnbp21.h" | ||
51 | #include "bsbe1.h" | ||
52 | #include "bsru6.h" | ||
53 | #include "tda1002x.h" | ||
54 | #include "tda827x.h" | ||
55 | #include "bsbe1-d01a.h" | ||
56 | |||
57 | #define MODULE_NAME "budget_ci" | ||
58 | |||
59 | /* | ||
60 | * Regarding DEBIADDR_IR: | ||
61 | * Some CI modules hang if random addresses are read. | ||
62 | * Using address 0x4000 for the IR read means that we | ||
63 | * use the same address as for CI version, which should | ||
64 | * be a safe default. | ||
65 | */ | ||
66 | #define DEBIADDR_IR 0x4000 | ||
67 | #define DEBIADDR_CICONTROL 0x0000 | ||
68 | #define DEBIADDR_CIVERSION 0x4000 | ||
69 | #define DEBIADDR_IO 0x1000 | ||
70 | #define DEBIADDR_ATTR 0x3000 | ||
71 | |||
72 | #define CICONTROL_RESET 0x01 | ||
73 | #define CICONTROL_ENABLETS 0x02 | ||
74 | #define CICONTROL_CAMDETECT 0x08 | ||
75 | |||
76 | #define DEBICICTL 0x00420000 | ||
77 | #define DEBICICAM 0x02420000 | ||
78 | |||
79 | #define SLOTSTATUS_NONE 1 | ||
80 | #define SLOTSTATUS_PRESENT 2 | ||
81 | #define SLOTSTATUS_RESET 4 | ||
82 | #define SLOTSTATUS_READY 8 | ||
83 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | ||
84 | |||
85 | /* RC5 device wildcard */ | ||
86 | #define IR_DEVICE_ANY 255 | ||
87 | |||
88 | static int rc5_device = -1; | ||
89 | module_param(rc5_device, int, 0644); | ||
90 | MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); | ||
91 | |||
92 | static int ir_debug; | ||
93 | module_param(ir_debug, int, 0644); | ||
94 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); | ||
95 | |||
96 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
97 | |||
98 | struct budget_ci_ir { | ||
99 | struct rc_dev *dev; | ||
100 | struct tasklet_struct msp430_irq_tasklet; | ||
101 | char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ | ||
102 | char phys[32]; | ||
103 | int rc5_device; | ||
104 | u32 ir_key; | ||
105 | bool have_command; | ||
106 | bool full_rc5; /* Outputs a full RC5 code */ | ||
107 | }; | ||
108 | |||
109 | struct budget_ci { | ||
110 | struct budget budget; | ||
111 | struct tasklet_struct ciintf_irq_tasklet; | ||
112 | int slot_status; | ||
113 | int ci_irq; | ||
114 | struct dvb_ca_en50221 ca; | ||
115 | struct budget_ci_ir ir; | ||
116 | u8 tuner_pll_address; /* used for philips_tdm1316l configs */ | ||
117 | }; | ||
118 | |||
119 | static void msp430_ir_interrupt(unsigned long data) | ||
120 | { | ||
121 | struct budget_ci *budget_ci = (struct budget_ci *) data; | ||
122 | struct rc_dev *dev = budget_ci->ir.dev; | ||
123 | u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; | ||
124 | |||
125 | /* | ||
126 | * The msp430 chip can generate two different bytes, command and device | ||
127 | * | ||
128 | * type1: X1CCCCCC, C = command bits (0 - 63) | ||
129 | * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit | ||
130 | * | ||
131 | * Each signal from the remote control can generate one or more command | ||
132 | * bytes and one or more device bytes. For the repeated bytes, the | ||
133 | * highest bit (X) is set. The first command byte is always generated | ||
134 | * before the first device byte. Other than that, no specific order | ||
135 | * seems to apply. To make life interesting, bytes can also be lost. | ||
136 | * | ||
137 | * Only when we have a command and device byte, a keypress is | ||
138 | * generated. | ||
139 | */ | ||
140 | |||
141 | if (ir_debug) | ||
142 | printk("budget_ci: received byte 0x%02x\n", command); | ||
143 | |||
144 | /* Remove repeat bit, we use every command */ | ||
145 | command = command & 0x7f; | ||
146 | |||
147 | /* Is this a RC5 command byte? */ | ||
148 | if (command & 0x40) { | ||
149 | budget_ci->ir.have_command = true; | ||
150 | budget_ci->ir.ir_key = command & 0x3f; | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | /* It's a RC5 device byte */ | ||
155 | if (!budget_ci->ir.have_command) | ||
156 | return; | ||
157 | budget_ci->ir.have_command = false; | ||
158 | |||
159 | if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && | ||
160 | budget_ci->ir.rc5_device != (command & 0x1f)) | ||
161 | return; | ||
162 | |||
163 | if (budget_ci->ir.full_rc5) { | ||
164 | rc_keydown(dev, | ||
165 | budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key, | ||
166 | (command & 0x20) ? 1 : 0); | ||
167 | return; | ||
168 | } | ||
169 | |||
170 | /* FIXME: We should generate complete scancodes for all devices */ | ||
171 | rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0); | ||
172 | } | ||
173 | |||
174 | static int msp430_ir_init(struct budget_ci *budget_ci) | ||
175 | { | ||
176 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
177 | struct rc_dev *dev; | ||
178 | int error; | ||
179 | |||
180 | dev = rc_allocate_device(); | ||
181 | if (!dev) { | ||
182 | printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); | ||
183 | return -ENOMEM; | ||
184 | } | ||
185 | |||
186 | snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), | ||
187 | "Budget-CI dvb ir receiver %s", saa->name); | ||
188 | snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys), | ||
189 | "pci-%s/ir0", pci_name(saa->pci)); | ||
190 | |||
191 | dev->driver_name = MODULE_NAME; | ||
192 | dev->input_name = budget_ci->ir.name; | ||
193 | dev->input_phys = budget_ci->ir.phys; | ||
194 | dev->input_id.bustype = BUS_PCI; | ||
195 | dev->input_id.version = 1; | ||
196 | if (saa->pci->subsystem_vendor) { | ||
197 | dev->input_id.vendor = saa->pci->subsystem_vendor; | ||
198 | dev->input_id.product = saa->pci->subsystem_device; | ||
199 | } else { | ||
200 | dev->input_id.vendor = saa->pci->vendor; | ||
201 | dev->input_id.product = saa->pci->device; | ||
202 | } | ||
203 | dev->dev.parent = &saa->pci->dev; | ||
204 | |||
205 | if (rc5_device < 0) | ||
206 | budget_ci->ir.rc5_device = IR_DEVICE_ANY; | ||
207 | else | ||
208 | budget_ci->ir.rc5_device = rc5_device; | ||
209 | |||
210 | /* Select keymap and address */ | ||
211 | switch (budget_ci->budget.dev->pci->subsystem_device) { | ||
212 | case 0x100c: | ||
213 | case 0x100f: | ||
214 | case 0x1011: | ||
215 | case 0x1012: | ||
216 | /* The hauppauge keymap is a superset of these remotes */ | ||
217 | dev->map_name = RC_MAP_HAUPPAUGE; | ||
218 | budget_ci->ir.full_rc5 = true; | ||
219 | |||
220 | if (rc5_device < 0) | ||
221 | budget_ci->ir.rc5_device = 0x1f; | ||
222 | break; | ||
223 | case 0x1010: | ||
224 | case 0x1017: | ||
225 | case 0x1019: | ||
226 | case 0x101a: | ||
227 | case 0x101b: | ||
228 | /* for the Technotrend 1500 bundled remote */ | ||
229 | dev->map_name = RC_MAP_TT_1500; | ||
230 | break; | ||
231 | default: | ||
232 | /* unknown remote */ | ||
233 | dev->map_name = RC_MAP_BUDGET_CI_OLD; | ||
234 | break; | ||
235 | } | ||
236 | if (!budget_ci->ir.full_rc5) | ||
237 | dev->scanmask = 0xff; | ||
238 | |||
239 | error = rc_register_device(dev); | ||
240 | if (error) { | ||
241 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); | ||
242 | rc_free_device(dev); | ||
243 | return error; | ||
244 | } | ||
245 | |||
246 | budget_ci->ir.dev = dev; | ||
247 | |||
248 | tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, | ||
249 | (unsigned long) budget_ci); | ||
250 | |||
251 | SAA7146_IER_ENABLE(saa, MASK_06); | ||
252 | saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static void msp430_ir_deinit(struct budget_ci *budget_ci) | ||
258 | { | ||
259 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
260 | |||
261 | SAA7146_IER_DISABLE(saa, MASK_06); | ||
262 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | ||
263 | tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); | ||
264 | |||
265 | rc_unregister_device(budget_ci->ir.dev); | ||
266 | } | ||
267 | |||
268 | static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) | ||
269 | { | ||
270 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
271 | |||
272 | if (slot != 0) | ||
273 | return -EINVAL; | ||
274 | |||
275 | return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM, | ||
276 | DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0); | ||
277 | } | ||
278 | |||
279 | static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) | ||
280 | { | ||
281 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
282 | |||
283 | if (slot != 0) | ||
284 | return -EINVAL; | ||
285 | |||
286 | return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM, | ||
287 | DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0); | ||
288 | } | ||
289 | |||
290 | static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) | ||
291 | { | ||
292 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
293 | |||
294 | if (slot != 0) | ||
295 | return -EINVAL; | ||
296 | |||
297 | return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM, | ||
298 | DEBIADDR_IO | (address & 3), 1, 1, 0); | ||
299 | } | ||
300 | |||
301 | static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) | ||
302 | { | ||
303 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
304 | |||
305 | if (slot != 0) | ||
306 | return -EINVAL; | ||
307 | |||
308 | return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM, | ||
309 | DEBIADDR_IO | (address & 3), 1, value, 1, 0); | ||
310 | } | ||
311 | |||
312 | static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | ||
313 | { | ||
314 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
315 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
316 | |||
317 | if (slot != 0) | ||
318 | return -EINVAL; | ||
319 | |||
320 | if (budget_ci->ci_irq) { | ||
321 | // trigger on RISING edge during reset so we know when READY is re-asserted | ||
322 | saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); | ||
323 | } | ||
324 | budget_ci->slot_status = SLOTSTATUS_RESET; | ||
325 | ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); | ||
326 | msleep(1); | ||
327 | ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, | ||
328 | CICONTROL_RESET, 1, 0); | ||
329 | |||
330 | saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); | ||
331 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | ||
336 | { | ||
337 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
338 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
339 | |||
340 | if (slot != 0) | ||
341 | return -EINVAL; | ||
342 | |||
343 | saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); | ||
344 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | ||
349 | { | ||
350 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
351 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
352 | int tmp; | ||
353 | |||
354 | if (slot != 0) | ||
355 | return -EINVAL; | ||
356 | |||
357 | saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); | ||
358 | |||
359 | tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); | ||
360 | ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, | ||
361 | tmp | CICONTROL_ENABLETS, 1, 0); | ||
362 | |||
363 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static void ciintf_interrupt(unsigned long data) | ||
368 | { | ||
369 | struct budget_ci *budget_ci = (struct budget_ci *) data; | ||
370 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
371 | unsigned int flags; | ||
372 | |||
373 | // ensure we don't get spurious IRQs during initialisation | ||
374 | if (!budget_ci->budget.ci_present) | ||
375 | return; | ||
376 | |||
377 | // read the CAM status | ||
378 | flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); | ||
379 | if (flags & CICONTROL_CAMDETECT) { | ||
380 | |||
381 | // GPIO should be set to trigger on falling edge if a CAM is present | ||
382 | saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); | ||
383 | |||
384 | if (budget_ci->slot_status & SLOTSTATUS_NONE) { | ||
385 | // CAM insertion IRQ | ||
386 | budget_ci->slot_status = SLOTSTATUS_PRESENT; | ||
387 | dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, | ||
388 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
389 | |||
390 | } else if (budget_ci->slot_status & SLOTSTATUS_RESET) { | ||
391 | // CAM ready (reset completed) | ||
392 | budget_ci->slot_status = SLOTSTATUS_READY; | ||
393 | dvb_ca_en50221_camready_irq(&budget_ci->ca, 0); | ||
394 | |||
395 | } else if (budget_ci->slot_status & SLOTSTATUS_READY) { | ||
396 | // FR/DA IRQ | ||
397 | dvb_ca_en50221_frda_irq(&budget_ci->ca, 0); | ||
398 | } | ||
399 | } else { | ||
400 | |||
401 | // trigger on rising edge if a CAM is not present - when a CAM is inserted, we | ||
402 | // only want to get the IRQ when it sets READY. If we trigger on the falling edge, | ||
403 | // the CAM might not actually be ready yet. | ||
404 | saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); | ||
405 | |||
406 | // generate a CAM removal IRQ if we haven't already | ||
407 | if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) { | ||
408 | // CAM removal IRQ | ||
409 | budget_ci->slot_status = SLOTSTATUS_NONE; | ||
410 | dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, | ||
411 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | |||
416 | static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) | ||
417 | { | ||
418 | struct budget_ci *budget_ci = (struct budget_ci *) ca->data; | ||
419 | unsigned int flags; | ||
420 | |||
421 | // ensure we don't get spurious IRQs during initialisation | ||
422 | if (!budget_ci->budget.ci_present) | ||
423 | return -EINVAL; | ||
424 | |||
425 | // read the CAM status | ||
426 | flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); | ||
427 | if (flags & CICONTROL_CAMDETECT) { | ||
428 | // mark it as present if it wasn't before | ||
429 | if (budget_ci->slot_status & SLOTSTATUS_NONE) { | ||
430 | budget_ci->slot_status = SLOTSTATUS_PRESENT; | ||
431 | } | ||
432 | |||
433 | // during a RESET, we check if we can read from IO memory to see when CAM is ready | ||
434 | if (budget_ci->slot_status & SLOTSTATUS_RESET) { | ||
435 | if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) { | ||
436 | budget_ci->slot_status = SLOTSTATUS_READY; | ||
437 | } | ||
438 | } | ||
439 | } else { | ||
440 | budget_ci->slot_status = SLOTSTATUS_NONE; | ||
441 | } | ||
442 | |||
443 | if (budget_ci->slot_status != SLOTSTATUS_NONE) { | ||
444 | if (budget_ci->slot_status & SLOTSTATUS_READY) { | ||
445 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
446 | } | ||
447 | return DVB_CA_EN50221_POLL_CAM_PRESENT; | ||
448 | } | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | static int ciintf_init(struct budget_ci *budget_ci) | ||
454 | { | ||
455 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
456 | int flags; | ||
457 | int result; | ||
458 | int ci_version; | ||
459 | int ca_flags; | ||
460 | |||
461 | memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221)); | ||
462 | |||
463 | // enable DEBI pins | ||
464 | saa7146_write(saa, MC1, MASK_27 | MASK_11); | ||
465 | |||
466 | // test if it is there | ||
467 | ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0); | ||
468 | if ((ci_version & 0xa0) != 0xa0) { | ||
469 | result = -ENODEV; | ||
470 | goto error; | ||
471 | } | ||
472 | |||
473 | // determine whether a CAM is present or not | ||
474 | flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); | ||
475 | budget_ci->slot_status = SLOTSTATUS_NONE; | ||
476 | if (flags & CICONTROL_CAMDETECT) | ||
477 | budget_ci->slot_status = SLOTSTATUS_PRESENT; | ||
478 | |||
479 | // version 0xa2 of the CI firmware doesn't generate interrupts | ||
480 | if (ci_version == 0xa2) { | ||
481 | ca_flags = 0; | ||
482 | budget_ci->ci_irq = 0; | ||
483 | } else { | ||
484 | ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | | ||
485 | DVB_CA_EN50221_FLAG_IRQ_FR | | ||
486 | DVB_CA_EN50221_FLAG_IRQ_DA; | ||
487 | budget_ci->ci_irq = 1; | ||
488 | } | ||
489 | |||
490 | // register CI interface | ||
491 | budget_ci->ca.owner = THIS_MODULE; | ||
492 | budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem; | ||
493 | budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem; | ||
494 | budget_ci->ca.read_cam_control = ciintf_read_cam_control; | ||
495 | budget_ci->ca.write_cam_control = ciintf_write_cam_control; | ||
496 | budget_ci->ca.slot_reset = ciintf_slot_reset; | ||
497 | budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; | ||
498 | budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; | ||
499 | budget_ci->ca.poll_slot_status = ciintf_poll_slot_status; | ||
500 | budget_ci->ca.data = budget_ci; | ||
501 | if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, | ||
502 | &budget_ci->ca, | ||
503 | ca_flags, 1)) != 0) { | ||
504 | printk("budget_ci: CI interface detected, but initialisation failed.\n"); | ||
505 | goto error; | ||
506 | } | ||
507 | |||
508 | // Setup CI slot IRQ | ||
509 | if (budget_ci->ci_irq) { | ||
510 | tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); | ||
511 | if (budget_ci->slot_status != SLOTSTATUS_NONE) { | ||
512 | saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); | ||
513 | } else { | ||
514 | saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); | ||
515 | } | ||
516 | SAA7146_IER_ENABLE(saa, MASK_03); | ||
517 | } | ||
518 | |||
519 | // enable interface | ||
520 | ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, | ||
521 | CICONTROL_RESET, 1, 0); | ||
522 | |||
523 | // success! | ||
524 | printk("budget_ci: CI interface initialised\n"); | ||
525 | budget_ci->budget.ci_present = 1; | ||
526 | |||
527 | // forge a fake CI IRQ so the CAM state is setup correctly | ||
528 | if (budget_ci->ci_irq) { | ||
529 | flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; | ||
530 | if (budget_ci->slot_status != SLOTSTATUS_NONE) | ||
531 | flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; | ||
532 | dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); | ||
533 | } | ||
534 | |||
535 | return 0; | ||
536 | |||
537 | error: | ||
538 | saa7146_write(saa, MC1, MASK_27); | ||
539 | return result; | ||
540 | } | ||
541 | |||
542 | static void ciintf_deinit(struct budget_ci *budget_ci) | ||
543 | { | ||
544 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
545 | |||
546 | // disable CI interrupts | ||
547 | if (budget_ci->ci_irq) { | ||
548 | SAA7146_IER_DISABLE(saa, MASK_03); | ||
549 | saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); | ||
550 | tasklet_kill(&budget_ci->ciintf_irq_tasklet); | ||
551 | } | ||
552 | |||
553 | // reset interface | ||
554 | ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); | ||
555 | msleep(1); | ||
556 | ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, | ||
557 | CICONTROL_RESET, 1, 0); | ||
558 | |||
559 | // disable TS data stream to CI interface | ||
560 | saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); | ||
561 | |||
562 | // release the CA device | ||
563 | dvb_ca_en50221_release(&budget_ci->ca); | ||
564 | |||
565 | // disable DEBI pins | ||
566 | saa7146_write(saa, MC1, MASK_27); | ||
567 | } | ||
568 | |||
569 | static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) | ||
570 | { | ||
571 | struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv; | ||
572 | |||
573 | dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci); | ||
574 | |||
575 | if (*isr & MASK_06) | ||
576 | tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet); | ||
577 | |||
578 | if (*isr & MASK_10) | ||
579 | ttpci_budget_irq10_handler(dev, isr); | ||
580 | |||
581 | if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) | ||
582 | tasklet_schedule(&budget_ci->ciintf_irq_tasklet); | ||
583 | } | ||
584 | |||
585 | static u8 philips_su1278_tt_inittab[] = { | ||
586 | 0x01, 0x0f, | ||
587 | 0x02, 0x30, | ||
588 | 0x03, 0x00, | ||
589 | 0x04, 0x5b, | ||
590 | 0x05, 0x85, | ||
591 | 0x06, 0x02, | ||
592 | 0x07, 0x00, | ||
593 | 0x08, 0x02, | ||
594 | 0x09, 0x00, | ||
595 | 0x0C, 0x01, | ||
596 | 0x0D, 0x81, | ||
597 | 0x0E, 0x44, | ||
598 | 0x0f, 0x14, | ||
599 | 0x10, 0x3c, | ||
600 | 0x11, 0x84, | ||
601 | 0x12, 0xda, | ||
602 | 0x13, 0x97, | ||
603 | 0x14, 0x95, | ||
604 | 0x15, 0xc9, | ||
605 | 0x16, 0x19, | ||
606 | 0x17, 0x8c, | ||
607 | 0x18, 0x59, | ||
608 | 0x19, 0xf8, | ||
609 | 0x1a, 0xfe, | ||
610 | 0x1c, 0x7f, | ||
611 | 0x1d, 0x00, | ||
612 | 0x1e, 0x00, | ||
613 | 0x1f, 0x50, | ||
614 | 0x20, 0x00, | ||
615 | 0x21, 0x00, | ||
616 | 0x22, 0x00, | ||
617 | 0x23, 0x00, | ||
618 | 0x28, 0x00, | ||
619 | 0x29, 0x28, | ||
620 | 0x2a, 0x14, | ||
621 | 0x2b, 0x0f, | ||
622 | 0x2c, 0x09, | ||
623 | 0x2d, 0x09, | ||
624 | 0x31, 0x1f, | ||
625 | 0x32, 0x19, | ||
626 | 0x33, 0xfc, | ||
627 | 0x34, 0x93, | ||
628 | 0xff, 0xff | ||
629 | }; | ||
630 | |||
631 | static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) | ||
632 | { | ||
633 | stv0299_writereg(fe, 0x0e, 0x44); | ||
634 | if (srate >= 10000000) { | ||
635 | stv0299_writereg(fe, 0x13, 0x97); | ||
636 | stv0299_writereg(fe, 0x14, 0x95); | ||
637 | stv0299_writereg(fe, 0x15, 0xc9); | ||
638 | stv0299_writereg(fe, 0x17, 0x8c); | ||
639 | stv0299_writereg(fe, 0x1a, 0xfe); | ||
640 | stv0299_writereg(fe, 0x1c, 0x7f); | ||
641 | stv0299_writereg(fe, 0x2d, 0x09); | ||
642 | } else { | ||
643 | stv0299_writereg(fe, 0x13, 0x99); | ||
644 | stv0299_writereg(fe, 0x14, 0x8d); | ||
645 | stv0299_writereg(fe, 0x15, 0xce); | ||
646 | stv0299_writereg(fe, 0x17, 0x43); | ||
647 | stv0299_writereg(fe, 0x1a, 0x1d); | ||
648 | stv0299_writereg(fe, 0x1c, 0x12); | ||
649 | stv0299_writereg(fe, 0x2d, 0x05); | ||
650 | } | ||
651 | stv0299_writereg(fe, 0x0e, 0x23); | ||
652 | stv0299_writereg(fe, 0x0f, 0x94); | ||
653 | stv0299_writereg(fe, 0x10, 0x39); | ||
654 | stv0299_writereg(fe, 0x15, 0xc9); | ||
655 | |||
656 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
657 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
658 | stv0299_writereg(fe, 0x21, (ratio) & 0xf0); | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe) | ||
664 | { | ||
665 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
666 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | ||
667 | u32 div; | ||
668 | u8 buf[4]; | ||
669 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; | ||
670 | |||
671 | if ((p->frequency < 950000) || (p->frequency > 2150000)) | ||
672 | return -EINVAL; | ||
673 | |||
674 | div = (p->frequency + (500 - 1)) / 500; /* round correctly */ | ||
675 | buf[0] = (div >> 8) & 0x7f; | ||
676 | buf[1] = div & 0xff; | ||
677 | buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2; | ||
678 | buf[3] = 0x20; | ||
679 | |||
680 | if (p->symbol_rate < 4000000) | ||
681 | buf[3] |= 1; | ||
682 | |||
683 | if (p->frequency < 1250000) | ||
684 | buf[3] |= 0; | ||
685 | else if (p->frequency < 1550000) | ||
686 | buf[3] |= 0x40; | ||
687 | else if (p->frequency < 2050000) | ||
688 | buf[3] |= 0x80; | ||
689 | else if (p->frequency < 2150000) | ||
690 | buf[3] |= 0xC0; | ||
691 | |||
692 | if (fe->ops.i2c_gate_ctrl) | ||
693 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
694 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) | ||
695 | return -EIO; | ||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static struct stv0299_config philips_su1278_tt_config = { | ||
700 | |||
701 | .demod_address = 0x68, | ||
702 | .inittab = philips_su1278_tt_inittab, | ||
703 | .mclk = 64000000UL, | ||
704 | .invert = 0, | ||
705 | .skip_reinit = 1, | ||
706 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
707 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
708 | .min_delay_ms = 50, | ||
709 | .set_symbol_rate = philips_su1278_tt_set_symbol_rate, | ||
710 | }; | ||
711 | |||
712 | |||
713 | |||
714 | static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) | ||
715 | { | ||
716 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | ||
717 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | ||
718 | static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; | ||
719 | struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len = | ||
720 | sizeof(td1316_init) }; | ||
721 | |||
722 | // setup PLL configuration | ||
723 | if (fe->ops.i2c_gate_ctrl) | ||
724 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
725 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | ||
726 | return -EIO; | ||
727 | msleep(1); | ||
728 | |||
729 | // disable the mc44BC374c (do not check for errors) | ||
730 | tuner_msg.addr = 0x65; | ||
731 | tuner_msg.buf = disable_mc44BC374c; | ||
732 | tuner_msg.len = sizeof(disable_mc44BC374c); | ||
733 | if (fe->ops.i2c_gate_ctrl) | ||
734 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
735 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { | ||
736 | if (fe->ops.i2c_gate_ctrl) | ||
737 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
738 | i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); | ||
739 | } | ||
740 | |||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) | ||
745 | { | ||
746 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
747 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | ||
748 | u8 tuner_buf[4]; | ||
749 | struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) }; | ||
750 | int tuner_frequency = 0; | ||
751 | u8 band, cp, filter; | ||
752 | |||
753 | // determine charge pump | ||
754 | tuner_frequency = p->frequency + 36130000; | ||
755 | if (tuner_frequency < 87000000) | ||
756 | return -EINVAL; | ||
757 | else if (tuner_frequency < 130000000) | ||
758 | cp = 3; | ||
759 | else if (tuner_frequency < 160000000) | ||
760 | cp = 5; | ||
761 | else if (tuner_frequency < 200000000) | ||
762 | cp = 6; | ||
763 | else if (tuner_frequency < 290000000) | ||
764 | cp = 3; | ||
765 | else if (tuner_frequency < 420000000) | ||
766 | cp = 5; | ||
767 | else if (tuner_frequency < 480000000) | ||
768 | cp = 6; | ||
769 | else if (tuner_frequency < 620000000) | ||
770 | cp = 3; | ||
771 | else if (tuner_frequency < 830000000) | ||
772 | cp = 5; | ||
773 | else if (tuner_frequency < 895000000) | ||
774 | cp = 7; | ||
775 | else | ||
776 | return -EINVAL; | ||
777 | |||
778 | // determine band | ||
779 | if (p->frequency < 49000000) | ||
780 | return -EINVAL; | ||
781 | else if (p->frequency < 159000000) | ||
782 | band = 1; | ||
783 | else if (p->frequency < 444000000) | ||
784 | band = 2; | ||
785 | else if (p->frequency < 861000000) | ||
786 | band = 4; | ||
787 | else | ||
788 | return -EINVAL; | ||
789 | |||
790 | // setup PLL filter and TDA9889 | ||
791 | switch (p->bandwidth_hz) { | ||
792 | case 6000000: | ||
793 | tda1004x_writereg(fe, 0x0C, 0x14); | ||
794 | filter = 0; | ||
795 | break; | ||
796 | |||
797 | case 7000000: | ||
798 | tda1004x_writereg(fe, 0x0C, 0x80); | ||
799 | filter = 0; | ||
800 | break; | ||
801 | |||
802 | case 8000000: | ||
803 | tda1004x_writereg(fe, 0x0C, 0x14); | ||
804 | filter = 1; | ||
805 | break; | ||
806 | |||
807 | default: | ||
808 | return -EINVAL; | ||
809 | } | ||
810 | |||
811 | // calculate divisor | ||
812 | // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) | ||
813 | tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000; | ||
814 | |||
815 | // setup tuner buffer | ||
816 | tuner_buf[0] = tuner_frequency >> 8; | ||
817 | tuner_buf[1] = tuner_frequency & 0xff; | ||
818 | tuner_buf[2] = 0xca; | ||
819 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | ||
820 | |||
821 | if (fe->ops.i2c_gate_ctrl) | ||
822 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
823 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | ||
824 | return -EIO; | ||
825 | |||
826 | msleep(1); | ||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe, | ||
831 | const struct firmware **fw, char *name) | ||
832 | { | ||
833 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | ||
834 | |||
835 | return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev); | ||
836 | } | ||
837 | |||
838 | static struct tda1004x_config philips_tdm1316l_config = { | ||
839 | |||
840 | .demod_address = 0x8, | ||
841 | .invert = 0, | ||
842 | .invert_oclk = 0, | ||
843 | .xtal_freq = TDA10046_XTAL_4M, | ||
844 | .agc_config = TDA10046_AGC_DEFAULT, | ||
845 | .if_freq = TDA10046_FREQ_3617, | ||
846 | .request_firmware = philips_tdm1316l_request_firmware, | ||
847 | }; | ||
848 | |||
849 | static struct tda1004x_config philips_tdm1316l_config_invert = { | ||
850 | |||
851 | .demod_address = 0x8, | ||
852 | .invert = 1, | ||
853 | .invert_oclk = 0, | ||
854 | .xtal_freq = TDA10046_XTAL_4M, | ||
855 | .agc_config = TDA10046_AGC_DEFAULT, | ||
856 | .if_freq = TDA10046_FREQ_3617, | ||
857 | .request_firmware = philips_tdm1316l_request_firmware, | ||
858 | }; | ||
859 | |||
860 | static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) | ||
861 | { | ||
862 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
863 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | ||
864 | u8 tuner_buf[5]; | ||
865 | struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address, | ||
866 | .flags = 0, | ||
867 | .buf = tuner_buf, | ||
868 | .len = sizeof(tuner_buf) }; | ||
869 | int tuner_frequency = 0; | ||
870 | u8 band, cp, filter; | ||
871 | |||
872 | // determine charge pump | ||
873 | tuner_frequency = p->frequency + 36125000; | ||
874 | if (tuner_frequency < 87000000) | ||
875 | return -EINVAL; | ||
876 | else if (tuner_frequency < 130000000) { | ||
877 | cp = 3; | ||
878 | band = 1; | ||
879 | } else if (tuner_frequency < 160000000) { | ||
880 | cp = 5; | ||
881 | band = 1; | ||
882 | } else if (tuner_frequency < 200000000) { | ||
883 | cp = 6; | ||
884 | band = 1; | ||
885 | } else if (tuner_frequency < 290000000) { | ||
886 | cp = 3; | ||
887 | band = 2; | ||
888 | } else if (tuner_frequency < 420000000) { | ||
889 | cp = 5; | ||
890 | band = 2; | ||
891 | } else if (tuner_frequency < 480000000) { | ||
892 | cp = 6; | ||
893 | band = 2; | ||
894 | } else if (tuner_frequency < 620000000) { | ||
895 | cp = 3; | ||
896 | band = 4; | ||
897 | } else if (tuner_frequency < 830000000) { | ||
898 | cp = 5; | ||
899 | band = 4; | ||
900 | } else if (tuner_frequency < 895000000) { | ||
901 | cp = 7; | ||
902 | band = 4; | ||
903 | } else | ||
904 | return -EINVAL; | ||
905 | |||
906 | // assume PLL filter should always be 8MHz for the moment. | ||
907 | filter = 1; | ||
908 | |||
909 | // calculate divisor | ||
910 | tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500; | ||
911 | |||
912 | // setup tuner buffer | ||
913 | tuner_buf[0] = tuner_frequency >> 8; | ||
914 | tuner_buf[1] = tuner_frequency & 0xff; | ||
915 | tuner_buf[2] = 0xc8; | ||
916 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | ||
917 | tuner_buf[4] = 0x80; | ||
918 | |||
919 | if (fe->ops.i2c_gate_ctrl) | ||
920 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
921 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | ||
922 | return -EIO; | ||
923 | |||
924 | msleep(50); | ||
925 | |||
926 | if (fe->ops.i2c_gate_ctrl) | ||
927 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
928 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | ||
929 | return -EIO; | ||
930 | |||
931 | msleep(1); | ||
932 | |||
933 | return 0; | ||
934 | } | ||
935 | |||
936 | static u8 dvbc_philips_tdm1316l_inittab[] = { | ||
937 | 0x80, 0x01, | ||
938 | 0x80, 0x00, | ||
939 | 0x81, 0x01, | ||
940 | 0x81, 0x00, | ||
941 | 0x00, 0x09, | ||
942 | 0x01, 0x69, | ||
943 | 0x03, 0x00, | ||
944 | 0x04, 0x00, | ||
945 | 0x07, 0x00, | ||
946 | 0x08, 0x00, | ||
947 | 0x20, 0x00, | ||
948 | 0x21, 0x40, | ||
949 | 0x22, 0x00, | ||
950 | 0x23, 0x00, | ||
951 | 0x24, 0x40, | ||
952 | 0x25, 0x88, | ||
953 | 0x30, 0xff, | ||
954 | 0x31, 0x00, | ||
955 | 0x32, 0xff, | ||
956 | 0x33, 0x00, | ||
957 | 0x34, 0x50, | ||
958 | 0x35, 0x7f, | ||
959 | 0x36, 0x00, | ||
960 | 0x37, 0x20, | ||
961 | 0x38, 0x00, | ||
962 | 0x40, 0x1c, | ||
963 | 0x41, 0xff, | ||
964 | 0x42, 0x29, | ||
965 | 0x43, 0x20, | ||
966 | 0x44, 0xff, | ||
967 | 0x45, 0x00, | ||
968 | 0x46, 0x00, | ||
969 | 0x49, 0x04, | ||
970 | 0x4a, 0x00, | ||
971 | 0x4b, 0x7b, | ||
972 | 0x52, 0x30, | ||
973 | 0x55, 0xae, | ||
974 | 0x56, 0x47, | ||
975 | 0x57, 0xe1, | ||
976 | 0x58, 0x3a, | ||
977 | 0x5a, 0x1e, | ||
978 | 0x5b, 0x34, | ||
979 | 0x60, 0x00, | ||
980 | 0x63, 0x00, | ||
981 | 0x64, 0x00, | ||
982 | 0x65, 0x00, | ||
983 | 0x66, 0x00, | ||
984 | 0x67, 0x00, | ||
985 | 0x68, 0x00, | ||
986 | 0x69, 0x00, | ||
987 | 0x6a, 0x02, | ||
988 | 0x6b, 0x00, | ||
989 | 0x70, 0xff, | ||
990 | 0x71, 0x00, | ||
991 | 0x72, 0x00, | ||
992 | 0x73, 0x00, | ||
993 | 0x74, 0x0c, | ||
994 | 0x80, 0x00, | ||
995 | 0x81, 0x00, | ||
996 | 0x82, 0x00, | ||
997 | 0x83, 0x00, | ||
998 | 0x84, 0x04, | ||
999 | 0x85, 0x80, | ||
1000 | 0x86, 0x24, | ||
1001 | 0x87, 0x78, | ||
1002 | 0x88, 0x10, | ||
1003 | 0x89, 0x00, | ||
1004 | 0x90, 0x01, | ||
1005 | 0x91, 0x01, | ||
1006 | 0xa0, 0x04, | ||
1007 | 0xa1, 0x00, | ||
1008 | 0xa2, 0x00, | ||
1009 | 0xb0, 0x91, | ||
1010 | 0xb1, 0x0b, | ||
1011 | 0xc0, 0x53, | ||
1012 | 0xc1, 0x70, | ||
1013 | 0xc2, 0x12, | ||
1014 | 0xd0, 0x00, | ||
1015 | 0xd1, 0x00, | ||
1016 | 0xd2, 0x00, | ||
1017 | 0xd3, 0x00, | ||
1018 | 0xd4, 0x00, | ||
1019 | 0xd5, 0x00, | ||
1020 | 0xde, 0x00, | ||
1021 | 0xdf, 0x00, | ||
1022 | 0x61, 0x38, | ||
1023 | 0x62, 0x0a, | ||
1024 | 0x53, 0x13, | ||
1025 | 0x59, 0x08, | ||
1026 | 0xff, 0xff, | ||
1027 | }; | ||
1028 | |||
1029 | static struct stv0297_config dvbc_philips_tdm1316l_config = { | ||
1030 | .demod_address = 0x1c, | ||
1031 | .inittab = dvbc_philips_tdm1316l_inittab, | ||
1032 | .invert = 0, | ||
1033 | .stop_during_read = 1, | ||
1034 | }; | ||
1035 | |||
1036 | static struct tda10023_config tda10023_config = { | ||
1037 | .demod_address = 0xc, | ||
1038 | .invert = 0, | ||
1039 | .xtal = 16000000, | ||
1040 | .pll_m = 11, | ||
1041 | .pll_p = 3, | ||
1042 | .pll_n = 1, | ||
1043 | .deltaf = 0xa511, | ||
1044 | }; | ||
1045 | |||
1046 | static struct tda827x_config tda827x_config = { | ||
1047 | .config = 0, | ||
1048 | }; | ||
1049 | |||
1050 | /* TT S2-3200 DVB-S (STB0899) Inittab */ | ||
1051 | static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { | ||
1052 | |||
1053 | { STB0899_DEV_ID , 0x81 }, | ||
1054 | { STB0899_DISCNTRL1 , 0x32 }, | ||
1055 | { STB0899_DISCNTRL2 , 0x80 }, | ||
1056 | { STB0899_DISRX_ST0 , 0x04 }, | ||
1057 | { STB0899_DISRX_ST1 , 0x00 }, | ||
1058 | { STB0899_DISPARITY , 0x00 }, | ||
1059 | { STB0899_DISSTATUS , 0x20 }, | ||
1060 | { STB0899_DISF22 , 0x8c }, | ||
1061 | { STB0899_DISF22RX , 0x9a }, | ||
1062 | { STB0899_SYSREG , 0x0b }, | ||
1063 | { STB0899_ACRPRESC , 0x11 }, | ||
1064 | { STB0899_ACRDIV1 , 0x0a }, | ||
1065 | { STB0899_ACRDIV2 , 0x05 }, | ||
1066 | { STB0899_DACR1 , 0x00 }, | ||
1067 | { STB0899_DACR2 , 0x00 }, | ||
1068 | { STB0899_OUTCFG , 0x00 }, | ||
1069 | { STB0899_MODECFG , 0x00 }, | ||
1070 | { STB0899_IRQSTATUS_3 , 0x30 }, | ||
1071 | { STB0899_IRQSTATUS_2 , 0x00 }, | ||
1072 | { STB0899_IRQSTATUS_1 , 0x00 }, | ||
1073 | { STB0899_IRQSTATUS_0 , 0x00 }, | ||
1074 | { STB0899_IRQMSK_3 , 0xf3 }, | ||
1075 | { STB0899_IRQMSK_2 , 0xfc }, | ||
1076 | { STB0899_IRQMSK_1 , 0xff }, | ||
1077 | { STB0899_IRQMSK_0 , 0xff }, | ||
1078 | { STB0899_IRQCFG , 0x00 }, | ||
1079 | { STB0899_I2CCFG , 0x88 }, | ||
1080 | { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */ | ||
1081 | { STB0899_IOPVALUE5 , 0x00 }, | ||
1082 | { STB0899_IOPVALUE4 , 0x20 }, | ||
1083 | { STB0899_IOPVALUE3 , 0xc9 }, | ||
1084 | { STB0899_IOPVALUE2 , 0x90 }, | ||
1085 | { STB0899_IOPVALUE1 , 0x40 }, | ||
1086 | { STB0899_IOPVALUE0 , 0x00 }, | ||
1087 | { STB0899_GPIO00CFG , 0x82 }, | ||
1088 | { STB0899_GPIO01CFG , 0x82 }, | ||
1089 | { STB0899_GPIO02CFG , 0x82 }, | ||
1090 | { STB0899_GPIO03CFG , 0x82 }, | ||
1091 | { STB0899_GPIO04CFG , 0x82 }, | ||
1092 | { STB0899_GPIO05CFG , 0x82 }, | ||
1093 | { STB0899_GPIO06CFG , 0x82 }, | ||
1094 | { STB0899_GPIO07CFG , 0x82 }, | ||
1095 | { STB0899_GPIO08CFG , 0x82 }, | ||
1096 | { STB0899_GPIO09CFG , 0x82 }, | ||
1097 | { STB0899_GPIO10CFG , 0x82 }, | ||
1098 | { STB0899_GPIO11CFG , 0x82 }, | ||
1099 | { STB0899_GPIO12CFG , 0x82 }, | ||
1100 | { STB0899_GPIO13CFG , 0x82 }, | ||
1101 | { STB0899_GPIO14CFG , 0x82 }, | ||
1102 | { STB0899_GPIO15CFG , 0x82 }, | ||
1103 | { STB0899_GPIO16CFG , 0x82 }, | ||
1104 | { STB0899_GPIO17CFG , 0x82 }, | ||
1105 | { STB0899_GPIO18CFG , 0x82 }, | ||
1106 | { STB0899_GPIO19CFG , 0x82 }, | ||
1107 | { STB0899_GPIO20CFG , 0x82 }, | ||
1108 | { STB0899_SDATCFG , 0xb8 }, | ||
1109 | { STB0899_SCLTCFG , 0xba }, | ||
1110 | { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ | ||
1111 | { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ | ||
1112 | { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ | ||
1113 | { STB0899_DIRCLKCFG , 0x82 }, | ||
1114 | { STB0899_CLKOUT27CFG , 0x7e }, | ||
1115 | { STB0899_STDBYCFG , 0x82 }, | ||
1116 | { STB0899_CS0CFG , 0x82 }, | ||
1117 | { STB0899_CS1CFG , 0x82 }, | ||
1118 | { STB0899_DISEQCOCFG , 0x20 }, | ||
1119 | { STB0899_GPIO32CFG , 0x82 }, | ||
1120 | { STB0899_GPIO33CFG , 0x82 }, | ||
1121 | { STB0899_GPIO34CFG , 0x82 }, | ||
1122 | { STB0899_GPIO35CFG , 0x82 }, | ||
1123 | { STB0899_GPIO36CFG , 0x82 }, | ||
1124 | { STB0899_GPIO37CFG , 0x82 }, | ||
1125 | { STB0899_GPIO38CFG , 0x82 }, | ||
1126 | { STB0899_GPIO39CFG , 0x82 }, | ||
1127 | { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | ||
1128 | { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | ||
1129 | { STB0899_FILTCTRL , 0x00 }, | ||
1130 | { STB0899_SYSCTRL , 0x00 }, | ||
1131 | { STB0899_STOPCLK1 , 0x20 }, | ||
1132 | { STB0899_STOPCLK2 , 0x00 }, | ||
1133 | { STB0899_INTBUFSTATUS , 0x00 }, | ||
1134 | { STB0899_INTBUFCTRL , 0x0a }, | ||
1135 | { 0xffff , 0xff }, | ||
1136 | }; | ||
1137 | |||
1138 | static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { | ||
1139 | { STB0899_DEMOD , 0x00 }, | ||
1140 | { STB0899_RCOMPC , 0xc9 }, | ||
1141 | { STB0899_AGC1CN , 0x41 }, | ||
1142 | { STB0899_AGC1REF , 0x10 }, | ||
1143 | { STB0899_RTC , 0x7a }, | ||
1144 | { STB0899_TMGCFG , 0x4e }, | ||
1145 | { STB0899_AGC2REF , 0x34 }, | ||
1146 | { STB0899_TLSR , 0x84 }, | ||
1147 | { STB0899_CFD , 0xc7 }, | ||
1148 | { STB0899_ACLC , 0x87 }, | ||
1149 | { STB0899_BCLC , 0x94 }, | ||
1150 | { STB0899_EQON , 0x41 }, | ||
1151 | { STB0899_LDT , 0xdd }, | ||
1152 | { STB0899_LDT2 , 0xc9 }, | ||
1153 | { STB0899_EQUALREF , 0xb4 }, | ||
1154 | { STB0899_TMGRAMP , 0x10 }, | ||
1155 | { STB0899_TMGTHD , 0x30 }, | ||
1156 | { STB0899_IDCCOMP , 0xfb }, | ||
1157 | { STB0899_QDCCOMP , 0x03 }, | ||
1158 | { STB0899_POWERI , 0x3b }, | ||
1159 | { STB0899_POWERQ , 0x3d }, | ||
1160 | { STB0899_RCOMP , 0x81 }, | ||
1161 | { STB0899_AGCIQIN , 0x80 }, | ||
1162 | { STB0899_AGC2I1 , 0x04 }, | ||
1163 | { STB0899_AGC2I2 , 0xf5 }, | ||
1164 | { STB0899_TLIR , 0x25 }, | ||
1165 | { STB0899_RTF , 0x80 }, | ||
1166 | { STB0899_DSTATUS , 0x00 }, | ||
1167 | { STB0899_LDI , 0xca }, | ||
1168 | { STB0899_CFRM , 0xf1 }, | ||
1169 | { STB0899_CFRL , 0xf3 }, | ||
1170 | { STB0899_NIRM , 0x2a }, | ||
1171 | { STB0899_NIRL , 0x05 }, | ||
1172 | { STB0899_ISYMB , 0x17 }, | ||
1173 | { STB0899_QSYMB , 0xfa }, | ||
1174 | { STB0899_SFRH , 0x2f }, | ||
1175 | { STB0899_SFRM , 0x68 }, | ||
1176 | { STB0899_SFRL , 0x40 }, | ||
1177 | { STB0899_SFRUPH , 0x2f }, | ||
1178 | { STB0899_SFRUPM , 0x68 }, | ||
1179 | { STB0899_SFRUPL , 0x40 }, | ||
1180 | { STB0899_EQUAI1 , 0xfd }, | ||
1181 | { STB0899_EQUAQ1 , 0x04 }, | ||
1182 | { STB0899_EQUAI2 , 0x0f }, | ||
1183 | { STB0899_EQUAQ2 , 0xff }, | ||
1184 | { STB0899_EQUAI3 , 0xdf }, | ||
1185 | { STB0899_EQUAQ3 , 0xfa }, | ||
1186 | { STB0899_EQUAI4 , 0x37 }, | ||
1187 | { STB0899_EQUAQ4 , 0x0d }, | ||
1188 | { STB0899_EQUAI5 , 0xbd }, | ||
1189 | { STB0899_EQUAQ5 , 0xf7 }, | ||
1190 | { STB0899_DSTATUS2 , 0x00 }, | ||
1191 | { STB0899_VSTATUS , 0x00 }, | ||
1192 | { STB0899_VERROR , 0xff }, | ||
1193 | { STB0899_IQSWAP , 0x2a }, | ||
1194 | { STB0899_ECNT1M , 0x00 }, | ||
1195 | { STB0899_ECNT1L , 0x00 }, | ||
1196 | { STB0899_ECNT2M , 0x00 }, | ||
1197 | { STB0899_ECNT2L , 0x00 }, | ||
1198 | { STB0899_ECNT3M , 0x00 }, | ||
1199 | { STB0899_ECNT3L , 0x00 }, | ||
1200 | { STB0899_FECAUTO1 , 0x06 }, | ||
1201 | { STB0899_FECM , 0x01 }, | ||
1202 | { STB0899_VTH12 , 0xf0 }, | ||
1203 | { STB0899_VTH23 , 0xa0 }, | ||
1204 | { STB0899_VTH34 , 0x78 }, | ||
1205 | { STB0899_VTH56 , 0x4e }, | ||
1206 | { STB0899_VTH67 , 0x48 }, | ||
1207 | { STB0899_VTH78 , 0x38 }, | ||
1208 | { STB0899_PRVIT , 0xff }, | ||
1209 | { STB0899_VITSYNC , 0x19 }, | ||
1210 | { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | ||
1211 | { STB0899_TSULC , 0x42 }, | ||
1212 | { STB0899_RSLLC , 0x40 }, | ||
1213 | { STB0899_TSLPL , 0x12 }, | ||
1214 | { STB0899_TSCFGH , 0x0c }, | ||
1215 | { STB0899_TSCFGM , 0x00 }, | ||
1216 | { STB0899_TSCFGL , 0x0c }, | ||
1217 | { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ | ||
1218 | { STB0899_RSSYNCDEL , 0x00 }, | ||
1219 | { STB0899_TSINHDELH , 0x02 }, | ||
1220 | { STB0899_TSINHDELM , 0x00 }, | ||
1221 | { STB0899_TSINHDELL , 0x00 }, | ||
1222 | { STB0899_TSLLSTKM , 0x00 }, | ||
1223 | { STB0899_TSLLSTKL , 0x00 }, | ||
1224 | { STB0899_TSULSTKM , 0x00 }, | ||
1225 | { STB0899_TSULSTKL , 0xab }, | ||
1226 | { STB0899_PCKLENUL , 0x00 }, | ||
1227 | { STB0899_PCKLENLL , 0xcc }, | ||
1228 | { STB0899_RSPCKLEN , 0xcc }, | ||
1229 | { STB0899_TSSTATUS , 0x80 }, | ||
1230 | { STB0899_ERRCTRL1 , 0xb6 }, | ||
1231 | { STB0899_ERRCTRL2 , 0x96 }, | ||
1232 | { STB0899_ERRCTRL3 , 0x89 }, | ||
1233 | { STB0899_DMONMSK1 , 0x27 }, | ||
1234 | { STB0899_DMONMSK0 , 0x03 }, | ||
1235 | { STB0899_DEMAPVIT , 0x5c }, | ||
1236 | { STB0899_PLPARM , 0x1f }, | ||
1237 | { STB0899_PDELCTRL , 0x48 }, | ||
1238 | { STB0899_PDELCTRL2 , 0x00 }, | ||
1239 | { STB0899_BBHCTRL1 , 0x00 }, | ||
1240 | { STB0899_BBHCTRL2 , 0x00 }, | ||
1241 | { STB0899_HYSTTHRESH , 0x77 }, | ||
1242 | { STB0899_MATCSTM , 0x00 }, | ||
1243 | { STB0899_MATCSTL , 0x00 }, | ||
1244 | { STB0899_UPLCSTM , 0x00 }, | ||
1245 | { STB0899_UPLCSTL , 0x00 }, | ||
1246 | { STB0899_DFLCSTM , 0x00 }, | ||
1247 | { STB0899_DFLCSTL , 0x00 }, | ||
1248 | { STB0899_SYNCCST , 0x00 }, | ||
1249 | { STB0899_SYNCDCSTM , 0x00 }, | ||
1250 | { STB0899_SYNCDCSTL , 0x00 }, | ||
1251 | { STB0899_ISI_ENTRY , 0x00 }, | ||
1252 | { STB0899_ISI_BIT_EN , 0x00 }, | ||
1253 | { STB0899_MATSTRM , 0x00 }, | ||
1254 | { STB0899_MATSTRL , 0x00 }, | ||
1255 | { STB0899_UPLSTRM , 0x00 }, | ||
1256 | { STB0899_UPLSTRL , 0x00 }, | ||
1257 | { STB0899_DFLSTRM , 0x00 }, | ||
1258 | { STB0899_DFLSTRL , 0x00 }, | ||
1259 | { STB0899_SYNCSTR , 0x00 }, | ||
1260 | { STB0899_SYNCDSTRM , 0x00 }, | ||
1261 | { STB0899_SYNCDSTRL , 0x00 }, | ||
1262 | { STB0899_CFGPDELSTATUS1 , 0x10 }, | ||
1263 | { STB0899_CFGPDELSTATUS2 , 0x00 }, | ||
1264 | { STB0899_BBFERRORM , 0x00 }, | ||
1265 | { STB0899_BBFERRORL , 0x00 }, | ||
1266 | { STB0899_UPKTERRORM , 0x00 }, | ||
1267 | { STB0899_UPKTERRORL , 0x00 }, | ||
1268 | { 0xffff , 0xff }, | ||
1269 | }; | ||
1270 | |||
1271 | static struct stb0899_config tt3200_config = { | ||
1272 | .init_dev = tt3200_stb0899_s1_init_1, | ||
1273 | .init_s2_demod = stb0899_s2_init_2, | ||
1274 | .init_s1_demod = tt3200_stb0899_s1_init_3, | ||
1275 | .init_s2_fec = stb0899_s2_init_4, | ||
1276 | .init_tst = stb0899_s1_init_5, | ||
1277 | |||
1278 | .postproc = NULL, | ||
1279 | |||
1280 | .demod_address = 0x68, | ||
1281 | |||
1282 | .xtal_freq = 27000000, | ||
1283 | .inversion = IQ_SWAP_ON, /* 1 */ | ||
1284 | |||
1285 | .lo_clk = 76500000, | ||
1286 | .hi_clk = 99000000, | ||
1287 | |||
1288 | .esno_ave = STB0899_DVBS2_ESNO_AVE, | ||
1289 | .esno_quant = STB0899_DVBS2_ESNO_QUANT, | ||
1290 | .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, | ||
1291 | .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, | ||
1292 | .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, | ||
1293 | .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, | ||
1294 | .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, | ||
1295 | .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, | ||
1296 | .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | ||
1297 | |||
1298 | .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, | ||
1299 | .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | ||
1300 | .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, | ||
1301 | .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, | ||
1302 | |||
1303 | .tuner_get_frequency = stb6100_get_frequency, | ||
1304 | .tuner_set_frequency = stb6100_set_frequency, | ||
1305 | .tuner_set_bandwidth = stb6100_set_bandwidth, | ||
1306 | .tuner_get_bandwidth = stb6100_get_bandwidth, | ||
1307 | .tuner_set_rfsiggain = NULL | ||
1308 | }; | ||
1309 | |||
1310 | static struct stb6100_config tt3200_stb6100_config = { | ||
1311 | .tuner_address = 0x60, | ||
1312 | .refclock = 27000000, | ||
1313 | }; | ||
1314 | |||
1315 | static void frontend_init(struct budget_ci *budget_ci) | ||
1316 | { | ||
1317 | switch (budget_ci->budget.dev->pci->subsystem_device) { | ||
1318 | case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059)) | ||
1319 | budget_ci->budget.dvb_frontend = | ||
1320 | dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap); | ||
1321 | if (budget_ci->budget.dvb_frontend) { | ||
1322 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | ||
1323 | budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; | ||
1324 | break; | ||
1325 | } | ||
1326 | break; | ||
1327 | |||
1328 | case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059)) | ||
1329 | budget_ci->budget.dvb_frontend = | ||
1330 | dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap); | ||
1331 | if (budget_ci->budget.dvb_frontend) { | ||
1332 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params; | ||
1333 | break; | ||
1334 | } | ||
1335 | break; | ||
1336 | |||
1337 | case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt)) | ||
1338 | budget_ci->tuner_pll_address = 0x61; | ||
1339 | budget_ci->budget.dvb_frontend = | ||
1340 | dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | ||
1341 | if (budget_ci->budget.dvb_frontend) { | ||
1342 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; | ||
1343 | break; | ||
1344 | } | ||
1345 | break; | ||
1346 | |||
1347 | case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889) | ||
1348 | budget_ci->tuner_pll_address = 0x63; | ||
1349 | budget_ci->budget.dvb_frontend = | ||
1350 | dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | ||
1351 | if (budget_ci->budget.dvb_frontend) { | ||
1352 | budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1353 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1354 | break; | ||
1355 | } | ||
1356 | break; | ||
1357 | |||
1358 | case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) | ||
1359 | budget_ci->tuner_pll_address = 0x60; | ||
1360 | budget_ci->budget.dvb_frontend = | ||
1361 | dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap); | ||
1362 | if (budget_ci->budget.dvb_frontend) { | ||
1363 | budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1364 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1365 | break; | ||
1366 | } | ||
1367 | break; | ||
1368 | |||
1369 | case 0x1017: // TT S-1500 PCI | ||
1370 | budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap); | ||
1371 | if (budget_ci->budget.dvb_frontend) { | ||
1372 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; | ||
1373 | budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; | ||
1374 | |||
1375 | budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
1376 | if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) { | ||
1377 | printk("%s: No LNBP21 found!\n", __func__); | ||
1378 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1379 | budget_ci->budget.dvb_frontend = NULL; | ||
1380 | } | ||
1381 | } | ||
1382 | break; | ||
1383 | |||
1384 | case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */ | ||
1385 | budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48); | ||
1386 | if (budget_ci->budget.dvb_frontend) { | ||
1387 | if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) { | ||
1388 | printk(KERN_ERR "%s: No tda827x found!\n", __func__); | ||
1389 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1390 | budget_ci->budget.dvb_frontend = NULL; | ||
1391 | } | ||
1392 | } | ||
1393 | break; | ||
1394 | |||
1395 | case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */ | ||
1396 | budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap); | ||
1397 | if (budget_ci->budget.dvb_frontend) { | ||
1398 | if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) { | ||
1399 | if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) { | ||
1400 | printk(KERN_ERR "%s: No LNBP21 found!\n", __func__); | ||
1401 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1402 | budget_ci->budget.dvb_frontend = NULL; | ||
1403 | } | ||
1404 | } else { | ||
1405 | printk(KERN_ERR "%s: No STB6000 found!\n", __func__); | ||
1406 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1407 | budget_ci->budget.dvb_frontend = NULL; | ||
1408 | } | ||
1409 | } | ||
1410 | break; | ||
1411 | |||
1412 | case 0x1019: // TT S2-3200 PCI | ||
1413 | /* | ||
1414 | * NOTE! on some STB0899 versions, the internal PLL takes a longer time | ||
1415 | * to settle, aka LOCK. On the older revisions of the chip, we don't see | ||
1416 | * this, as a result on the newer chips the entire clock tree, will not | ||
1417 | * be stable after a freshly POWER 'ed up situation. | ||
1418 | * In this case, we should RESET the STB0899 (Active LOW) and wait for | ||
1419 | * PLL stabilization. | ||
1420 | * | ||
1421 | * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is | ||
1422 | * connected to the SAA7146 GPIO, GPIO2, Pin 142 | ||
1423 | */ | ||
1424 | /* Reset Demodulator */ | ||
1425 | saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO); | ||
1426 | /* Wait for everything to die */ | ||
1427 | msleep(50); | ||
1428 | /* Pull it up out of Reset state */ | ||
1429 | saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI); | ||
1430 | /* Wait for PLL to stabilize */ | ||
1431 | msleep(250); | ||
1432 | /* | ||
1433 | * PLL state should be stable now. Ideally, we should check | ||
1434 | * for PLL LOCK status. But well, never mind! | ||
1435 | */ | ||
1436 | budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap); | ||
1437 | if (budget_ci->budget.dvb_frontend) { | ||
1438 | if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) { | ||
1439 | if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) { | ||
1440 | printk("%s: No LNBP21 found!\n", __func__); | ||
1441 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1442 | budget_ci->budget.dvb_frontend = NULL; | ||
1443 | } | ||
1444 | } else { | ||
1445 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1446 | budget_ci->budget.dvb_frontend = NULL; | ||
1447 | } | ||
1448 | } | ||
1449 | break; | ||
1450 | |||
1451 | } | ||
1452 | |||
1453 | if (budget_ci->budget.dvb_frontend == NULL) { | ||
1454 | printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", | ||
1455 | budget_ci->budget.dev->pci->vendor, | ||
1456 | budget_ci->budget.dev->pci->device, | ||
1457 | budget_ci->budget.dev->pci->subsystem_vendor, | ||
1458 | budget_ci->budget.dev->pci->subsystem_device); | ||
1459 | } else { | ||
1460 | if (dvb_register_frontend | ||
1461 | (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { | ||
1462 | printk("budget-ci: Frontend registration failed!\n"); | ||
1463 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1464 | budget_ci->budget.dvb_frontend = NULL; | ||
1465 | } | ||
1466 | } | ||
1467 | } | ||
1468 | |||
1469 | static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) | ||
1470 | { | ||
1471 | struct budget_ci *budget_ci; | ||
1472 | int err; | ||
1473 | |||
1474 | budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL); | ||
1475 | if (!budget_ci) { | ||
1476 | err = -ENOMEM; | ||
1477 | goto out1; | ||
1478 | } | ||
1479 | |||
1480 | dprintk(2, "budget_ci: %p\n", budget_ci); | ||
1481 | |||
1482 | dev->ext_priv = budget_ci; | ||
1483 | |||
1484 | err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE, | ||
1485 | adapter_nr); | ||
1486 | if (err) | ||
1487 | goto out2; | ||
1488 | |||
1489 | err = msp430_ir_init(budget_ci); | ||
1490 | if (err) | ||
1491 | goto out3; | ||
1492 | |||
1493 | ciintf_init(budget_ci); | ||
1494 | |||
1495 | budget_ci->budget.dvb_adapter.priv = budget_ci; | ||
1496 | frontend_init(budget_ci); | ||
1497 | |||
1498 | ttpci_budget_init_hooks(&budget_ci->budget); | ||
1499 | |||
1500 | return 0; | ||
1501 | |||
1502 | out3: | ||
1503 | ttpci_budget_deinit(&budget_ci->budget); | ||
1504 | out2: | ||
1505 | kfree(budget_ci); | ||
1506 | out1: | ||
1507 | return err; | ||
1508 | } | ||
1509 | |||
1510 | static int budget_ci_detach(struct saa7146_dev *dev) | ||
1511 | { | ||
1512 | struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv; | ||
1513 | struct saa7146_dev *saa = budget_ci->budget.dev; | ||
1514 | int err; | ||
1515 | |||
1516 | if (budget_ci->budget.ci_present) | ||
1517 | ciintf_deinit(budget_ci); | ||
1518 | msp430_ir_deinit(budget_ci); | ||
1519 | if (budget_ci->budget.dvb_frontend) { | ||
1520 | dvb_unregister_frontend(budget_ci->budget.dvb_frontend); | ||
1521 | dvb_frontend_detach(budget_ci->budget.dvb_frontend); | ||
1522 | } | ||
1523 | err = ttpci_budget_deinit(&budget_ci->budget); | ||
1524 | |||
1525 | // disable frontend and CI interface | ||
1526 | saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); | ||
1527 | |||
1528 | kfree(budget_ci); | ||
1529 | |||
1530 | return err; | ||
1531 | } | ||
1532 | |||
1533 | static struct saa7146_extension budget_extension; | ||
1534 | |||
1535 | MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT); | ||
1536 | MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); | ||
1537 | MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); | ||
1538 | MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); | ||
1539 | MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); | ||
1540 | MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); | ||
1541 | MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); | ||
1542 | MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT); | ||
1543 | |||
1544 | static struct pci_device_id pci_tbl[] = { | ||
1545 | MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), | ||
1546 | MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f), | ||
1547 | MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010), | ||
1548 | MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), | ||
1549 | MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), | ||
1550 | MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), | ||
1551 | MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), | ||
1552 | MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019), | ||
1553 | MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b), | ||
1554 | { | ||
1555 | .vendor = 0, | ||
1556 | } | ||
1557 | }; | ||
1558 | |||
1559 | MODULE_DEVICE_TABLE(pci, pci_tbl); | ||
1560 | |||
1561 | static struct saa7146_extension budget_extension = { | ||
1562 | .name = "budget_ci dvb", | ||
1563 | .flags = SAA7146_USE_I2C_IRQ, | ||
1564 | |||
1565 | .module = THIS_MODULE, | ||
1566 | .pci_tbl = &pci_tbl[0], | ||
1567 | .attach = budget_ci_attach, | ||
1568 | .detach = budget_ci_detach, | ||
1569 | |||
1570 | .irq_mask = MASK_03 | MASK_06 | MASK_10, | ||
1571 | .irq_func = budget_ci_irq, | ||
1572 | }; | ||
1573 | |||
1574 | static int __init budget_ci_init(void) | ||
1575 | { | ||
1576 | return saa7146_register_extension(&budget_extension); | ||
1577 | } | ||
1578 | |||
1579 | static void __exit budget_ci_exit(void) | ||
1580 | { | ||
1581 | saa7146_unregister_extension(&budget_extension); | ||
1582 | } | ||
1583 | |||
1584 | module_init(budget_ci_init); | ||
1585 | module_exit(budget_ci_exit); | ||
1586 | |||
1587 | MODULE_LICENSE("GPL"); | ||
1588 | MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others"); | ||
1589 | MODULE_DESCRIPTION("driver for the SAA7146 based so-called " | ||
1590 | "budget PCI DVB cards w/ CI-module produced by " | ||
1591 | "Siemens, Technotrend, Hauppauge"); | ||
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c deleted file mode 100644 index 37d02fe09137..000000000000 --- a/drivers/media/dvb/ttpci/budget-core.c +++ /dev/null | |||
@@ -1,602 +0,0 @@ | |||
1 | /* | ||
2 | * budget-core.c: driver for the SAA7146 based Budget DVB cards | ||
3 | * | ||
4 | * Compiled from various sources by Michael Hunold <michael@mihu.de> | ||
5 | * | ||
6 | * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * | ||
8 | * Copyright (C) 1999-2002 Ralph Metzler | ||
9 | * & Marcus Metzler for convergence integrated media GmbH | ||
10 | * | ||
11 | * 26feb2004 Support for FS Activy Card (Grundig tuner) by | ||
12 | * Michael Dreher <michael@5dot1.de>, | ||
13 | * Oliver Endriss <o.endriss@gmx.de>, | ||
14 | * Andreas 'randy' Weinberger | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License | ||
18 | * as published by the Free Software Foundation; either version 2 | ||
19 | * of the License, or (at your option) any later version. | ||
20 | * | ||
21 | * | ||
22 | * This program is distributed in the hope that it will be useful, | ||
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
25 | * GNU General Public License for more details. | ||
26 | * | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program; if not, write to the Free Software | ||
30 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
31 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
32 | * | ||
33 | * | ||
34 | * the project's page is at http://www.linuxtv.org/ | ||
35 | */ | ||
36 | |||
37 | |||
38 | #include "budget.h" | ||
39 | #include "ttpci-eeprom.h" | ||
40 | |||
41 | #define TS_WIDTH (2 * TS_SIZE) | ||
42 | #define TS_WIDTH_ACTIVY TS_SIZE | ||
43 | #define TS_WIDTH_DVBC TS_SIZE | ||
44 | #define TS_HEIGHT_MASK 0xf00 | ||
45 | #define TS_HEIGHT_MASK_ACTIVY 0xc00 | ||
46 | #define TS_HEIGHT_MASK_DVBC 0xe00 | ||
47 | #define TS_MIN_BUFSIZE_K 188 | ||
48 | #define TS_MAX_BUFSIZE_K 1410 | ||
49 | #define TS_MAX_BUFSIZE_K_ACTIVY 564 | ||
50 | #define TS_MAX_BUFSIZE_K_DVBC 1316 | ||
51 | #define BUFFER_WARNING_WAIT (30*HZ) | ||
52 | |||
53 | int budget_debug; | ||
54 | static int dma_buffer_size = TS_MIN_BUFSIZE_K; | ||
55 | module_param_named(debug, budget_debug, int, 0644); | ||
56 | module_param_named(bufsize, dma_buffer_size, int, 0444); | ||
57 | MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off)."); | ||
58 | MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)"); | ||
59 | |||
60 | /**************************************************************************** | ||
61 | * TT budget / WinTV Nova | ||
62 | ****************************************************************************/ | ||
63 | |||
64 | static int stop_ts_capture(struct budget *budget) | ||
65 | { | ||
66 | dprintk(2, "budget: %p\n", budget); | ||
67 | |||
68 | saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off | ||
69 | SAA7146_IER_DISABLE(budget->dev, MASK_10); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int start_ts_capture(struct budget *budget) | ||
74 | { | ||
75 | struct saa7146_dev *dev = budget->dev; | ||
76 | |||
77 | dprintk(2, "budget: %p\n", budget); | ||
78 | |||
79 | if (!budget->feeding || !budget->fe_synced) | ||
80 | return 0; | ||
81 | |||
82 | saa7146_write(dev, MC1, MASK_20); // DMA3 off | ||
83 | |||
84 | memset(budget->grabbing, 0x00, budget->buffer_size); | ||
85 | |||
86 | saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000)); | ||
87 | |||
88 | budget->ttbp = 0; | ||
89 | |||
90 | /* | ||
91 | * Signal path on the Activy: | ||
92 | * | ||
93 | * tuner -> SAA7146 port A -> SAA7146 BRS -> SAA7146 DMA3 -> memory | ||
94 | * | ||
95 | * Since the tuner feeds 204 bytes packets into the SAA7146, | ||
96 | * DMA3 is configured to strip the trailing 16 FEC bytes: | ||
97 | * Pitch: 188, NumBytes3: 188, NumLines3: 1024 | ||
98 | */ | ||
99 | |||
100 | switch(budget->card->type) { | ||
101 | case BUDGET_FS_ACTIVY: | ||
102 | saa7146_write(dev, DD1_INIT, 0x04000000); | ||
103 | saa7146_write(dev, MC2, (MASK_09 | MASK_25)); | ||
104 | saa7146_write(dev, BRS_CTRL, 0x00000000); | ||
105 | break; | ||
106 | case BUDGET_PATCH: | ||
107 | saa7146_write(dev, DD1_INIT, 0x00000200); | ||
108 | saa7146_write(dev, MC2, (MASK_10 | MASK_26)); | ||
109 | saa7146_write(dev, BRS_CTRL, 0x60000000); | ||
110 | break; | ||
111 | case BUDGET_CIN1200C_MK3: | ||
112 | case BUDGET_KNC1C_MK3: | ||
113 | case BUDGET_KNC1C_TDA10024: | ||
114 | case BUDGET_KNC1CP_MK3: | ||
115 | if (budget->video_port == BUDGET_VIDEO_PORTA) { | ||
116 | saa7146_write(dev, DD1_INIT, 0x06000200); | ||
117 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
118 | saa7146_write(dev, BRS_CTRL, 0x00000000); | ||
119 | } else { | ||
120 | saa7146_write(dev, DD1_INIT, 0x00000600); | ||
121 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
122 | saa7146_write(dev, BRS_CTRL, 0x60000000); | ||
123 | } | ||
124 | break; | ||
125 | default: | ||
126 | if (budget->video_port == BUDGET_VIDEO_PORTA) { | ||
127 | saa7146_write(dev, DD1_INIT, 0x06000200); | ||
128 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
129 | saa7146_write(dev, BRS_CTRL, 0x00000000); | ||
130 | } else { | ||
131 | saa7146_write(dev, DD1_INIT, 0x02000600); | ||
132 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
133 | saa7146_write(dev, BRS_CTRL, 0x60000000); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | saa7146_write(dev, MC2, (MASK_08 | MASK_24)); | ||
138 | mdelay(10); | ||
139 | |||
140 | saa7146_write(dev, BASE_ODD3, 0); | ||
141 | if (budget->buffer_size > budget->buffer_height * budget->buffer_width) { | ||
142 | // using odd/even buffers | ||
143 | saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width); | ||
144 | } else { | ||
145 | // using a single buffer | ||
146 | saa7146_write(dev, BASE_EVEN3, 0); | ||
147 | } | ||
148 | saa7146_write(dev, PROT_ADDR3, budget->buffer_size); | ||
149 | saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); | ||
150 | |||
151 | saa7146_write(dev, PITCH3, budget->buffer_width); | ||
152 | saa7146_write(dev, NUM_LINE_BYTE3, | ||
153 | (budget->buffer_height << 16) | budget->buffer_width); | ||
154 | |||
155 | saa7146_write(dev, MC2, (MASK_04 | MASK_20)); | ||
156 | |||
157 | SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */ | ||
158 | SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ | ||
159 | saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status) | ||
165 | { | ||
166 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
167 | int synced; | ||
168 | int ret; | ||
169 | |||
170 | if (budget->read_fe_status) | ||
171 | ret = budget->read_fe_status(fe, status); | ||
172 | else | ||
173 | ret = -EINVAL; | ||
174 | |||
175 | if (!ret) { | ||
176 | synced = (*status & FE_HAS_LOCK); | ||
177 | if (synced != budget->fe_synced) { | ||
178 | budget->fe_synced = synced; | ||
179 | spin_lock(&budget->feedlock); | ||
180 | if (synced) | ||
181 | start_ts_capture(budget); | ||
182 | else | ||
183 | stop_ts_capture(budget); | ||
184 | spin_unlock(&budget->feedlock); | ||
185 | } | ||
186 | } | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static void vpeirq(unsigned long data) | ||
191 | { | ||
192 | struct budget *budget = (struct budget *) data; | ||
193 | u8 *mem = (u8 *) (budget->grabbing); | ||
194 | u32 olddma = budget->ttbp; | ||
195 | u32 newdma = saa7146_read(budget->dev, PCI_VDP3); | ||
196 | u32 count; | ||
197 | |||
198 | /* Ensure streamed PCI data is synced to CPU */ | ||
199 | pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE); | ||
200 | |||
201 | /* nearest lower position divisible by 188 */ | ||
202 | newdma -= newdma % 188; | ||
203 | |||
204 | if (newdma >= budget->buffer_size) | ||
205 | return; | ||
206 | |||
207 | budget->ttbp = newdma; | ||
208 | |||
209 | if (budget->feeding == 0 || newdma == olddma) | ||
210 | return; | ||
211 | |||
212 | if (newdma > olddma) { /* no wraparound, dump olddma..newdma */ | ||
213 | count = newdma - olddma; | ||
214 | dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); | ||
215 | } else { /* wraparound, dump olddma..buflen and 0..newdma */ | ||
216 | count = budget->buffer_size - olddma; | ||
217 | dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); | ||
218 | count += newdma; | ||
219 | dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188); | ||
220 | } | ||
221 | |||
222 | if (count > budget->buffer_warning_threshold) | ||
223 | budget->buffer_warnings++; | ||
224 | |||
225 | if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) { | ||
226 | printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n", | ||
227 | budget->dev->name, __func__, budget->buffer_warnings, count); | ||
228 | budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT; | ||
229 | budget->buffer_warnings = 0; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | |||
234 | int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count, | ||
235 | int uselocks, int nobusyloop) | ||
236 | { | ||
237 | struct saa7146_dev *saa = budget->dev; | ||
238 | int result = 0; | ||
239 | unsigned long flags = 0; | ||
240 | |||
241 | if (count > 4 || count <= 0) | ||
242 | return 0; | ||
243 | |||
244 | if (uselocks) | ||
245 | spin_lock_irqsave(&budget->debilock, flags); | ||
246 | |||
247 | if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { | ||
248 | if (uselocks) | ||
249 | spin_unlock_irqrestore(&budget->debilock, flags); | ||
250 | return result; | ||
251 | } | ||
252 | |||
253 | saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); | ||
254 | saa7146_write(saa, DEBI_CONFIG, config); | ||
255 | saa7146_write(saa, DEBI_PAGE, 0); | ||
256 | saa7146_write(saa, MC2, (2 << 16) | 2); | ||
257 | |||
258 | if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { | ||
259 | if (uselocks) | ||
260 | spin_unlock_irqrestore(&budget->debilock, flags); | ||
261 | return result; | ||
262 | } | ||
263 | |||
264 | result = saa7146_read(saa, DEBI_AD); | ||
265 | result &= (0xffffffffUL >> ((4 - count) * 8)); | ||
266 | |||
267 | if (uselocks) | ||
268 | spin_unlock_irqrestore(&budget->debilock, flags); | ||
269 | |||
270 | return result; | ||
271 | } | ||
272 | |||
273 | int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, | ||
274 | int count, u32 value, int uselocks, int nobusyloop) | ||
275 | { | ||
276 | struct saa7146_dev *saa = budget->dev; | ||
277 | unsigned long flags = 0; | ||
278 | int result; | ||
279 | |||
280 | if (count > 4 || count <= 0) | ||
281 | return 0; | ||
282 | |||
283 | if (uselocks) | ||
284 | spin_lock_irqsave(&budget->debilock, flags); | ||
285 | |||
286 | if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { | ||
287 | if (uselocks) | ||
288 | spin_unlock_irqrestore(&budget->debilock, flags); | ||
289 | return result; | ||
290 | } | ||
291 | |||
292 | saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x00000 | (addr & 0xffff)); | ||
293 | saa7146_write(saa, DEBI_CONFIG, config); | ||
294 | saa7146_write(saa, DEBI_PAGE, 0); | ||
295 | saa7146_write(saa, DEBI_AD, value); | ||
296 | saa7146_write(saa, MC2, (2 << 16) | 2); | ||
297 | |||
298 | if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { | ||
299 | if (uselocks) | ||
300 | spin_unlock_irqrestore(&budget->debilock, flags); | ||
301 | return result; | ||
302 | } | ||
303 | |||
304 | if (uselocks) | ||
305 | spin_unlock_irqrestore(&budget->debilock, flags); | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | |||
310 | /**************************************************************************** | ||
311 | * DVB API SECTION | ||
312 | ****************************************************************************/ | ||
313 | |||
314 | static int budget_start_feed(struct dvb_demux_feed *feed) | ||
315 | { | ||
316 | struct dvb_demux *demux = feed->demux; | ||
317 | struct budget *budget = (struct budget *) demux->priv; | ||
318 | int status = 0; | ||
319 | |||
320 | dprintk(2, "budget: %p\n", budget); | ||
321 | |||
322 | if (!demux->dmx.frontend) | ||
323 | return -EINVAL; | ||
324 | |||
325 | spin_lock(&budget->feedlock); | ||
326 | feed->pusi_seen = 0; /* have a clean section start */ | ||
327 | if (budget->feeding++ == 0) | ||
328 | status = start_ts_capture(budget); | ||
329 | spin_unlock(&budget->feedlock); | ||
330 | return status; | ||
331 | } | ||
332 | |||
333 | static int budget_stop_feed(struct dvb_demux_feed *feed) | ||
334 | { | ||
335 | struct dvb_demux *demux = feed->demux; | ||
336 | struct budget *budget = (struct budget *) demux->priv; | ||
337 | int status = 0; | ||
338 | |||
339 | dprintk(2, "budget: %p\n", budget); | ||
340 | |||
341 | spin_lock(&budget->feedlock); | ||
342 | if (--budget->feeding == 0) | ||
343 | status = stop_ts_capture(budget); | ||
344 | spin_unlock(&budget->feedlock); | ||
345 | return status; | ||
346 | } | ||
347 | |||
348 | static int budget_register(struct budget *budget) | ||
349 | { | ||
350 | struct dvb_demux *dvbdemux = &budget->demux; | ||
351 | int ret; | ||
352 | |||
353 | dprintk(2, "budget: %p\n", budget); | ||
354 | |||
355 | dvbdemux->priv = (void *) budget; | ||
356 | |||
357 | dvbdemux->filternum = 256; | ||
358 | dvbdemux->feednum = 256; | ||
359 | dvbdemux->start_feed = budget_start_feed; | ||
360 | dvbdemux->stop_feed = budget_stop_feed; | ||
361 | dvbdemux->write_to_decoder = NULL; | ||
362 | |||
363 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
364 | DMX_MEMORY_BASED_FILTERING); | ||
365 | |||
366 | dvb_dmx_init(&budget->demux); | ||
367 | |||
368 | budget->dmxdev.filternum = 256; | ||
369 | budget->dmxdev.demux = &dvbdemux->dmx; | ||
370 | budget->dmxdev.capabilities = 0; | ||
371 | |||
372 | dvb_dmxdev_init(&budget->dmxdev, &budget->dvb_adapter); | ||
373 | |||
374 | budget->hw_frontend.source = DMX_FRONTEND_0; | ||
375 | |||
376 | ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend); | ||
377 | |||
378 | if (ret < 0) | ||
379 | return ret; | ||
380 | |||
381 | budget->mem_frontend.source = DMX_MEMORY_FE; | ||
382 | ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend); | ||
383 | if (ret < 0) | ||
384 | return ret; | ||
385 | |||
386 | ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend); | ||
387 | if (ret < 0) | ||
388 | return ret; | ||
389 | |||
390 | dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx); | ||
391 | |||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static void budget_unregister(struct budget *budget) | ||
396 | { | ||
397 | struct dvb_demux *dvbdemux = &budget->demux; | ||
398 | |||
399 | dprintk(2, "budget: %p\n", budget); | ||
400 | |||
401 | dvb_net_release(&budget->dvb_net); | ||
402 | |||
403 | dvbdemux->dmx.close(&dvbdemux->dmx); | ||
404 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend); | ||
405 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend); | ||
406 | |||
407 | dvb_dmxdev_release(&budget->dmxdev); | ||
408 | dvb_dmx_release(&budget->demux); | ||
409 | } | ||
410 | |||
411 | int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | ||
412 | struct saa7146_pci_extension_data *info, | ||
413 | struct module *owner, short *adapter_nums) | ||
414 | { | ||
415 | int ret = 0; | ||
416 | struct budget_info *bi = info->ext_priv; | ||
417 | int max_bufsize; | ||
418 | int height_mask; | ||
419 | |||
420 | memset(budget, 0, sizeof(struct budget)); | ||
421 | |||
422 | dprintk(2, "dev: %p, budget: %p\n", dev, budget); | ||
423 | |||
424 | budget->card = bi; | ||
425 | budget->dev = (struct saa7146_dev *) dev; | ||
426 | |||
427 | switch(budget->card->type) { | ||
428 | case BUDGET_FS_ACTIVY: | ||
429 | budget->buffer_width = TS_WIDTH_ACTIVY; | ||
430 | max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; | ||
431 | height_mask = TS_HEIGHT_MASK_ACTIVY; | ||
432 | break; | ||
433 | |||
434 | case BUDGET_KNC1C: | ||
435 | case BUDGET_KNC1CP: | ||
436 | case BUDGET_CIN1200C: | ||
437 | case BUDGET_KNC1C_MK3: | ||
438 | case BUDGET_KNC1C_TDA10024: | ||
439 | case BUDGET_KNC1CP_MK3: | ||
440 | case BUDGET_CIN1200C_MK3: | ||
441 | budget->buffer_width = TS_WIDTH_DVBC; | ||
442 | max_bufsize = TS_MAX_BUFSIZE_K_DVBC; | ||
443 | height_mask = TS_HEIGHT_MASK_DVBC; | ||
444 | break; | ||
445 | |||
446 | default: | ||
447 | budget->buffer_width = TS_WIDTH; | ||
448 | max_bufsize = TS_MAX_BUFSIZE_K; | ||
449 | height_mask = TS_HEIGHT_MASK; | ||
450 | } | ||
451 | |||
452 | if (dma_buffer_size < TS_MIN_BUFSIZE_K) | ||
453 | dma_buffer_size = TS_MIN_BUFSIZE_K; | ||
454 | else if (dma_buffer_size > max_bufsize) | ||
455 | dma_buffer_size = max_bufsize; | ||
456 | |||
457 | budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; | ||
458 | if (budget->buffer_height > 0xfff) { | ||
459 | budget->buffer_height /= 2; | ||
460 | budget->buffer_height &= height_mask; | ||
461 | budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width; | ||
462 | } else { | ||
463 | budget->buffer_height &= height_mask; | ||
464 | budget->buffer_size = budget->buffer_height * budget->buffer_width; | ||
465 | } | ||
466 | budget->buffer_warning_threshold = budget->buffer_size * 80/100; | ||
467 | budget->buffer_warnings = 0; | ||
468 | budget->buffer_warning_time = jiffies; | ||
469 | |||
470 | dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n", | ||
471 | budget->dev->name, | ||
472 | budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single", | ||
473 | budget->buffer_width, budget->buffer_height); | ||
474 | printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); | ||
475 | |||
476 | ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, | ||
477 | owner, &budget->dev->pci->dev, adapter_nums); | ||
478 | if (ret < 0) | ||
479 | return ret; | ||
480 | |||
481 | /* set dd1 stream a & b */ | ||
482 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | ||
483 | saa7146_write(dev, MC2, (MASK_09 | MASK_25)); | ||
484 | saa7146_write(dev, MC2, (MASK_10 | MASK_26)); | ||
485 | saa7146_write(dev, DD1_INIT, 0x02000000); | ||
486 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
487 | |||
488 | if (bi->type != BUDGET_FS_ACTIVY) | ||
489 | budget->video_port = BUDGET_VIDEO_PORTB; | ||
490 | else | ||
491 | budget->video_port = BUDGET_VIDEO_PORTA; | ||
492 | spin_lock_init(&budget->feedlock); | ||
493 | spin_lock_init(&budget->debilock); | ||
494 | |||
495 | /* the Siemens DVB needs this if you want to have the i2c chips | ||
496 | get recognized before the main driver is loaded */ | ||
497 | if (bi->type != BUDGET_FS_ACTIVY) | ||
498 | saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ | ||
499 | |||
500 | strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); | ||
501 | |||
502 | saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); | ||
503 | strcpy(budget->i2c_adap.name, budget->card->name); | ||
504 | |||
505 | if (i2c_add_adapter(&budget->i2c_adap) < 0) { | ||
506 | ret = -ENOMEM; | ||
507 | goto err_dvb_unregister; | ||
508 | } | ||
509 | |||
510 | ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac); | ||
511 | |||
512 | budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt); | ||
513 | if (NULL == budget->grabbing) { | ||
514 | ret = -ENOMEM; | ||
515 | goto err_del_i2c; | ||
516 | } | ||
517 | |||
518 | saa7146_write(dev, PCI_BT_V1, 0x001c0000); | ||
519 | /* upload all */ | ||
520 | saa7146_write(dev, GPIO_CTRL, 0x000000); | ||
521 | |||
522 | tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); | ||
523 | |||
524 | /* frontend power on */ | ||
525 | if (bi->type != BUDGET_FS_ACTIVY) | ||
526 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); | ||
527 | |||
528 | if ((ret = budget_register(budget)) == 0) | ||
529 | return 0; /* Everything OK */ | ||
530 | |||
531 | /* An error occurred, cleanup resources */ | ||
532 | saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); | ||
533 | |||
534 | err_del_i2c: | ||
535 | i2c_del_adapter(&budget->i2c_adap); | ||
536 | |||
537 | err_dvb_unregister: | ||
538 | dvb_unregister_adapter(&budget->dvb_adapter); | ||
539 | |||
540 | return ret; | ||
541 | } | ||
542 | |||
543 | void ttpci_budget_init_hooks(struct budget *budget) | ||
544 | { | ||
545 | if (budget->dvb_frontend && !budget->read_fe_status) { | ||
546 | budget->read_fe_status = budget->dvb_frontend->ops.read_status; | ||
547 | budget->dvb_frontend->ops.read_status = budget_read_fe_status; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | int ttpci_budget_deinit(struct budget *budget) | ||
552 | { | ||
553 | struct saa7146_dev *dev = budget->dev; | ||
554 | |||
555 | dprintk(2, "budget: %p\n", budget); | ||
556 | |||
557 | budget_unregister(budget); | ||
558 | |||
559 | tasklet_kill(&budget->vpe_tasklet); | ||
560 | |||
561 | saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); | ||
562 | |||
563 | i2c_del_adapter(&budget->i2c_adap); | ||
564 | |||
565 | dvb_unregister_adapter(&budget->dvb_adapter); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr) | ||
571 | { | ||
572 | struct budget *budget = (struct budget *) dev->ext_priv; | ||
573 | |||
574 | dprintk(8, "dev: %p, budget: %p\n", dev, budget); | ||
575 | |||
576 | if (*isr & MASK_10) | ||
577 | tasklet_schedule(&budget->vpe_tasklet); | ||
578 | } | ||
579 | |||
580 | void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port) | ||
581 | { | ||
582 | struct budget *budget = (struct budget *) dev->ext_priv; | ||
583 | |||
584 | spin_lock(&budget->feedlock); | ||
585 | budget->video_port = video_port; | ||
586 | if (budget->feeding) { | ||
587 | stop_ts_capture(budget); | ||
588 | start_ts_capture(budget); | ||
589 | } | ||
590 | spin_unlock(&budget->feedlock); | ||
591 | } | ||
592 | |||
593 | EXPORT_SYMBOL_GPL(ttpci_budget_debiread); | ||
594 | EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); | ||
595 | EXPORT_SYMBOL_GPL(ttpci_budget_init); | ||
596 | EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks); | ||
597 | EXPORT_SYMBOL_GPL(ttpci_budget_deinit); | ||
598 | EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); | ||
599 | EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); | ||
600 | EXPORT_SYMBOL_GPL(budget_debug); | ||
601 | |||
602 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c deleted file mode 100644 index 2cb35c23d2ac..000000000000 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ /dev/null | |||
@@ -1,680 +0,0 @@ | |||
1 | /* | ||
2 | * budget-patch.c: driver for Budget Patch, | ||
3 | * hardware modification of DVB-S cards enabling full TS | ||
4 | * | ||
5 | * Written by Emard <emard@softhome.net> | ||
6 | * | ||
7 | * Original idea by Roberto Deza <rdeza@unav.es> | ||
8 | * | ||
9 | * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic | ||
10 | * and Metzlerbros | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
27 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
28 | * | ||
29 | * | ||
30 | * the project's page is at http://www.linuxtv.org/ | ||
31 | */ | ||
32 | |||
33 | #include "av7110.h" | ||
34 | #include "av7110_hw.h" | ||
35 | #include "budget.h" | ||
36 | #include "stv0299.h" | ||
37 | #include "ves1x93.h" | ||
38 | #include "tda8083.h" | ||
39 | |||
40 | #include "bsru6.h" | ||
41 | |||
42 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
43 | |||
44 | #define budget_patch budget | ||
45 | |||
46 | static struct saa7146_extension budget_extension; | ||
47 | |||
48 | MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH); | ||
49 | //MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC); | ||
50 | |||
51 | static struct pci_device_id pci_tbl[] = { | ||
52 | MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000), | ||
53 | // MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), | ||
54 | { | ||
55 | .vendor = 0, | ||
56 | } | ||
57 | }; | ||
58 | |||
59 | /* those lines are for budget-patch to be tried | ||
60 | ** on a true budget card and observe the | ||
61 | ** behaviour of VSYNC generated by rps1. | ||
62 | ** this code was shamelessly copy/pasted from budget.c | ||
63 | */ | ||
64 | static void gpio_Set22K (struct budget *budget, int state) | ||
65 | { | ||
66 | struct saa7146_dev *dev=budget->dev; | ||
67 | dprintk(2, "budget: %p\n", budget); | ||
68 | saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); | ||
69 | } | ||
70 | |||
71 | /* Diseqc functions only for TT Budget card */ | ||
72 | /* taken from the Skyvision DVB driver by | ||
73 | Ralph Metzler <rjkm@metzlerbros.de> */ | ||
74 | |||
75 | static void DiseqcSendBit (struct budget *budget, int data) | ||
76 | { | ||
77 | struct saa7146_dev *dev=budget->dev; | ||
78 | dprintk(2, "budget: %p\n", budget); | ||
79 | |||
80 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); | ||
81 | udelay(data ? 500 : 1000); | ||
82 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
83 | udelay(data ? 1000 : 500); | ||
84 | } | ||
85 | |||
86 | static void DiseqcSendByte (struct budget *budget, int data) | ||
87 | { | ||
88 | int i, par=1, d; | ||
89 | |||
90 | dprintk(2, "budget: %p\n", budget); | ||
91 | |||
92 | for (i=7; i>=0; i--) { | ||
93 | d = (data>>i)&1; | ||
94 | par ^= d; | ||
95 | DiseqcSendBit(budget, d); | ||
96 | } | ||
97 | |||
98 | DiseqcSendBit(budget, par); | ||
99 | } | ||
100 | |||
101 | static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) | ||
102 | { | ||
103 | struct saa7146_dev *dev=budget->dev; | ||
104 | int i; | ||
105 | |||
106 | dprintk(2, "budget: %p\n", budget); | ||
107 | |||
108 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
109 | mdelay(16); | ||
110 | |||
111 | for (i=0; i<len; i++) | ||
112 | DiseqcSendByte(budget, msg[i]); | ||
113 | |||
114 | mdelay(16); | ||
115 | |||
116 | if (burst!=-1) { | ||
117 | if (burst) | ||
118 | DiseqcSendByte(budget, 0xff); | ||
119 | else { | ||
120 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); | ||
121 | mdelay(12); | ||
122 | udelay(500); | ||
123 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
124 | } | ||
125 | msleep(20); | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /* shamelessly copy/pasted from budget.c | ||
132 | */ | ||
133 | static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
134 | { | ||
135 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
136 | |||
137 | switch (tone) { | ||
138 | case SEC_TONE_ON: | ||
139 | gpio_Set22K (budget, 1); | ||
140 | break; | ||
141 | |||
142 | case SEC_TONE_OFF: | ||
143 | gpio_Set22K (budget, 0); | ||
144 | break; | ||
145 | |||
146 | default: | ||
147 | return -EINVAL; | ||
148 | } | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) | ||
154 | { | ||
155 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
156 | |||
157 | SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | ||
163 | { | ||
164 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
165 | |||
166 | SendDiSEqCMsg (budget, 0, NULL, minicmd); | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length) | ||
172 | { | ||
173 | int i; | ||
174 | |||
175 | dprintk(2, "budget: %p\n", budget); | ||
176 | |||
177 | for (i = 2; i < length; i++) | ||
178 | { | ||
179 | ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0); | ||
180 | msleep(5); | ||
181 | } | ||
182 | if (length) | ||
183 | ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0); | ||
184 | else | ||
185 | ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0); | ||
186 | msleep(5); | ||
187 | ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0); | ||
188 | msleep(5); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static void av7110_set22k(struct budget_patch *budget, int state) | ||
193 | { | ||
194 | u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0}; | ||
195 | |||
196 | dprintk(2, "budget: %p\n", budget); | ||
197 | budget_av7110_send_fw_cmd(budget, buf, 2); | ||
198 | } | ||
199 | |||
200 | static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst) | ||
201 | { | ||
202 | int i; | ||
203 | u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC), | ||
204 | 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
205 | |||
206 | dprintk(2, "budget: %p\n", budget); | ||
207 | |||
208 | if (len>10) | ||
209 | len=10; | ||
210 | |||
211 | buf[1] = len+2; | ||
212 | buf[2] = len; | ||
213 | |||
214 | if (burst != -1) | ||
215 | buf[3]=burst ? 0x01 : 0x00; | ||
216 | else | ||
217 | buf[3]=0xffff; | ||
218 | |||
219 | for (i=0; i<len; i++) | ||
220 | buf[i+4]=msg[i]; | ||
221 | |||
222 | budget_av7110_send_fw_cmd(budget, buf, 18); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
227 | { | ||
228 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | ||
229 | |||
230 | switch (tone) { | ||
231 | case SEC_TONE_ON: | ||
232 | av7110_set22k (budget, 1); | ||
233 | break; | ||
234 | |||
235 | case SEC_TONE_OFF: | ||
236 | av7110_set22k (budget, 0); | ||
237 | break; | ||
238 | |||
239 | default: | ||
240 | return -EINVAL; | ||
241 | } | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) | ||
247 | { | ||
248 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | ||
249 | |||
250 | av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | ||
256 | { | ||
257 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | ||
258 | |||
259 | av7110_send_diseqc_msg (budget, 0, NULL, minicmd); | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) | ||
265 | { | ||
266 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
267 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | ||
268 | u8 pwr = 0; | ||
269 | u8 buf[4]; | ||
270 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
271 | u32 div = (p->frequency + 479500) / 125; | ||
272 | |||
273 | if (p->frequency > 2000000) | ||
274 | pwr = 3; | ||
275 | else if (p->frequency > 1800000) | ||
276 | pwr = 2; | ||
277 | else if (p->frequency > 1600000) | ||
278 | pwr = 1; | ||
279 | else if (p->frequency > 1200000) | ||
280 | pwr = 0; | ||
281 | else if (p->frequency >= 1100000) | ||
282 | pwr = 1; | ||
283 | else pwr = 2; | ||
284 | |||
285 | buf[0] = (div >> 8) & 0x7f; | ||
286 | buf[1] = div & 0xff; | ||
287 | buf[2] = ((div & 0x18000) >> 10) | 0x95; | ||
288 | buf[3] = (pwr << 6) | 0x30; | ||
289 | |||
290 | // NOTE: since we're using a prescaler of 2, we set the | ||
291 | // divisor frequency to 62.5kHz and divide by 125 above | ||
292 | |||
293 | if (fe->ops.i2c_gate_ctrl) | ||
294 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
295 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) | ||
296 | return -EIO; | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static struct ves1x93_config alps_bsrv2_config = { | ||
301 | .demod_address = 0x08, | ||
302 | .xin = 90100000UL, | ||
303 | .invert_pwm = 0, | ||
304 | }; | ||
305 | |||
306 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) | ||
307 | { | ||
308 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
309 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | ||
310 | u32 div; | ||
311 | u8 data[4]; | ||
312 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
313 | |||
314 | div = p->frequency / 125; | ||
315 | data[0] = (div >> 8) & 0x7f; | ||
316 | data[1] = div & 0xff; | ||
317 | data[2] = 0x8e; | ||
318 | data[3] = 0x00; | ||
319 | |||
320 | if (fe->ops.i2c_gate_ctrl) | ||
321 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
322 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) | ||
323 | return -EIO; | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static struct tda8083_config grundig_29504_451_config = { | ||
328 | .demod_address = 0x68, | ||
329 | }; | ||
330 | |||
331 | static void frontend_init(struct budget_patch* budget) | ||
332 | { | ||
333 | switch(budget->dev->pci->subsystem_device) { | ||
334 | case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X | ||
335 | case 0x1013: // SATELCO Multimedia PCI | ||
336 | |||
337 | // try the ALPS BSRV2 first of all | ||
338 | budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap); | ||
339 | if (budget->dvb_frontend) { | ||
340 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; | ||
341 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; | ||
342 | budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst; | ||
343 | budget->dvb_frontend->ops.set_tone = budget_patch_set_tone; | ||
344 | break; | ||
345 | } | ||
346 | |||
347 | // try the ALPS BSRU6 now | ||
348 | budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); | ||
349 | if (budget->dvb_frontend) { | ||
350 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | ||
351 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; | ||
352 | |||
353 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | ||
354 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
355 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
356 | break; | ||
357 | } | ||
358 | |||
359 | // Try the grundig 29504-451 | ||
360 | budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap); | ||
361 | if (budget->dvb_frontend) { | ||
362 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; | ||
363 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | ||
364 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
365 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
366 | break; | ||
367 | } | ||
368 | break; | ||
369 | } | ||
370 | |||
371 | if (budget->dvb_frontend == NULL) { | ||
372 | printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", | ||
373 | budget->dev->pci->vendor, | ||
374 | budget->dev->pci->device, | ||
375 | budget->dev->pci->subsystem_vendor, | ||
376 | budget->dev->pci->subsystem_device); | ||
377 | } else { | ||
378 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { | ||
379 | printk("budget-av: Frontend registration failed!\n"); | ||
380 | dvb_frontend_detach(budget->dvb_frontend); | ||
381 | budget->dvb_frontend = NULL; | ||
382 | } | ||
383 | } | ||
384 | } | ||
385 | |||
386 | /* written by Emard */ | ||
387 | static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) | ||
388 | { | ||
389 | struct budget_patch *budget; | ||
390 | int err; | ||
391 | int count = 0; | ||
392 | int detected = 0; | ||
393 | |||
394 | #define PATCH_RESET 0 | ||
395 | #define RPS_IRQ 0 | ||
396 | #define HPS_SETUP 0 | ||
397 | #if PATCH_RESET | ||
398 | saa7146_write(dev, MC1, MASK_31); | ||
399 | msleep(40); | ||
400 | #endif | ||
401 | #if HPS_SETUP | ||
402 | // initialize registers. Better to have it like this | ||
403 | // than leaving something unconfigured | ||
404 | saa7146_write(dev, DD1_STREAM_B, 0); | ||
405 | // port B VSYNC at rising edge | ||
406 | saa7146_write(dev, DD1_INIT, 0x00000200); // have this in budget-core too! | ||
407 | saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI | ||
408 | |||
409 | // debi config | ||
410 | // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18); | ||
411 | |||
412 | // zero all HPS registers | ||
413 | saa7146_write(dev, HPS_H_PRESCALE, 0); // r68 | ||
414 | saa7146_write(dev, HPS_H_SCALE, 0); // r6c | ||
415 | saa7146_write(dev, BCS_CTRL, 0); // r70 | ||
416 | saa7146_write(dev, HPS_V_SCALE, 0); // r60 | ||
417 | saa7146_write(dev, HPS_V_GAIN, 0); // r64 | ||
418 | saa7146_write(dev, CHROMA_KEY_RANGE, 0); // r74 | ||
419 | saa7146_write(dev, CLIP_FORMAT_CTRL, 0); // r78 | ||
420 | // Set HPS prescaler for port B input | ||
421 | saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) ); | ||
422 | saa7146_write(dev, MC2, | ||
423 | 0 * (MASK_08 | MASK_24) | // BRS control | ||
424 | 0 * (MASK_09 | MASK_25) | // a | ||
425 | 0 * (MASK_10 | MASK_26) | // b | ||
426 | 1 * (MASK_06 | MASK_22) | // HPS_CTRL1 | ||
427 | 1 * (MASK_05 | MASK_21) | // HPS_CTRL2 | ||
428 | 0 * (MASK_01 | MASK_15) // DEBI | ||
429 | ); | ||
430 | #endif | ||
431 | // Disable RPS1 and RPS0 | ||
432 | saa7146_write(dev, MC1, ( MASK_29 | MASK_28)); | ||
433 | // RPS1 timeout disable | ||
434 | saa7146_write(dev, RPS_TOV1, 0); | ||
435 | |||
436 | // code for autodetection | ||
437 | // will wait for VBI_B event (vertical blank at port B) | ||
438 | // and will reset GPIO3 after VBI_B is detected. | ||
439 | // (GPIO3 should be raised high by CPU to | ||
440 | // test if GPIO3 will generate vertical blank signal | ||
441 | // in budget patch GPIO3 is connected to VSYNC_B | ||
442 | count = 0; | ||
443 | #if 0 | ||
444 | WRITE_RPS1(CMD_UPLOAD | | ||
445 | MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ); | ||
446 | #endif | ||
447 | WRITE_RPS1(CMD_PAUSE | EVT_VBI_B); | ||
448 | WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); | ||
449 | WRITE_RPS1(GPIO3_MSK); | ||
450 | WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); | ||
451 | #if RPS_IRQ | ||
452 | // issue RPS1 interrupt to increment counter | ||
453 | WRITE_RPS1(CMD_INTERRUPT); | ||
454 | // at least a NOP is neede between two interrupts | ||
455 | WRITE_RPS1(CMD_NOP); | ||
456 | // interrupt again | ||
457 | WRITE_RPS1(CMD_INTERRUPT); | ||
458 | #endif | ||
459 | WRITE_RPS1(CMD_STOP); | ||
460 | |||
461 | #if RPS_IRQ | ||
462 | // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) | ||
463 | // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled | ||
464 | // use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called | ||
465 | saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); | ||
466 | // set event counter 1 threshold to maximum allowed value (rEC p55) | ||
467 | saa7146_write(dev, ECT1R, 0x3fff ); | ||
468 | #endif | ||
469 | // Fix VSYNC level | ||
470 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
471 | // Set RPS1 Address register to point to RPS code (r108 p42) | ||
472 | saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); | ||
473 | // Enable RPS1, (rFC p33) | ||
474 | saa7146_write(dev, MC1, (MASK_13 | MASK_29 )); | ||
475 | |||
476 | |||
477 | mdelay(50); | ||
478 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); | ||
479 | mdelay(150); | ||
480 | |||
481 | |||
482 | if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) | ||
483 | detected = 1; | ||
484 | |||
485 | #if RPS_IRQ | ||
486 | printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff ); | ||
487 | #endif | ||
488 | // Disable RPS1 | ||
489 | saa7146_write(dev, MC1, ( MASK_29 )); | ||
490 | |||
491 | if(detected == 0) | ||
492 | printk("budget-patch not detected or saa7146 in non-default state.\n" | ||
493 | "try enabling ressetting of 7146 with MASK_31 in MC1 register\n"); | ||
494 | |||
495 | else | ||
496 | printk("BUDGET-PATCH DETECTED.\n"); | ||
497 | |||
498 | |||
499 | /* OLD (Original design by Roberto Deza): | ||
500 | ** This code will setup the SAA7146_RPS1 to generate a square | ||
501 | ** wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of | ||
502 | ** TS_WIDTH packets) has been acquired on SAA7146_D1B video port; | ||
503 | ** then, this GPIO3 output which is connected to the D1B_VSYNC | ||
504 | ** input, will trigger the acquisition of the alternate field | ||
505 | ** and so on. | ||
506 | ** Currently, the TT_budget / WinTV_Nova cards have two ICs | ||
507 | ** (74HCT4040, LVC74) for the generation of this VSYNC signal, | ||
508 | ** which seems that can be done perfectly without this :-)). | ||
509 | */ | ||
510 | |||
511 | /* New design (By Emard) | ||
512 | ** this rps1 code will copy internal HS event to GPIO3 pin. | ||
513 | ** GPIO3 is in budget-patch hardware connected to port B VSYNC | ||
514 | |||
515 | ** HS is an internal event of 7146, accessible with RPS | ||
516 | ** and temporarily raised high every n lines | ||
517 | ** (n in defined in the RPS_THRESH1 counter threshold) | ||
518 | ** I think HS is raised high on the beginning of the n-th line | ||
519 | ** and remains high until this n-th line that triggered | ||
520 | ** it is completely received. When the reception of n-th line | ||
521 | ** ends, HS is lowered. | ||
522 | |||
523 | ** To transmit data over DMA, 7146 needs changing state at | ||
524 | ** port B VSYNC pin. Any changing of port B VSYNC will | ||
525 | ** cause some DMA data transfer, with more or less packets loss. | ||
526 | ** It depends on the phase and frequency of VSYNC and | ||
527 | ** the way of 7146 is instructed to trigger on port B (defined | ||
528 | ** in DD1_INIT register, 3rd nibble from the right valid | ||
529 | ** numbers are 0-7, see datasheet) | ||
530 | ** | ||
531 | ** The correct triggering can minimize packet loss, | ||
532 | ** dvbtraffic should give this stable bandwidths: | ||
533 | ** 22k transponder = 33814 kbit/s | ||
534 | ** 27.5k transponder = 38045 kbit/s | ||
535 | ** by experiment it is found that the best results | ||
536 | ** (stable bandwidths and almost no packet loss) | ||
537 | ** are obtained using DD1_INIT triggering number 2 | ||
538 | ** (Va at rising edge of VS Fa = HS x VS-failing forced toggle) | ||
539 | ** and a VSYNC phase that occurs in the middle of DMA transfer | ||
540 | ** (about byte 188*512=96256 in the DMA window). | ||
541 | ** | ||
542 | ** Phase of HS is still not clear to me how to control, | ||
543 | ** It just happens to be so. It can be seen if one enables | ||
544 | ** RPS_IRQ and print Event Counter 1 in vpeirq(). Every | ||
545 | ** time RPS_INTERRUPT is called, the Event Counter 1 will | ||
546 | ** increment. That's how the 7146 is programmed to do event | ||
547 | ** counting in this budget-patch.c | ||
548 | ** I *think* HPS setting has something to do with the phase | ||
549 | ** of HS but I can't be 100% sure in that. | ||
550 | |||
551 | ** hardware debug note: a working budget card (including budget patch) | ||
552 | ** with vpeirq() interrupt setup in mode "0x90" (every 64K) will | ||
553 | ** generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes | ||
554 | ** and that means 3*25=75 Hz of interrupt frequency, as seen by | ||
555 | ** watch cat /proc/interrupts | ||
556 | ** | ||
557 | ** If this frequency is 3x lower (and data received in the DMA | ||
558 | ** buffer don't start with 0x47, but in the middle of packets, | ||
559 | ** whose lengths appear to be like 188 292 188 104 etc. | ||
560 | ** this means VSYNC line is not connected in the hardware. | ||
561 | ** (check soldering pcb and pins) | ||
562 | ** The same behaviour of missing VSYNC can be duplicated on budget | ||
563 | ** cards, by setting DD1_INIT trigger mode 7 in 3rd nibble. | ||
564 | */ | ||
565 | |||
566 | // Setup RPS1 "program" (p35) | ||
567 | count = 0; | ||
568 | |||
569 | |||
570 | // Wait Source Line Counter Threshold (p36) | ||
571 | WRITE_RPS1(CMD_PAUSE | EVT_HS); | ||
572 | // Set GPIO3=1 (p42) | ||
573 | WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); | ||
574 | WRITE_RPS1(GPIO3_MSK); | ||
575 | WRITE_RPS1(SAA7146_GPIO_OUTHI<<24); | ||
576 | #if RPS_IRQ | ||
577 | // issue RPS1 interrupt | ||
578 | WRITE_RPS1(CMD_INTERRUPT); | ||
579 | #endif | ||
580 | // Wait reset Source Line Counter Threshold (p36) | ||
581 | WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS); | ||
582 | // Set GPIO3=0 (p42) | ||
583 | WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); | ||
584 | WRITE_RPS1(GPIO3_MSK); | ||
585 | WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); | ||
586 | #if RPS_IRQ | ||
587 | // issue RPS1 interrupt | ||
588 | WRITE_RPS1(CMD_INTERRUPT); | ||
589 | #endif | ||
590 | // Jump to begin of RPS program (p37) | ||
591 | WRITE_RPS1(CMD_JUMP); | ||
592 | WRITE_RPS1(dev->d_rps1.dma_handle); | ||
593 | |||
594 | // Fix VSYNC level | ||
595 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
596 | // Set RPS1 Address register to point to RPS code (r108 p42) | ||
597 | saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); | ||
598 | |||
599 | if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL))) | ||
600 | return -ENOMEM; | ||
601 | |||
602 | dprintk(2, "budget: %p\n", budget); | ||
603 | |||
604 | err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); | ||
605 | if (err) { | ||
606 | kfree(budget); | ||
607 | return err; | ||
608 | } | ||
609 | |||
610 | // Set Source Line Counter Threshold, using BRS (rCC p43) | ||
611 | // It generates HS event every TS_HEIGHT lines | ||
612 | // this is related to TS_WIDTH set in register | ||
613 | // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE | ||
614 | // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188 | ||
615 | //,then RPS_THRESH1 | ||
616 | // should be set to trigger every TS_HEIGHT (512) lines. | ||
617 | // | ||
618 | saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 ); | ||
619 | |||
620 | // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 ); | ||
621 | // Enable RPS1 (rFC p33) | ||
622 | saa7146_write(dev, MC1, (MASK_13 | MASK_29)); | ||
623 | |||
624 | |||
625 | dev->ext_priv = budget; | ||
626 | |||
627 | budget->dvb_adapter.priv = budget; | ||
628 | frontend_init(budget); | ||
629 | |||
630 | ttpci_budget_init_hooks(budget); | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static int budget_patch_detach (struct saa7146_dev* dev) | ||
636 | { | ||
637 | struct budget_patch *budget = (struct budget_patch*) dev->ext_priv; | ||
638 | int err; | ||
639 | |||
640 | if (budget->dvb_frontend) { | ||
641 | dvb_unregister_frontend(budget->dvb_frontend); | ||
642 | dvb_frontend_detach(budget->dvb_frontend); | ||
643 | } | ||
644 | err = ttpci_budget_deinit (budget); | ||
645 | |||
646 | kfree (budget); | ||
647 | |||
648 | return err; | ||
649 | } | ||
650 | |||
651 | static int __init budget_patch_init(void) | ||
652 | { | ||
653 | return saa7146_register_extension(&budget_extension); | ||
654 | } | ||
655 | |||
656 | static void __exit budget_patch_exit(void) | ||
657 | { | ||
658 | saa7146_unregister_extension(&budget_extension); | ||
659 | } | ||
660 | |||
661 | static struct saa7146_extension budget_extension = { | ||
662 | .name = "budget_patch dvb", | ||
663 | .flags = 0, | ||
664 | |||
665 | .module = THIS_MODULE, | ||
666 | .pci_tbl = pci_tbl, | ||
667 | .attach = budget_patch_attach, | ||
668 | .detach = budget_patch_detach, | ||
669 | |||
670 | .irq_mask = MASK_10, | ||
671 | .irq_func = ttpci_budget_irq10_handler, | ||
672 | }; | ||
673 | |||
674 | module_init(budget_patch_init); | ||
675 | module_exit(budget_patch_exit); | ||
676 | |||
677 | MODULE_LICENSE("GPL"); | ||
678 | MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others"); | ||
679 | MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 " | ||
680 | "based so-called Budget Patch cards"); | ||
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c deleted file mode 100644 index 7e6e43ae5c51..000000000000 --- a/drivers/media/dvb/ttpci/budget.c +++ /dev/null | |||
@@ -1,871 +0,0 @@ | |||
1 | /* | ||
2 | * budget.c: driver for the SAA7146 based Budget DVB cards | ||
3 | * | ||
4 | * Compiled from various sources by Michael Hunold <michael@mihu.de> | ||
5 | * | ||
6 | * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * | ||
8 | * Copyright (C) 1999-2002 Ralph Metzler | ||
9 | * & Marcus Metzler for convergence integrated media GmbH | ||
10 | * | ||
11 | * 26feb2004 Support for FS Activy Card (Grundig tuner) by | ||
12 | * Michael Dreher <michael@5dot1.de>, | ||
13 | * Oliver Endriss <o.endriss@gmx.de> and | ||
14 | * Andreas 'randy' Weinberger | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License | ||
18 | * as published by the Free Software Foundation; either version 2 | ||
19 | * of the License, or (at your option) any later version. | ||
20 | * | ||
21 | * | ||
22 | * This program is distributed in the hope that it will be useful, | ||
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
25 | * GNU General Public License for more details. | ||
26 | * | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program; if not, write to the Free Software | ||
30 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
31 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
32 | * | ||
33 | * | ||
34 | * the project's page is at http://www.linuxtv.org/ | ||
35 | */ | ||
36 | |||
37 | #include "budget.h" | ||
38 | #include "stv0299.h" | ||
39 | #include "ves1x93.h" | ||
40 | #include "ves1820.h" | ||
41 | #include "l64781.h" | ||
42 | #include "tda8083.h" | ||
43 | #include "s5h1420.h" | ||
44 | #include "tda10086.h" | ||
45 | #include "tda826x.h" | ||
46 | #include "lnbp21.h" | ||
47 | #include "bsru6.h" | ||
48 | #include "bsbe1.h" | ||
49 | #include "tdhd1.h" | ||
50 | #include "stv6110x.h" | ||
51 | #include "stv090x.h" | ||
52 | #include "isl6423.h" | ||
53 | #include "lnbh24.h" | ||
54 | |||
55 | |||
56 | static int diseqc_method; | ||
57 | module_param(diseqc_method, int, 0444); | ||
58 | MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); | ||
59 | |||
60 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
61 | |||
62 | static void Set22K (struct budget *budget, int state) | ||
63 | { | ||
64 | struct saa7146_dev *dev=budget->dev; | ||
65 | dprintk(2, "budget: %p\n", budget); | ||
66 | saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); | ||
67 | } | ||
68 | |||
69 | /* Diseqc functions only for TT Budget card */ | ||
70 | /* taken from the Skyvision DVB driver by | ||
71 | Ralph Metzler <rjkm@metzlerbros.de> */ | ||
72 | |||
73 | static void DiseqcSendBit (struct budget *budget, int data) | ||
74 | { | ||
75 | struct saa7146_dev *dev=budget->dev; | ||
76 | dprintk(2, "budget: %p\n", budget); | ||
77 | |||
78 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); | ||
79 | udelay(data ? 500 : 1000); | ||
80 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
81 | udelay(data ? 1000 : 500); | ||
82 | } | ||
83 | |||
84 | static void DiseqcSendByte (struct budget *budget, int data) | ||
85 | { | ||
86 | int i, par=1, d; | ||
87 | |||
88 | dprintk(2, "budget: %p\n", budget); | ||
89 | |||
90 | for (i=7; i>=0; i--) { | ||
91 | d = (data>>i)&1; | ||
92 | par ^= d; | ||
93 | DiseqcSendBit(budget, d); | ||
94 | } | ||
95 | |||
96 | DiseqcSendBit(budget, par); | ||
97 | } | ||
98 | |||
99 | static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) | ||
100 | { | ||
101 | struct saa7146_dev *dev=budget->dev; | ||
102 | int i; | ||
103 | |||
104 | dprintk(2, "budget: %p\n", budget); | ||
105 | |||
106 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
107 | mdelay(16); | ||
108 | |||
109 | for (i=0; i<len; i++) | ||
110 | DiseqcSendByte(budget, msg[i]); | ||
111 | |||
112 | mdelay(16); | ||
113 | |||
114 | if (burst!=-1) { | ||
115 | if (burst) | ||
116 | DiseqcSendByte(budget, 0xff); | ||
117 | else { | ||
118 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); | ||
119 | mdelay(12); | ||
120 | udelay(500); | ||
121 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); | ||
122 | } | ||
123 | msleep(20); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Routines for the Fujitsu Siemens Activy budget card | ||
131 | * 22 kHz tone and DiSEqC are handled by the frontend. | ||
132 | * Voltage must be set here. | ||
133 | * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL | ||
134 | */ | ||
135 | static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) | ||
136 | { | ||
137 | struct saa7146_dev *dev=budget->dev; | ||
138 | |||
139 | dprintk(2, "budget: %p\n", budget); | ||
140 | |||
141 | switch (voltage) { | ||
142 | case SEC_VOLTAGE_13: | ||
143 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
144 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); | ||
145 | break; | ||
146 | case SEC_VOLTAGE_18: | ||
147 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
148 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); | ||
149 | break; | ||
150 | case SEC_VOLTAGE_OFF: | ||
151 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); | ||
152 | break; | ||
153 | default: | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
161 | { | ||
162 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
163 | |||
164 | return SetVoltage_Activy (budget, voltage); | ||
165 | } | ||
166 | |||
167 | static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
168 | { | ||
169 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
170 | |||
171 | switch (tone) { | ||
172 | case SEC_TONE_ON: | ||
173 | Set22K (budget, 1); | ||
174 | break; | ||
175 | |||
176 | case SEC_TONE_OFF: | ||
177 | Set22K (budget, 0); | ||
178 | break; | ||
179 | |||
180 | default: | ||
181 | return -EINVAL; | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) | ||
188 | { | ||
189 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
190 | |||
191 | SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | ||
197 | { | ||
198 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
199 | |||
200 | SendDiSEqCMsg (budget, 0, NULL, minicmd); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) | ||
206 | { | ||
207 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
208 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
209 | u8 pwr = 0; | ||
210 | u8 buf[4]; | ||
211 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
212 | u32 div = (c->frequency + 479500) / 125; | ||
213 | |||
214 | if (c->frequency > 2000000) | ||
215 | pwr = 3; | ||
216 | else if (c->frequency > 1800000) | ||
217 | pwr = 2; | ||
218 | else if (c->frequency > 1600000) | ||
219 | pwr = 1; | ||
220 | else if (c->frequency > 1200000) | ||
221 | pwr = 0; | ||
222 | else if (c->frequency >= 1100000) | ||
223 | pwr = 1; | ||
224 | else pwr = 2; | ||
225 | |||
226 | buf[0] = (div >> 8) & 0x7f; | ||
227 | buf[1] = div & 0xff; | ||
228 | buf[2] = ((div & 0x18000) >> 10) | 0x95; | ||
229 | buf[3] = (pwr << 6) | 0x30; | ||
230 | |||
231 | // NOTE: since we're using a prescaler of 2, we set the | ||
232 | // divisor frequency to 62.5kHz and divide by 125 above | ||
233 | |||
234 | if (fe->ops.i2c_gate_ctrl) | ||
235 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
236 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static struct ves1x93_config alps_bsrv2_config = | ||
241 | { | ||
242 | .demod_address = 0x08, | ||
243 | .xin = 90100000UL, | ||
244 | .invert_pwm = 0, | ||
245 | }; | ||
246 | |||
247 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) | ||
248 | { | ||
249 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
250 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
251 | u32 div; | ||
252 | u8 data[4]; | ||
253 | struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
254 | |||
255 | div = (c->frequency + 35937500 + 31250) / 62500; | ||
256 | |||
257 | data[0] = (div >> 8) & 0x7f; | ||
258 | data[1] = div & 0xff; | ||
259 | data[2] = 0x85 | ((div >> 10) & 0x60); | ||
260 | data[3] = (c->frequency < 174000000 ? 0x88 : c->frequency < 470000000 ? 0x84 : 0x81); | ||
261 | |||
262 | if (fe->ops.i2c_gate_ctrl) | ||
263 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
264 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static struct ves1820_config alps_tdbe2_config = { | ||
269 | .demod_address = 0x09, | ||
270 | .xin = 57840000UL, | ||
271 | .invert = 1, | ||
272 | .selagc = VES1820_SELAGC_SIGNAMPERR, | ||
273 | }; | ||
274 | |||
275 | static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe) | ||
276 | { | ||
277 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
278 | struct budget *budget = fe->dvb->priv; | ||
279 | u8 *tuner_addr = fe->tuner_priv; | ||
280 | u32 div; | ||
281 | u8 cfg, cpump, band_select; | ||
282 | u8 data[4]; | ||
283 | struct i2c_msg msg = { .flags = 0, .buf = data, .len = sizeof(data) }; | ||
284 | |||
285 | if (tuner_addr) | ||
286 | msg.addr = *tuner_addr; | ||
287 | else | ||
288 | msg.addr = 0x61; | ||
289 | |||
290 | div = (36125000 + c->frequency) / 166666; | ||
291 | |||
292 | cfg = 0x88; | ||
293 | |||
294 | if (c->frequency < 175000000) | ||
295 | cpump = 2; | ||
296 | else if (c->frequency < 390000000) | ||
297 | cpump = 1; | ||
298 | else if (c->frequency < 470000000) | ||
299 | cpump = 2; | ||
300 | else if (c->frequency < 750000000) | ||
301 | cpump = 1; | ||
302 | else | ||
303 | cpump = 3; | ||
304 | |||
305 | if (c->frequency < 175000000) | ||
306 | band_select = 0x0e; | ||
307 | else if (c->frequency < 470000000) | ||
308 | band_select = 0x05; | ||
309 | else | ||
310 | band_select = 0x03; | ||
311 | |||
312 | data[0] = (div >> 8) & 0x7f; | ||
313 | data[1] = div & 0xff; | ||
314 | data[2] = ((div >> 10) & 0x60) | cfg; | ||
315 | data[3] = (cpump << 6) | band_select; | ||
316 | |||
317 | if (fe->ops.i2c_gate_ctrl) | ||
318 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
319 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static struct l64781_config grundig_29504_401_config = { | ||
324 | .demod_address = 0x55, | ||
325 | }; | ||
326 | |||
327 | static struct l64781_config grundig_29504_401_config_activy = { | ||
328 | .demod_address = 0x54, | ||
329 | }; | ||
330 | |||
331 | static u8 tuner_address_grundig_29504_401_activy = 0x60; | ||
332 | |||
333 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) | ||
334 | { | ||
335 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
336 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
337 | u32 div; | ||
338 | u8 data[4]; | ||
339 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
340 | |||
341 | div = c->frequency / 125; | ||
342 | data[0] = (div >> 8) & 0x7f; | ||
343 | data[1] = div & 0xff; | ||
344 | data[2] = 0x8e; | ||
345 | data[3] = 0x00; | ||
346 | |||
347 | if (fe->ops.i2c_gate_ctrl) | ||
348 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
349 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static struct tda8083_config grundig_29504_451_config = { | ||
354 | .demod_address = 0x68, | ||
355 | }; | ||
356 | |||
357 | static int s5h1420_tuner_set_params(struct dvb_frontend *fe) | ||
358 | { | ||
359 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
360 | struct budget* budget = (struct budget*) fe->dvb->priv; | ||
361 | u32 div; | ||
362 | u8 data[4]; | ||
363 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
364 | |||
365 | div = c->frequency / 1000; | ||
366 | data[0] = (div >> 8) & 0x7f; | ||
367 | data[1] = div & 0xff; | ||
368 | data[2] = 0xc2; | ||
369 | |||
370 | if (div < 1450) | ||
371 | data[3] = 0x00; | ||
372 | else if (div < 1850) | ||
373 | data[3] = 0x40; | ||
374 | else if (div < 2000) | ||
375 | data[3] = 0x80; | ||
376 | else | ||
377 | data[3] = 0xc0; | ||
378 | |||
379 | if (fe->ops.i2c_gate_ctrl) | ||
380 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
381 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static struct s5h1420_config s5h1420_config = { | ||
387 | .demod_address = 0x53, | ||
388 | .invert = 1, | ||
389 | .cdclk_polarity = 1, | ||
390 | }; | ||
391 | |||
392 | static struct tda10086_config tda10086_config = { | ||
393 | .demod_address = 0x0e, | ||
394 | .invert = 0, | ||
395 | .diseqc_tone = 1, | ||
396 | .xtal_freq = TDA10086_XTAL_16M, | ||
397 | }; | ||
398 | |||
399 | static struct stv0299_config alps_bsru6_config_activy = { | ||
400 | .demod_address = 0x68, | ||
401 | .inittab = alps_bsru6_inittab, | ||
402 | .mclk = 88000000UL, | ||
403 | .invert = 1, | ||
404 | .op0_off = 1, | ||
405 | .min_delay_ms = 100, | ||
406 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
407 | }; | ||
408 | |||
409 | static struct stv0299_config alps_bsbe1_config_activy = { | ||
410 | .demod_address = 0x68, | ||
411 | .inittab = alps_bsbe1_inittab, | ||
412 | .mclk = 88000000UL, | ||
413 | .invert = 1, | ||
414 | .op0_off = 1, | ||
415 | .min_delay_ms = 100, | ||
416 | .set_symbol_rate = alps_bsbe1_set_symbol_rate, | ||
417 | }; | ||
418 | |||
419 | static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name) | ||
420 | { | ||
421 | struct budget *budget = (struct budget *)fe->dvb->priv; | ||
422 | |||
423 | return request_firmware(fw, name, &budget->dev->pci->dev); | ||
424 | } | ||
425 | |||
426 | |||
427 | static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) | ||
428 | { | ||
429 | u8 val; | ||
430 | struct i2c_msg msg[] = { | ||
431 | { .addr = adr, .flags = 0, .buf = ®, .len = 1 }, | ||
432 | { .addr = adr, .flags = I2C_M_RD, .buf = &val, .len = 1 } | ||
433 | }; | ||
434 | |||
435 | return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val; | ||
436 | } | ||
437 | |||
438 | static u8 read_pwm(struct budget* budget) | ||
439 | { | ||
440 | u8 b = 0xff; | ||
441 | u8 pwm; | ||
442 | struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, | ||
443 | { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; | ||
444 | |||
445 | if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) | ||
446 | pwm = 0x48; | ||
447 | |||
448 | return pwm; | ||
449 | } | ||
450 | |||
451 | static struct stv090x_config tt1600_stv090x_config = { | ||
452 | .device = STV0903, | ||
453 | .demod_mode = STV090x_SINGLE, | ||
454 | .clk_mode = STV090x_CLK_EXT, | ||
455 | |||
456 | .xtal = 13500000, | ||
457 | .address = 0x68, | ||
458 | |||
459 | .ts1_mode = STV090x_TSMODE_DVBCI, | ||
460 | .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, | ||
461 | |||
462 | .repeater_level = STV090x_RPTLEVEL_16, | ||
463 | |||
464 | .tuner_init = NULL, | ||
465 | .tuner_sleep = NULL, | ||
466 | .tuner_set_mode = NULL, | ||
467 | .tuner_set_frequency = NULL, | ||
468 | .tuner_get_frequency = NULL, | ||
469 | .tuner_set_bandwidth = NULL, | ||
470 | .tuner_get_bandwidth = NULL, | ||
471 | .tuner_set_bbgain = NULL, | ||
472 | .tuner_get_bbgain = NULL, | ||
473 | .tuner_set_refclk = NULL, | ||
474 | .tuner_get_status = NULL, | ||
475 | }; | ||
476 | |||
477 | static struct stv6110x_config tt1600_stv6110x_config = { | ||
478 | .addr = 0x60, | ||
479 | .refclk = 27000000, | ||
480 | .clk_div = 2, | ||
481 | }; | ||
482 | |||
483 | static struct isl6423_config tt1600_isl6423_config = { | ||
484 | .current_max = SEC_CURRENT_515m, | ||
485 | .curlim = SEC_CURRENT_LIM_ON, | ||
486 | .mod_extern = 1, | ||
487 | .addr = 0x08, | ||
488 | }; | ||
489 | |||
490 | static void frontend_init(struct budget *budget) | ||
491 | { | ||
492 | (void)alps_bsbe1_config; /* avoid warning */ | ||
493 | |||
494 | switch(budget->dev->pci->subsystem_device) { | ||
495 | case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) | ||
496 | case 0x1013: | ||
497 | // try the ALPS BSRV2 first of all | ||
498 | budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap); | ||
499 | if (budget->dvb_frontend) { | ||
500 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; | ||
501 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | ||
502 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
503 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
504 | break; | ||
505 | } | ||
506 | |||
507 | // try the ALPS BSRU6 now | ||
508 | budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); | ||
509 | if (budget->dvb_frontend) { | ||
510 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | ||
511 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; | ||
512 | if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) { | ||
513 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | ||
514 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
515 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
516 | } | ||
517 | break; | ||
518 | } | ||
519 | break; | ||
520 | |||
521 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) | ||
522 | |||
523 | budget->dvb_frontend = dvb_attach(ves1820_attach, &alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); | ||
524 | if (budget->dvb_frontend) { | ||
525 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
526 | break; | ||
527 | } | ||
528 | break; | ||
529 | |||
530 | case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) | ||
531 | |||
532 | budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap); | ||
533 | if (budget->dvb_frontend) { | ||
534 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; | ||
535 | budget->dvb_frontend->tuner_priv = NULL; | ||
536 | break; | ||
537 | } | ||
538 | break; | ||
539 | |||
540 | case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */ | ||
541 | { | ||
542 | int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67); | ||
543 | |||
544 | if (subtype < 0) | ||
545 | break; | ||
546 | /* fixme: find a better way to identify the card */ | ||
547 | if (subtype < 0x36) { | ||
548 | /* assume ALPS BSRU6 */ | ||
549 | budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap); | ||
550 | if (budget->dvb_frontend) { | ||
551 | printk(KERN_INFO "budget: tuner ALPS BSRU6 detected\n"); | ||
552 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | ||
553 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; | ||
554 | budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; | ||
555 | budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
556 | break; | ||
557 | } | ||
558 | } else { | ||
559 | /* assume ALPS BSBE1 */ | ||
560 | /* reset tuner */ | ||
561 | saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTLO); | ||
562 | msleep(50); | ||
563 | saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTHI); | ||
564 | msleep(250); | ||
565 | budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap); | ||
566 | if (budget->dvb_frontend) { | ||
567 | printk(KERN_INFO "budget: tuner ALPS BSBE1 detected\n"); | ||
568 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; | ||
569 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; | ||
570 | budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; | ||
571 | budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
572 | break; | ||
573 | } | ||
574 | } | ||
575 | break; | ||
576 | } | ||
577 | |||
578 | case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) | ||
579 | budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap); | ||
580 | if (budget->dvb_frontend) { | ||
581 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; | ||
582 | budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; | ||
583 | budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
584 | } | ||
585 | break; | ||
586 | |||
587 | case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */ | ||
588 | budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap); | ||
589 | if (budget->dvb_frontend) { | ||
590 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params; | ||
591 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; | ||
592 | } | ||
593 | break; | ||
594 | |||
595 | case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */ | ||
596 | budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap); | ||
597 | if (budget->dvb_frontend) { | ||
598 | budget->dvb_frontend->tuner_priv = &tuner_address_grundig_29504_401_activy; | ||
599 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; | ||
600 | } | ||
601 | break; | ||
602 | |||
603 | case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) | ||
604 | budget->dvb_frontend = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap); | ||
605 | if (budget->dvb_frontend) { | ||
606 | budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; | ||
607 | if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { | ||
608 | printk("%s: No LNBP21 found!\n", __func__); | ||
609 | goto error_out; | ||
610 | } | ||
611 | break; | ||
612 | } | ||
613 | |||
614 | case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262) | ||
615 | // gpio2 is connected to CLB - reset it + leave it high | ||
616 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); | ||
617 | msleep(1); | ||
618 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); | ||
619 | msleep(1); | ||
620 | |||
621 | budget->dvb_frontend = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap); | ||
622 | if (budget->dvb_frontend) { | ||
623 | if (dvb_attach(tda826x_attach, budget->dvb_frontend, 0x60, &budget->i2c_adap, 0) == NULL) | ||
624 | printk("%s: No tda826x found!\n", __func__); | ||
625 | if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { | ||
626 | printk("%s: No LNBP21 found!\n", __func__); | ||
627 | goto error_out; | ||
628 | } | ||
629 | break; | ||
630 | } | ||
631 | |||
632 | case 0x101c: { /* TT S2-1600 */ | ||
633 | struct stv6110x_devctl *ctl; | ||
634 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); | ||
635 | msleep(50); | ||
636 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); | ||
637 | msleep(250); | ||
638 | |||
639 | budget->dvb_frontend = dvb_attach(stv090x_attach, | ||
640 | &tt1600_stv090x_config, | ||
641 | &budget->i2c_adap, | ||
642 | STV090x_DEMODULATOR_0); | ||
643 | |||
644 | if (budget->dvb_frontend) { | ||
645 | |||
646 | ctl = dvb_attach(stv6110x_attach, | ||
647 | budget->dvb_frontend, | ||
648 | &tt1600_stv6110x_config, | ||
649 | &budget->i2c_adap); | ||
650 | |||
651 | if (ctl) { | ||
652 | tt1600_stv090x_config.tuner_init = ctl->tuner_init; | ||
653 | tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep; | ||
654 | tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; | ||
655 | tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; | ||
656 | tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; | ||
657 | tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
658 | tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
659 | tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
660 | tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
661 | tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; | ||
662 | tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; | ||
663 | |||
664 | /* call the init function once to initialize | ||
665 | tuner's clock output divider and demod's | ||
666 | master clock */ | ||
667 | if (budget->dvb_frontend->ops.init) | ||
668 | budget->dvb_frontend->ops.init(budget->dvb_frontend); | ||
669 | |||
670 | if (dvb_attach(isl6423_attach, | ||
671 | budget->dvb_frontend, | ||
672 | &budget->i2c_adap, | ||
673 | &tt1600_isl6423_config) == NULL) { | ||
674 | printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__); | ||
675 | goto error_out; | ||
676 | } | ||
677 | } else { | ||
678 | printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__); | ||
679 | goto error_out; | ||
680 | } | ||
681 | } | ||
682 | } | ||
683 | break; | ||
684 | |||
685 | case 0x1020: { /* Omicom S2 */ | ||
686 | struct stv6110x_devctl *ctl; | ||
687 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); | ||
688 | msleep(50); | ||
689 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); | ||
690 | msleep(250); | ||
691 | |||
692 | budget->dvb_frontend = dvb_attach(stv090x_attach, | ||
693 | &tt1600_stv090x_config, | ||
694 | &budget->i2c_adap, | ||
695 | STV090x_DEMODULATOR_0); | ||
696 | |||
697 | if (budget->dvb_frontend) { | ||
698 | printk(KERN_INFO "budget: Omicom S2 detected\n"); | ||
699 | |||
700 | ctl = dvb_attach(stv6110x_attach, | ||
701 | budget->dvb_frontend, | ||
702 | &tt1600_stv6110x_config, | ||
703 | &budget->i2c_adap); | ||
704 | |||
705 | if (ctl) { | ||
706 | tt1600_stv090x_config.tuner_init = ctl->tuner_init; | ||
707 | tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep; | ||
708 | tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; | ||
709 | tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; | ||
710 | tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; | ||
711 | tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
712 | tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
713 | tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
714 | tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
715 | tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; | ||
716 | tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; | ||
717 | |||
718 | /* call the init function once to initialize | ||
719 | tuner's clock output divider and demod's | ||
720 | master clock */ | ||
721 | if (budget->dvb_frontend->ops.init) | ||
722 | budget->dvb_frontend->ops.init(budget->dvb_frontend); | ||
723 | |||
724 | if (dvb_attach(lnbh24_attach, | ||
725 | budget->dvb_frontend, | ||
726 | &budget->i2c_adap, | ||
727 | LNBH24_PCL | LNBH24_TTX, | ||
728 | LNBH24_TEN, 0x14>>1) == NULL) { | ||
729 | printk(KERN_ERR | ||
730 | "No LNBH24 found!\n"); | ||
731 | goto error_out; | ||
732 | } | ||
733 | } else { | ||
734 | printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__); | ||
735 | goto error_out; | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | break; | ||
740 | } | ||
741 | |||
742 | if (budget->dvb_frontend == NULL) { | ||
743 | printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", | ||
744 | budget->dev->pci->vendor, | ||
745 | budget->dev->pci->device, | ||
746 | budget->dev->pci->subsystem_vendor, | ||
747 | budget->dev->pci->subsystem_device); | ||
748 | } else { | ||
749 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) | ||
750 | goto error_out; | ||
751 | } | ||
752 | return; | ||
753 | |||
754 | error_out: | ||
755 | printk("budget: Frontend registration failed!\n"); | ||
756 | dvb_frontend_detach(budget->dvb_frontend); | ||
757 | budget->dvb_frontend = NULL; | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) | ||
762 | { | ||
763 | struct budget *budget = NULL; | ||
764 | int err; | ||
765 | |||
766 | budget = kmalloc(sizeof(struct budget), GFP_KERNEL); | ||
767 | if( NULL == budget ) { | ||
768 | return -ENOMEM; | ||
769 | } | ||
770 | |||
771 | dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget); | ||
772 | |||
773 | dev->ext_priv = budget; | ||
774 | |||
775 | err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); | ||
776 | if (err) { | ||
777 | printk("==> failed\n"); | ||
778 | kfree (budget); | ||
779 | return err; | ||
780 | } | ||
781 | |||
782 | budget->dvb_adapter.priv = budget; | ||
783 | frontend_init(budget); | ||
784 | |||
785 | ttpci_budget_init_hooks(budget); | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int budget_detach (struct saa7146_dev* dev) | ||
791 | { | ||
792 | struct budget *budget = (struct budget*) dev->ext_priv; | ||
793 | int err; | ||
794 | |||
795 | if (budget->dvb_frontend) { | ||
796 | dvb_unregister_frontend(budget->dvb_frontend); | ||
797 | dvb_frontend_detach(budget->dvb_frontend); | ||
798 | } | ||
799 | |||
800 | err = ttpci_budget_deinit (budget); | ||
801 | |||
802 | kfree (budget); | ||
803 | dev->ext_priv = NULL; | ||
804 | |||
805 | return err; | ||
806 | } | ||
807 | |||
808 | static struct saa7146_extension budget_extension; | ||
809 | |||
810 | MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); | ||
811 | MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); | ||
812 | MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); | ||
813 | MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); | ||
814 | MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); | ||
815 | MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT); | ||
816 | MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); | ||
817 | MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); | ||
818 | MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); | ||
819 | MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY); | ||
820 | MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT); | ||
821 | |||
822 | static struct pci_device_id pci_tbl[] = { | ||
823 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), | ||
824 | MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), | ||
825 | MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), | ||
826 | MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), | ||
827 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), | ||
828 | MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), | ||
829 | MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), | ||
830 | MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), | ||
831 | MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), | ||
832 | MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), | ||
833 | MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), | ||
834 | MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020), | ||
835 | { | ||
836 | .vendor = 0, | ||
837 | } | ||
838 | }; | ||
839 | |||
840 | MODULE_DEVICE_TABLE(pci, pci_tbl); | ||
841 | |||
842 | static struct saa7146_extension budget_extension = { | ||
843 | .name = "budget dvb", | ||
844 | .flags = SAA7146_USE_I2C_IRQ, | ||
845 | |||
846 | .module = THIS_MODULE, | ||
847 | .pci_tbl = pci_tbl, | ||
848 | .attach = budget_attach, | ||
849 | .detach = budget_detach, | ||
850 | |||
851 | .irq_mask = MASK_10, | ||
852 | .irq_func = ttpci_budget_irq10_handler, | ||
853 | }; | ||
854 | |||
855 | static int __init budget_init(void) | ||
856 | { | ||
857 | return saa7146_register_extension(&budget_extension); | ||
858 | } | ||
859 | |||
860 | static void __exit budget_exit(void) | ||
861 | { | ||
862 | saa7146_unregister_extension(&budget_extension); | ||
863 | } | ||
864 | |||
865 | module_init(budget_init); | ||
866 | module_exit(budget_exit); | ||
867 | |||
868 | MODULE_LICENSE("GPL"); | ||
869 | MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); | ||
870 | MODULE_DESCRIPTION("driver for the SAA7146 based so-called " | ||
871 | "budget PCI DVB cards by Siemens, Technotrend, Hauppauge"); | ||
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h deleted file mode 100644 index 3d8a806c20bb..000000000000 --- a/drivers/media/dvb/ttpci/budget.h +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | |||
2 | #ifndef __BUDGET_DVB__ | ||
3 | #define __BUDGET_DVB__ | ||
4 | |||
5 | #include "dvb_frontend.h" | ||
6 | #include "dvbdev.h" | ||
7 | #include "demux.h" | ||
8 | #include "dvb_demux.h" | ||
9 | #include "dmxdev.h" | ||
10 | #include "dvb_filter.h" | ||
11 | #include "dvb_net.h" | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/mutex.h> | ||
15 | |||
16 | #include <media/saa7146.h> | ||
17 | |||
18 | extern int budget_debug; | ||
19 | |||
20 | #ifdef dprintk | ||
21 | #undef dprintk | ||
22 | #endif | ||
23 | |||
24 | #define dprintk(level,args...) \ | ||
25 | do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __func__); printk(args); } } while (0) | ||
26 | |||
27 | struct budget_info { | ||
28 | char *name; | ||
29 | int type; | ||
30 | }; | ||
31 | |||
32 | /* place to store all the necessary device information */ | ||
33 | struct budget { | ||
34 | |||
35 | /* devices */ | ||
36 | struct dvb_device dvb_dev; | ||
37 | struct dvb_net dvb_net; | ||
38 | |||
39 | struct saa7146_dev *dev; | ||
40 | |||
41 | struct i2c_adapter i2c_adap; | ||
42 | struct budget_info *card; | ||
43 | |||
44 | unsigned char *grabbing; | ||
45 | struct saa7146_pgtable pt; | ||
46 | |||
47 | struct tasklet_struct fidb_tasklet; | ||
48 | struct tasklet_struct vpe_tasklet; | ||
49 | |||
50 | struct dmxdev dmxdev; | ||
51 | struct dvb_demux demux; | ||
52 | |||
53 | struct dmx_frontend hw_frontend; | ||
54 | struct dmx_frontend mem_frontend; | ||
55 | |||
56 | int ci_present; | ||
57 | int video_port; | ||
58 | |||
59 | u32 buffer_width; | ||
60 | u32 buffer_height; | ||
61 | u32 buffer_size; | ||
62 | u32 buffer_warning_threshold; | ||
63 | u32 buffer_warnings; | ||
64 | unsigned long buffer_warning_time; | ||
65 | |||
66 | u32 ttbp; | ||
67 | int feeding; | ||
68 | |||
69 | spinlock_t feedlock; | ||
70 | |||
71 | spinlock_t debilock; | ||
72 | |||
73 | struct dvb_adapter dvb_adapter; | ||
74 | struct dvb_frontend *dvb_frontend; | ||
75 | int (*read_fe_status)(struct dvb_frontend *fe, fe_status_t *status); | ||
76 | int fe_synced; | ||
77 | |||
78 | void *priv; | ||
79 | }; | ||
80 | |||
81 | #define MAKE_BUDGET_INFO(x_var,x_name,x_type) \ | ||
82 | static struct budget_info x_var ## _info = { \ | ||
83 | .name=x_name, \ | ||
84 | .type=x_type }; \ | ||
85 | static struct saa7146_pci_extension_data x_var = { \ | ||
86 | .ext_priv = &x_var ## _info, \ | ||
87 | .ext = &budget_extension }; | ||
88 | |||
89 | #define BUDGET_TT 0 | ||
90 | #define BUDGET_TT_HW_DISEQC 1 | ||
91 | #define BUDGET_PATCH 3 | ||
92 | #define BUDGET_FS_ACTIVY 4 | ||
93 | #define BUDGET_CIN1200S 5 | ||
94 | #define BUDGET_CIN1200C 6 | ||
95 | #define BUDGET_CIN1200T 7 | ||
96 | #define BUDGET_KNC1S 8 | ||
97 | #define BUDGET_KNC1C 9 | ||
98 | #define BUDGET_KNC1T 10 | ||
99 | #define BUDGET_KNC1SP 11 | ||
100 | #define BUDGET_KNC1CP 12 | ||
101 | #define BUDGET_KNC1TP 13 | ||
102 | #define BUDGET_TVSTAR 14 | ||
103 | #define BUDGET_CIN1200C_MK3 15 | ||
104 | #define BUDGET_KNC1C_MK3 16 | ||
105 | #define BUDGET_KNC1CP_MK3 17 | ||
106 | #define BUDGET_KNC1S2 18 | ||
107 | #define BUDGET_KNC1C_TDA10024 19 | ||
108 | |||
109 | #define BUDGET_VIDEO_PORTA 0 | ||
110 | #define BUDGET_VIDEO_PORTB 1 | ||
111 | |||
112 | extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | ||
113 | struct saa7146_pci_extension_data *info, | ||
114 | struct module *owner, short *adapter_nums); | ||
115 | extern void ttpci_budget_init_hooks(struct budget *budget); | ||
116 | extern int ttpci_budget_deinit(struct budget *budget); | ||
117 | extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); | ||
118 | extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port); | ||
119 | extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count, | ||
120 | int uselocks, int nobusyloop); | ||
121 | extern int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, int count, u32 value, | ||
122 | int uselocks, int nobusyloop); | ||
123 | |||
124 | #endif | ||
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c deleted file mode 100644 index 32d43156c548..000000000000 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ /dev/null | |||
@@ -1,176 +0,0 @@ | |||
1 | /* | ||
2 | Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM, | ||
3 | decode it and store it in the associated adapter struct for | ||
4 | use by dvb_net.c | ||
5 | |||
6 | This card appear to have the 24C16 write protect held to ground, | ||
7 | thus permitting normal read/write operation. Theoretically it | ||
8 | would be possible to write routines to burn a different (encoded) | ||
9 | MAC address into the EEPROM. | ||
10 | |||
11 | Robert Schlabbach GMX | ||
12 | Michael Glaum KVH Industries | ||
13 | Holger Waechtler Convergence | ||
14 | |||
15 | Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de> | ||
16 | Metzler Brothers Systementwicklung GbR | ||
17 | |||
18 | This program is free software; you can redistribute it and/or modify | ||
19 | it under the terms of the GNU General Public License as published by | ||
20 | the Free Software Foundation; either version 2 of the License, or | ||
21 | (at your option) any later version. | ||
22 | |||
23 | This program is distributed in the hope that it will be useful, | ||
24 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | GNU General Public License for more details. | ||
27 | |||
28 | You should have received a copy of the GNU General Public License | ||
29 | along with this program; if not, write to the Free Software | ||
30 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
31 | |||
32 | */ | ||
33 | |||
34 | #include <asm/errno.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/string.h> | ||
38 | #include <linux/i2c.h> | ||
39 | |||
40 | #include "ttpci-eeprom.h" | ||
41 | |||
42 | #if 1 | ||
43 | #define dprintk(x...) do { printk(x); } while (0) | ||
44 | #else | ||
45 | #define dprintk(x...) do { } while (0) | ||
46 | #endif | ||
47 | |||
48 | |||
49 | static int check_mac_tt(u8 *buf) | ||
50 | { | ||
51 | int i; | ||
52 | u16 tmp = 0xffff; | ||
53 | |||
54 | for (i = 0; i < 8; i++) { | ||
55 | tmp = (tmp << 8) | ((tmp >> 8) ^ buf[i]); | ||
56 | tmp ^= (tmp >> 4) & 0x0f; | ||
57 | tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5); | ||
58 | } | ||
59 | tmp ^= 0xffff; | ||
60 | return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9])); | ||
61 | } | ||
62 | |||
63 | static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC) | ||
64 | { | ||
65 | u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c, | ||
66 | 0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6, | ||
67 | 0x1d, 0x36, 0x64, 0x78}; | ||
68 | u8 data[20]; | ||
69 | int i; | ||
70 | |||
71 | /* In case there is a sig check failure have the orig contents available */ | ||
72 | memcpy(data, encodedMAC, 20); | ||
73 | |||
74 | for (i = 0; i < 20; i++) | ||
75 | data[i] ^= xor[i]; | ||
76 | for (i = 0; i < 10; i++) | ||
77 | data[i] = ((data[2 * i + 1] << 8) | data[2 * i]) | ||
78 | >> ((data[2 * i + 1] >> 6) & 3); | ||
79 | |||
80 | if (check_mac_tt(data)) | ||
81 | return -ENODEV; | ||
82 | |||
83 | decodedMAC[0] = data[2]; decodedMAC[1] = data[1]; decodedMAC[2] = data[0]; | ||
84 | decodedMAC[3] = data[6]; decodedMAC[4] = data[5]; decodedMAC[5] = data[4]; | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC) | ||
89 | { | ||
90 | u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c, | ||
91 | 0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6, | ||
92 | 0x1d, 0x36, 0x64, 0x78}; | ||
93 | u8 data[20]; | ||
94 | int i; | ||
95 | |||
96 | memcpy(data, encodedMAC, 20); | ||
97 | |||
98 | for (i = 0; i < 20; i++) | ||
99 | data[i] ^= xor[i]; | ||
100 | for (i = 0; i < 10; i++) | ||
101 | data[i] = ((data[2 * i + 1] << 8) | data[2 * i]) | ||
102 | >> ((data[2 * i + 1] >> 6) & 3); | ||
103 | |||
104 | if (check_mac_tt(data)) | ||
105 | return -ENODEV; | ||
106 | |||
107 | decodedMAC[0] = data[2]; | ||
108 | decodedMAC[1] = data[1]; | ||
109 | decodedMAC[2] = data[0]; | ||
110 | decodedMAC[3] = data[6]; | ||
111 | decodedMAC[4] = data[5]; | ||
112 | decodedMAC[5] = data[4]; | ||
113 | return 0; | ||
114 | } | ||
115 | EXPORT_SYMBOL(ttpci_eeprom_decode_mac); | ||
116 | |||
117 | static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC) | ||
118 | { | ||
119 | int ret; | ||
120 | u8 b0[] = { 0xcc }; | ||
121 | |||
122 | struct i2c_msg msg[] = { | ||
123 | { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 }, | ||
124 | { .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 } | ||
125 | }; | ||
126 | |||
127 | /* dprintk("%s\n", __func__); */ | ||
128 | |||
129 | ret = i2c_transfer(adapter, msg, 2); | ||
130 | |||
131 | if (ret != 2) /* Assume EEPROM isn't there */ | ||
132 | return (-ENODEV); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | |||
138 | int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac) | ||
139 | { | ||
140 | int ret, i; | ||
141 | u8 encodedMAC[20]; | ||
142 | u8 decodedMAC[6]; | ||
143 | |||
144 | ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC); | ||
145 | |||
146 | if (ret != 0) { /* Will only be -ENODEV */ | ||
147 | dprintk("Couldn't read from EEPROM: not there?\n"); | ||
148 | memset(proposed_mac, 0, 6); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | ret = getmac_tt(decodedMAC, encodedMAC); | ||
153 | if( ret != 0 ) { | ||
154 | dprintk("adapter failed MAC signature check\n"); | ||
155 | dprintk("encoded MAC from EEPROM was " ); | ||
156 | for(i=0; i<19; i++) { | ||
157 | dprintk( "%.2x:", encodedMAC[i]); | ||
158 | } | ||
159 | dprintk("%.2x\n", encodedMAC[19]); | ||
160 | memset(proposed_mac, 0, 6); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | memcpy(proposed_mac, decodedMAC, 6); | ||
165 | dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", | ||
166 | decodedMAC[0], decodedMAC[1], decodedMAC[2], | ||
167 | decodedMAC[3], decodedMAC[4], decodedMAC[5]); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | EXPORT_SYMBOL(ttpci_eeprom_parse_mac); | ||
172 | |||
173 | MODULE_LICENSE("GPL"); | ||
174 | MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); | ||
175 | MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards " | ||
176 | "made by Siemens, Technotrend, Hauppauge"); | ||
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.h b/drivers/media/dvb/ttpci/ttpci-eeprom.h deleted file mode 100644 index dcc33d5a5cb1..000000000000 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* | ||
2 | Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM, | ||
3 | decode it and store it in associated adapter net device | ||
4 | |||
5 | Robert Schlabbach GMX | ||
6 | Michael Glaum KVH Industries | ||
7 | Holger Waechtler Convergence | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | #ifndef __TTPCI_EEPROM_H__ | ||
26 | #define __TTPCI_EEPROM_H__ | ||
27 | |||
28 | #include <linux/types.h> | ||
29 | #include <linux/i2c.h> | ||
30 | |||
31 | extern int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC); | ||
32 | extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac); | ||
33 | |||
34 | #endif | ||