[PATCH] dvb: DST: reorganize Twinhan DST driver to support CI

- reorganize Twinhan DST driver to support CI
- add support for more cards
(Manu Abraham)

Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Johannes Stezenbach and committed by
Linus Torvalds
50b215a0 daeb6aa4

+1917 -372
+219
Documentation/dvb/ci.txt
···
··· 1 + * For the user 2 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 + NOTE: This document describes the usage of the high level CI API as 4 + in accordance to the Linux DVB API. This is a not a documentation for the, 5 + existing low level CI API. 6 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 + 8 + To utilize the High Level CI capabilities, 9 + 10 + (1*) This point is valid only for the Twinhan/clones 11 + For the Twinhan/Twinhan clones, the dst_ca module handles the CI 12 + hardware handling.This module is loaded automatically if a CI 13 + (Common Interface, that holds the CAM (Conditional Access Module) 14 + is detected. 15 + 16 + (2) one requires a userspace application, ca_zap. This small userland 17 + application is in charge of sending the descrambling related information 18 + to the CAM. 19 + 20 + This application requires the following to function properly as of now. 21 + 22 + (a) Tune to a valid channel, with szap. 23 + eg: $ szap -c channels.conf -r "TMC" -x 24 + 25 + (b) a channels.conf containing a valid PMT PID 26 + 27 + eg: TMC:11996:h:0:27500:278:512:650:321 28 + 29 + here 278 is a valid PMT PID. the rest of the values are the 30 + same ones that szap uses. 31 + 32 + (c) after running a szap, you have to run ca_zap, for the 33 + descrambler to function, 34 + 35 + eg: $ ca_zap patched_channels.conf "TMC" 36 + 37 + The patched means a patch to apply to scan, such that scan can 38 + generate a channels.conf_with pmt, which has this PMT PID info 39 + (NOTE: szap cannot use this channels.conf with the PMT_PID) 40 + 41 + 42 + (d) Hopeflly Enjoy your favourite subscribed channel as you do with 43 + a FTA card. 44 + 45 + (3) Currently ca_zap, and dst_test, both are meant for demonstration 46 + purposes only, they can become full fledged applications if necessary. 47 + 48 + 49 + * Cards that fall in this category 50 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 51 + At present the cards that fall in this category are the Twinhan and it's 52 + clones, these cards are available as VVMER, Tomato, Hercules, Orange and 53 + so on. 54 + 55 + * CI modules that are supported 56 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 + The CI module support is largely dependant upon the firmware on the cards 58 + Some cards do support almost all of the available CI modules. There is 59 + nothing much that can be done in order to make additional CI modules 60 + working with these cards. 61 + 62 + Modules that have been tested by this driver at present are 63 + 64 + (1) Irdeto 1 and 2 from SCM 65 + (2) Viaccess from SCM 66 + (3) Dragoncam 67 + 68 + * The High level CI API 69 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 + 71 + * For the programmer 72 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 73 + With the High Level CI approach any new card with almost any random 74 + architecture can be implemented with this style, the definitions 75 + insidethe switch statement can be easily adapted for any card, thereby 76 + eliminating the need for any additional ioctls. 77 + 78 + The disadvantage is that the driver/hardware has to manage the rest. For 79 + the application programmer it would be as simple as sending/receiving an 80 + array to/from the CI ioctls as defined in the Linux DVB API. No changes 81 + have been made in the API to accomodate this feature. 82 + 83 + 84 + * Why the need for another CI interface ? 85 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 86 + This is one of the most commonly asked question. Well a nice question. 87 + Strictly speaking this is not a new interface. 88 + 89 + The CI interface is defined in the DVB API in ca.h as 90 + 91 + typedef struct ca_slot_info { 92 + int num; /* slot number */ 93 + 94 + int type; /* CA interface this slot supports */ 95 + #define CA_CI 1 /* CI high level interface */ 96 + #define CA_CI_LINK 2 /* CI link layer level interface */ 97 + #define CA_CI_PHYS 4 /* CI physical layer level interface */ 98 + #define CA_DESCR 8 /* built-in descrambler */ 99 + #define CA_SC 128 /* simple smart card interface */ 100 + 101 + unsigned int flags; 102 + #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ 103 + #define CA_CI_MODULE_READY 2 104 + } ca_slot_info_t; 105 + 106 + 107 + 108 + This CI interface follows the CI high level interface, which is not 109 + implemented by most applications. Hence this area is revisited. 110 + 111 + This CI interface is quite different in the case that it tries to 112 + accomodate all other CI based devices, that fall into the other categories 113 + 114 + This means that this CI interface handles the EN50221 style tags in the 115 + Application layer only and no session management is taken care of by the 116 + application. The driver/hardware will take care of all that. 117 + 118 + This interface is purely an EN50221 interface exchanging APDU's. This 119 + means that no session management, link layer or a transport layer do 120 + exist in this case in the application to driver communication. It is 121 + as simple as that. The driver/hardware has to take care of that. 122 + 123 + 124 + With this High Level CI interface, the interface can be defined with the 125 + regular ioctls. 126 + 127 + All these ioctls are also valid for the High level CI interface 128 + 129 + #define CA_RESET _IO('o', 128) 130 + #define CA_GET_CAP _IOR('o', 129, ca_caps_t) 131 + #define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t) 132 + #define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t) 133 + #define CA_GET_MSG _IOR('o', 132, ca_msg_t) 134 + #define CA_SEND_MSG _IOW('o', 133, ca_msg_t) 135 + #define CA_SET_DESCR _IOW('o', 134, ca_descr_t) 136 + #define CA_SET_PID _IOW('o', 135, ca_pid_t) 137 + 138 + 139 + On querying the device, the device yields information thus 140 + 141 + CA_GET_SLOT_INFO 142 + ---------------------------- 143 + Command = [info] 144 + APP: Number=[1] 145 + APP: Type=[1] 146 + APP: flags=[1] 147 + APP: CI High level interface 148 + APP: CA/CI Module Present 149 + 150 + CA_GET_CAP 151 + ---------------------------- 152 + Command = [caps] 153 + APP: Slots=[1] 154 + APP: Type=[1] 155 + APP: Descrambler keys=[16] 156 + APP: Type=[1] 157 + 158 + CA_SEND_MSG 159 + ---------------------------- 160 + Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1] 161 + Found CA descriptor @ program level 162 + 163 + (20) ES type=[2] ES pid=[201] ES length =[0 (0x0)] 164 + (25) ES type=[4] ES pid=[301] ES length =[0 (0x0)] 165 + ca_message length is 25 (0x19) bytes 166 + EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00] 167 + 168 + 169 + Not all ioctl's are implemented in the driver from the API, the other 170 + features of the hardware that cannot be implemented by the API are achieved 171 + using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is 172 + used to exchange the data to maintain compatibility with other hardware. 173 + 174 + 175 + /* a message to/from a CI-CAM */ 176 + typedef struct ca_msg { 177 + unsigned int index; 178 + unsigned int type; 179 + unsigned int length; 180 + unsigned char msg[256]; 181 + } ca_msg_t; 182 + 183 + 184 + The flow of data can be described thus, 185 + 186 + 187 + 188 + 189 + 190 + App (User) 191 + ----- 192 + parse 193 + | 194 + | 195 + v 196 + en50221 APDU (package) 197 + -------------------------------------- 198 + | | | High Level CI driver 199 + | | | 200 + | v | 201 + | en50221 APDU (unpackage) | 202 + | | | 203 + | | | 204 + | v | 205 + | sanity checks | 206 + | | | 207 + | | | 208 + | v | 209 + | do (H/W dep) | 210 + -------------------------------------- 211 + | Hardware 212 + | 213 + v 214 + 215 + 216 + 217 + 218 + The High Level CI interface uses the EN50221 DVB standard, following a 219 + standard ensures futureproofness.
+1 -2
drivers/media/dvb/bt8xx/Kconfig
··· 11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and 12 pcHDTV HD2000 cards. 13 14 - Since these cards have no MPEG decoder onboard, they transmit 15 only compressed MPEG data over the PCI bus, so you need 16 an external software decoder to watch TV on your computer. 17 18 Say Y if you own such a device and want to use it. 19 -
··· 11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and 12 pcHDTV HD2000 cards. 13 14 + Since these cards have no MPEG decoder onboard, they transmit 15 only compressed MPEG data over the PCI bus, so you need 16 an external software decoder to watch TV on your computer. 17 18 Say Y if you own such a device and want to use it.
+1 -3
drivers/media/dvb/bt8xx/Makefile
··· 1 - 2 - obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o 3 4 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends 5 -
··· 1 + obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o 2 3 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
+9 -9
drivers/media/dvb/bt8xx/bt878.c
··· 4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> 5 * 6 * large parts based on the bttv driver 7 - * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 - * & Marcus Metzler (mocm@thp.uni-koeln.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 ··· 461 pci_set_drvdata(dev, bt); 462 463 /* if(init_bt878(btv) < 0) { 464 - bt878_remove(dev); 465 - return -EIO; 466 - } 467 */ 468 469 if ((result = bt878_mem_alloc(bt))) { ··· 536 MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); 537 538 static struct pci_driver bt878_pci_driver = { 539 - .name = "bt878", 540 .id_table = bt878_pci_tbl, 541 - .probe = bt878_probe, 542 - .remove = bt878_remove, 543 }; 544 545 static int bt878_pci_driver_registered = 0; ··· 558 (BT878_VERSION_CODE >> 8) & 0xff, 559 BT878_VERSION_CODE & 0xff); 560 /* 561 - bt878_check_chipset(); 562 */ 563 /* later we register inside of bt878_find_audio_dma() 564 * because we may want to ignore certain cards */
··· 4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.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 ··· 461 pci_set_drvdata(dev, bt); 462 463 /* if(init_bt878(btv) < 0) { 464 + bt878_remove(dev); 465 + return -EIO; 466 + } 467 */ 468 469 if ((result = bt878_mem_alloc(bt))) { ··· 536 MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); 537 538 static struct pci_driver bt878_pci_driver = { 539 + .name = "bt878", 540 .id_table = bt878_pci_tbl, 541 + .probe = bt878_probe, 542 + .remove = bt878_remove, 543 }; 544 545 static int bt878_pci_driver_registered = 0; ··· 558 (BT878_VERSION_CODE >> 8) & 0xff, 559 BT878_VERSION_CODE & 0xff); 560 /* 561 + bt878_check_chipset(); 562 */ 563 /* later we register inside of bt878_find_audio_dma() 564 * because we may want to ignore certain cards */
+549 -279
drivers/media/dvb/bt8xx/dst.c
··· 1 /* 2 - Frontend-driver for TwinHan DST Frontend 3 4 - Copyright (C) 2003 Jamie Honan 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 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 23 #include <linux/kernel.h> 24 #include <linux/module.h> ··· 31 32 #include "dvb_frontend.h" 33 #include "dst_priv.h" 34 - #include "dst.h" 35 36 - struct dst_state { 37 38 - struct i2c_adapter* i2c; 39 40 - struct bt878* bt; 41 42 - struct dvb_frontend_ops ops; 43 44 - /* configuration settings */ 45 - const struct dst_config* config; 46 47 - struct dvb_frontend frontend; 48 49 - /* private demodulator data */ 50 - u8 tx_tuna[10]; 51 - u8 rx_tuna[10]; 52 - u8 rxbuffer[10]; 53 - u8 diseq_flags; 54 - u8 dst_type; 55 - u32 type_flags; 56 - u32 frequency; /* intermediate frequency in kHz for QPSK */ 57 - fe_spectral_inversion_t inversion; 58 - u32 symbol_rate; /* symbol rate in Symbols per second */ 59 - fe_code_rate_t fec; 60 - fe_sec_voltage_t voltage; 61 - fe_sec_tone_mode_t tone; 62 - u32 decode_freq; 63 - u8 decode_lock; 64 - u16 decode_strength; 65 - u16 decode_snr; 66 - unsigned long cur_jiff; 67 - u8 k22; 68 - fe_bandwidth_t bandwidth; 69 - }; 70 71 - static unsigned int dst_verbose = 0; 72 - module_param(dst_verbose, int, 0644); 73 - MODULE_PARM_DESC(dst_verbose, "verbose startup messages, default is 1 (yes)"); 74 - static unsigned int dst_debug = 0; 75 - module_param(dst_debug, int, 0644); 76 - MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)"); 77 - 78 - #define dprintk if (dst_debug) printk 79 - 80 - #define DST_TYPE_IS_SAT 0 81 - #define DST_TYPE_IS_TERR 1 82 - #define DST_TYPE_IS_CABLE 2 83 - 84 - #define DST_TYPE_HAS_NEWTUNE 1 85 - #define DST_TYPE_HAS_TS204 2 86 - #define DST_TYPE_HAS_SYMDIV 4 87 88 #define HAS_LOCK 1 89 #define ATTEMPT_TUNE 2 ··· 66 bt878_device_control(state->bt, DST_IG_TS, &bits); 67 } 68 69 - static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh) 70 { 71 union dst_gpio_packet enb; 72 union dst_gpio_packet bits; ··· 74 75 enb.enb.mask = mask; 76 enb.enb.enable = enbb; 77 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { 78 - dprintk("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb); 79 return -EREMOTEIO; 80 } 81 82 /* because complete disabling means no output, no need to do output packet */ 83 if (enbb == 0) 84 return 0; 85 86 bits.outp.mask = enbb; 87 bits.outp.highvals = outhigh; 88 89 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { 90 - dprintk("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh); 91 return -EREMOTEIO; 92 } 93 return 0; 94 } 95 96 - static int dst_gpio_inb(struct dst_state *state, u8 * result) 97 { 98 union dst_gpio_packet rd_packet; 99 int err; ··· 117 *result = (u8) rd_packet.rd.value; 118 return 0; 119 } 120 121 - #define DST_I2C_ENABLE 1 122 - #define DST_8820 2 123 - 124 - static int dst_reset8820(struct dst_state *state) 125 { 126 - int retval; 127 - /* pull 8820 gpio pin low, wait, high, wait, then low */ 128 - // dprintk ("%s: reset 8820\n", __FUNCTION__); 129 - retval = dst_gpio_outb(state, DST_8820, DST_8820, 0); 130 - if (retval < 0) 131 - return retval; 132 msleep(10); 133 - retval = dst_gpio_outb(state, DST_8820, DST_8820, DST_8820); 134 - if (retval < 0) 135 - return retval; 136 - /* wait for more feedback on what works here * 137 - msleep(10); 138 - retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0); 139 - if (retval < 0) 140 - return retval; 141 - */ 142 return 0; 143 } 144 145 - static int dst_i2c_enable(struct dst_state *state) 146 { 147 - int retval; 148 - /* pull I2C enable gpio pin low, wait */ 149 - // dprintk ("%s: i2c enable\n", __FUNCTION__); 150 - retval = dst_gpio_outb(state, ~0, DST_I2C_ENABLE, 0); 151 - if (retval < 0) 152 - return retval; 153 - // dprintk ("%s: i2c enable delay\n", __FUNCTION__); 154 - msleep(33); 155 return 0; 156 } 157 158 - static int dst_i2c_disable(struct dst_state *state) 159 { 160 - int retval; 161 - /* release I2C enable gpio pin, wait */ 162 - // dprintk ("%s: i2c disable\n", __FUNCTION__); 163 - retval = dst_gpio_outb(state, ~0, 0, 0); 164 - if (retval < 0) 165 - return retval; 166 - // dprintk ("%s: i2c disable delay\n", __FUNCTION__); 167 - msleep(33); 168 return 0; 169 } 170 171 - static int dst_wait_dst_ready(struct dst_state *state) 172 { 173 u8 reply; 174 - int retval; 175 int i; 176 for (i = 0; i < 200; i++) { 177 - retval = dst_gpio_inb(state, &reply); 178 - if (retval < 0) 179 - return retval; 180 - if ((reply & DST_I2C_ENABLE) == 0) { 181 - dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i); 182 return 1; 183 } 184 - msleep(10); 185 } 186 - dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i); 187 return 0; 188 } 189 190 - static int write_dst(struct dst_state *state, u8 * data, u8 len) 191 { 192 struct i2c_msg msg = { 193 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len 194 }; 195 int err; 196 int cnt; 197 - 198 - if (dst_debug && dst_verbose) { 199 u8 i; 200 - dprintk("%s writing", __FUNCTION__); 201 - for (i = 0; i < len; i++) { 202 - dprintk(" 0x%02x", data[i]); 203 } 204 - dprintk("\n"); 205 } 206 - msleep(30); 207 - for (cnt = 0; cnt < 4; cnt++) { 208 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 209 - dprintk("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]); 210 - dst_i2c_disable(state); 211 - msleep(500); 212 - dst_i2c_enable(state); 213 - msleep(500); 214 continue; 215 } else 216 break; 217 } 218 - if (cnt >= 4) 219 - return -EREMOTEIO; 220 return 0; 221 } 222 223 - static int read_dst(struct dst_state *state, u8 * ret, u8 len) 224 { 225 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; 226 int err; 227 int cnt; 228 229 - for (cnt = 0; cnt < 4; cnt++) { 230 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 231 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]); 232 - dst_i2c_disable(state); 233 - dst_i2c_enable(state); 234 continue; 235 } else 236 break; 237 } 238 - if (cnt >= 4) 239 - return -EREMOTEIO; 240 - dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); 241 - if (dst_debug && dst_verbose) { 242 for (err = 1; err < len; err++) 243 dprintk(" 0x%x", ret[err]); 244 if (err > 1) 245 dprintk("\n"); 246 } 247 return 0; 248 } 249 250 static int dst_set_freq(struct dst_state *state, u32 freq) 251 { ··· 476 return 0; 477 } 478 479 - static u8 dst_check_sum(u8 * buf, u32 len) 480 { 481 u32 i; 482 u8 val = 0; ··· 487 } 488 return ((~val) + 1); 489 } 490 - 491 - struct dst_types { 492 - char *mstr; 493 - int offs; 494 - u8 dst_type; 495 - u32 type_flags; 496 - }; 497 - 498 - static struct dst_types dst_tlist[] = { 499 - {"DST-020", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV}, 500 - {"DST-030", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE}, 501 - {"DST-03T", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204}, 502 - {"DST-MOT", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV}, 503 - {"DST-CI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE}, 504 - {"DSTMCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE}, 505 - {"DSTFCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE}, 506 - {"DCTNEW", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE}, 507 - {"DCT-CI", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_TS204}, 508 - {"DTTDIG", 1, DST_TYPE_IS_TERR, 0} 509 - }; 510 - 511 - /* DCTNEW and DCT-CI are guesses */ 512 513 static void dst_type_flags_print(u32 type_flags) 514 { ··· 498 printk(" 0x%x ts204", DST_TYPE_HAS_TS204); 499 if (type_flags & DST_TYPE_HAS_SYMDIV) 500 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV); 501 printk("\n"); 502 } 503 504 - static int dst_type_print(u8 type) 505 { 506 char *otype; 507 switch (type) { 508 case DST_TYPE_IS_SAT: 509 otype = "satellite"; 510 break; 511 case DST_TYPE_IS_TERR: 512 otype = "terrestrial"; 513 break; 514 case DST_TYPE_IS_CABLE: 515 otype = "cable"; 516 break; 517 default: 518 printk("%s: invalid dst type %d\n", __FUNCTION__, type); 519 return -EINVAL; 520 } 521 printk("DST type : %s\n", otype); 522 return 0; 523 } 524 525 - static int dst_check_ci(struct dst_state *state) 526 { 527 - u8 txbuf[8]; 528 - u8 rxbuf[8]; 529 - int retval; 530 int i; 531 - struct dst_types *dsp; 532 - u8 use_dst_type; 533 - u32 use_type_flags; 534 535 - memset(txbuf, 0, sizeof(txbuf)); 536 - txbuf[1] = 6; 537 - txbuf[7] = dst_check_sum(txbuf, 7); 538 539 - dst_i2c_enable(state); 540 - dst_reset8820(state); 541 - retval = write_dst(state, txbuf, 8); 542 - if (retval < 0) { 543 - dst_i2c_disable(state); 544 - dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__); 545 - return retval; 546 } 547 - msleep(3); 548 - retval = read_dst(state, rxbuf, 1); 549 - dst_i2c_disable(state); 550 - if (retval < 0) { 551 - dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__); 552 - return retval; 553 } 554 - if (rxbuf[0] != 0xff) { 555 - dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]); 556 - return retval; 557 - } 558 - if (!dst_wait_dst_ready(state)) 559 - return 0; 560 - // dst_i2c_enable(i2c); Dimitri 561 - retval = read_dst(state, rxbuf, 8); 562 - dst_i2c_disable(state); 563 - if (retval < 0) { 564 - dprintk("%s: read not successful\n", __FUNCTION__); 565 - return retval; 566 - } 567 - if (rxbuf[7] != dst_check_sum(rxbuf, 7)) { 568 - dprintk("%s: checksum failure\n", __FUNCTION__); 569 - return retval; 570 - } 571 - rxbuf[7] = '\0'; 572 - for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) { 573 - if (!strncmp(&rxbuf[dsp->offs], dsp->mstr, strlen(dsp->mstr))) { 574 - use_type_flags = dsp->type_flags; 575 - use_dst_type = dsp->dst_type; 576 - printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr); 577 break; 578 } 579 } 580 - if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) { 581 - printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]); 582 - printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__); 583 use_dst_type = DST_TYPE_IS_SAT; 584 use_type_flags = DST_TYPE_HAS_SYMDIV; 585 } 586 - dst_type_print(use_dst_type); 587 588 state->type_flags = use_type_flags; 589 state->dst_type = use_dst_type; 590 dst_type_flags_print(state->type_flags); ··· 759 if (state->type_flags & DST_TYPE_HAS_TS204) { 760 dst_packsize(state, 204); 761 } 762 return 0; 763 } 764 765 - static int dst_command(struct dst_state* state, u8 * data, u8 len) 766 { 767 - int retval; 768 - u8 reply; 769 770 - dst_i2c_enable(state); 771 - dst_reset8820(state); 772 - retval = write_dst(state, data, len); 773 - if (retval < 0) { 774 - dst_i2c_disable(state); 775 - dprintk("%s: write not successful\n", __FUNCTION__); 776 - return retval; 777 } 778 - msleep(33); 779 - retval = read_dst(state, &reply, 1); 780 - dst_i2c_disable(state); 781 - if (retval < 0) { 782 - dprintk("%s: read verify not successful\n", __FUNCTION__); 783 - return retval; 784 } 785 - if (reply != 0xff) { 786 - dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 787 - return 0; 788 } 789 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 790 return 0; 791 - if (!dst_wait_dst_ready(state)) 792 - return 0; 793 - // dst_i2c_enable(i2c); Per dimitri 794 - retval = read_dst(state, state->rxbuffer, 8); 795 - dst_i2c_disable(state); 796 - if (retval < 0) { 797 - dprintk("%s: read not successful\n", __FUNCTION__); 798 - return 0; 799 } 800 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 801 dprintk("%s: checksum failure\n", __FUNCTION__); 802 - return 0; 803 } 804 return 0; 805 } 806 807 static int dst_get_signal(struct dst_state* state) 808 { ··· 885 paket[4] = 0; 886 else 887 paket[4] = 1; 888 if (state->tone == SEC_TONE_ON) 889 - paket[2] = state->k22; 890 else 891 paket[2] = 0; 892 - paket[7] = dst_check_sum(&paket[0], 7); 893 dst_command(state, paket, 8); 894 return 0; 895 } ··· 903 static int dst_get_tuna(struct dst_state* state) 904 { 905 int retval; 906 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) 907 return 0; 908 state->diseq_flags &= ~(HAS_LOCK); 909 - if (!dst_wait_dst_ready(state)) 910 return 0; 911 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 912 /* how to get variable length reply ???? */ 913 retval = read_dst(state, state->rx_tuna, 10); 914 } else { 915 - retval = read_dst(state, &state->rx_tuna[2], 8); 916 } 917 if (retval < 0) { 918 dprintk("%s: read not successful\n", __FUNCTION__); 919 return 0; 920 } 921 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 922 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 923 dprintk("%s: checksum failure?\n", __FUNCTION__); ··· 969 dst_set_voltage(fe, SEC_VOLTAGE_13); 970 } 971 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 972 - dst_i2c_enable(state); 973 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 974 - dst_reset8820(state); 975 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 976 retval = write_dst(state, &state->tx_tuna[0], 10); 977 } else { 978 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); 979 - retval = write_dst(state, &state->tx_tuna[2], 8); 980 } 981 if (retval < 0) { 982 - dst_i2c_disable(state); 983 dprintk("%s: write not successful\n", __FUNCTION__); 984 return retval; 985 } 986 - msleep(3); 987 - retval = read_dst(state, &reply, 1); 988 - dst_i2c_disable(state); 989 - if (retval < 0) { 990 - dprintk("%s: read verify not successful\n", __FUNCTION__); 991 - return retval; 992 } 993 - if (reply != 0xff) { 994 - dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 995 return 0; 996 } 997 state->diseq_flags |= ATTEMPT_TUNE; 998 return dst_get_tuna(state); 999 } 1000 ··· 1057 need_cmd = 1; 1058 state->diseq_flags |= HAS_POWER; 1059 break; 1060 case SEC_VOLTAGE_18: 1061 if ((state->diseq_flags & HAS_POWER) == 0) 1062 need_cmd = 1; 1063 state->diseq_flags |= HAS_POWER; 1064 val[8] |= 0x40; 1065 break; 1066 case SEC_VOLTAGE_OFF: 1067 need_cmd = 1; 1068 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); 1069 break; 1070 default: 1071 return -EINVAL; 1072 } 1073 - if (need_cmd) { 1074 dst_tone_power_cmd(state); 1075 - } 1076 return 0; 1077 } 1078 ··· 1096 switch (tone) { 1097 case SEC_TONE_OFF: 1098 break; 1099 case SEC_TONE_ON: 1100 val[8] |= 1; 1101 break; 1102 default: 1103 return -EINVAL; 1104 } 1105 dst_tone_power_cmd(state); 1106 return 0; 1107 } 1108 ··· 1180 struct dst_state* state = (struct dst_state*) fe->demodulator_priv; 1181 1182 dst_set_freq(state, p->frequency); 1183 dst_set_inversion(state, p->inversion); 1184 if (state->dst_type == DST_TYPE_IS_SAT) { 1185 dst_set_fec(state, p->u.qpsk.fec_inner); 1186 dst_set_symbolrate(state, p->u.qpsk.symbol_rate); 1187 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1188 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 1189 } else if (state->dst_type == DST_TYPE_IS_CABLE) { ··· 1231 static struct dvb_frontend_ops dst_dvbs_ops; 1232 static struct dvb_frontend_ops dst_dvbc_ops; 1233 1234 - struct dvb_frontend* dst_attach(const struct dst_config* config, 1235 - struct i2c_adapter* i2c, 1236 - struct bt878 *bt) 1237 { 1238 - struct dst_state* state = NULL; 1239 1240 - /* allocate memory for the internal state */ 1241 - state = (struct dst_state*) kmalloc(sizeof(struct dst_state), GFP_KERNEL); 1242 - if (state == NULL) goto error; 1243 1244 - /* setup the state */ 1245 - state->config = config; 1246 - state->i2c = i2c; 1247 - state->bt = bt; 1248 - 1249 - /* check if the demod is there */ 1250 - if (dst_check_ci(state) < 0) goto error; 1251 - 1252 /* determine settings based on type */ 1253 switch (state->dst_type) { 1254 case DST_TYPE_IS_TERR: 1255 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 1256 break; 1257 case DST_TYPE_IS_CABLE: 1258 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 1259 break; 1260 case DST_TYPE_IS_SAT: 1261 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 1262 break; 1263 default: 1264 - printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n"); 1265 - goto error; 1266 } 1267 1268 /* create dvb_frontend */ 1269 state->frontend.ops = &state->ops; 1270 state->frontend.demodulator_priv = state; 1271 - return &state->frontend; 1272 1273 - error: 1274 - kfree(state); 1275 - return NULL; 1276 } 1277 1278 static struct dvb_frontend_ops dst_dvbt_ops = { 1279 ··· 1321 .read_signal_strength = dst_read_signal_strength, 1322 .read_snr = dst_read_snr, 1323 1324 .diseqc_send_master_cmd = dst_set_diseqc, 1325 .set_voltage = dst_set_voltage, 1326 .set_tone = dst_set_tone, ··· 1353 .read_snr = dst_read_snr, 1354 }; 1355 1356 - MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); 1357 - MODULE_AUTHOR("Jamie Honan"); 1358 - MODULE_LICENSE("GPL"); 1359 1360 - EXPORT_SYMBOL(dst_attach);
··· 1 /* 2 3 + Frontend/Card driver for TwinHan DST Frontend 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 23 #include <linux/kernel.h> 24 #include <linux/module.h> ··· 31 32 #include "dvb_frontend.h" 33 #include "dst_priv.h" 34 + #include "dst_common.h" 35 36 37 + static unsigned int verbose = 1; 38 + module_param(verbose, int, 0644); 39 + MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 40 41 + static unsigned int debug = 1; 42 + module_param(debug, int, 0644); 43 + MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)"); 44 45 + static unsigned int dst_addons; 46 + module_param(dst_addons, int, 0644); 47 + MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (no)"); 48 49 + static unsigned int new_fw; 50 + module_param(new_fw, int, 0644); 51 + MODULE_PARM_DESC(new_fw, "Support for the new interface firmware, default 0"); 52 53 54 55 + #define dprintk if (debug) printk 56 57 #define HAS_LOCK 1 58 #define ATTEMPT_TUNE 2 ··· 97 bt878_device_control(state->bt, DST_IG_TS, &bits); 98 } 99 100 + int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay) 101 { 102 union dst_gpio_packet enb; 103 union dst_gpio_packet bits; ··· 105 106 enb.enb.mask = mask; 107 enb.enb.enable = enbb; 108 + if (verbose > 4) 109 + dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh); 110 + 111 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { 112 + dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb); 113 return -EREMOTEIO; 114 } 115 + 116 + msleep(1); 117 118 /* because complete disabling means no output, no need to do output packet */ 119 if (enbb == 0) 120 return 0; 121 122 + if (delay) 123 + msleep(10); 124 + 125 bits.outp.mask = enbb; 126 bits.outp.highvals = outhigh; 127 128 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { 129 + dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh); 130 return -EREMOTEIO; 131 } 132 return 0; 133 } 134 + EXPORT_SYMBOL(dst_gpio_outb); 135 136 + int dst_gpio_inb(struct dst_state *state, u8 * result) 137 { 138 union dst_gpio_packet rd_packet; 139 int err; ··· 139 *result = (u8) rd_packet.rd.value; 140 return 0; 141 } 142 + EXPORT_SYMBOL(dst_gpio_inb); 143 144 + int rdc_reset_state(struct dst_state *state) 145 { 146 + if (verbose > 1) 147 + dprintk("%s: Resetting state machine\n", __FUNCTION__); 148 + 149 + if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) { 150 + dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 151 + return -1; 152 + } 153 + 154 msleep(10); 155 + 156 + if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) { 157 + dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 158 + msleep(10); 159 + return -1; 160 + } 161 + 162 return 0; 163 } 164 + EXPORT_SYMBOL(rdc_reset_state); 165 166 + int rdc_8820_reset(struct dst_state *state) 167 { 168 + if (verbose > 1) 169 + dprintk("%s: Resetting DST\n", __FUNCTION__); 170 + 171 + if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) { 172 + dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 173 + return -1; 174 + } 175 + msleep(1); 176 + 177 + if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) { 178 + dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 179 + return -1; 180 + } 181 + 182 return 0; 183 } 184 + EXPORT_SYMBOL(rdc_8820_reset); 185 186 + int dst_pio_enable(struct dst_state *state) 187 { 188 + if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) { 189 + dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 190 + return -1; 191 + } 192 + msleep(1); 193 + 194 return 0; 195 } 196 + EXPORT_SYMBOL(dst_pio_enable); 197 198 + int dst_pio_disable(struct dst_state *state) 199 + { 200 + if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) { 201 + dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 202 + return -1; 203 + } 204 + 205 + return 0; 206 + } 207 + EXPORT_SYMBOL(dst_pio_disable); 208 + 209 + int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode) 210 { 211 u8 reply; 212 int i; 213 + 214 for (i = 0; i < 200; i++) { 215 + if (dst_gpio_inb(state, &reply) < 0) { 216 + dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__); 217 + return -1; 218 + } 219 + 220 + if ((reply & RDC_8820_PIO_0_ENABLE) == 0) { 221 + if (verbose > 4) 222 + dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i); 223 return 1; 224 } 225 + msleep(1); 226 } 227 + if (verbose > 1) 228 + dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i); 229 + 230 return 0; 231 } 232 + EXPORT_SYMBOL(dst_wait_dst_ready); 233 234 + int dst_error_recovery(struct dst_state *state) 235 + { 236 + dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__); 237 + dst_pio_disable(state); 238 + msleep(10); 239 + dst_pio_enable(state); 240 + msleep(10); 241 + 242 + return 0; 243 + } 244 + EXPORT_SYMBOL(dst_error_recovery); 245 + 246 + int dst_error_bailout(struct dst_state *state) 247 + { 248 + dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__); 249 + rdc_8820_reset(state); 250 + dst_pio_disable(state); 251 + msleep(10); 252 + 253 + return 0; 254 + } 255 + EXPORT_SYMBOL(dst_error_bailout); 256 + 257 + 258 + int dst_comm_init(struct dst_state* state) 259 + { 260 + if (verbose > 1) 261 + dprintk ("%s: Initializing DST..\n", __FUNCTION__); 262 + if ((dst_pio_enable(state)) < 0) { 263 + dprintk("%s: PIO Enable Failed.\n", __FUNCTION__); 264 + return -1; 265 + } 266 + if ((rdc_reset_state(state)) < 0) { 267 + dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__); 268 + return -1; 269 + } 270 + return 0; 271 + } 272 + EXPORT_SYMBOL(dst_comm_init); 273 + 274 + 275 + int write_dst(struct dst_state *state, u8 *data, u8 len) 276 { 277 struct i2c_msg msg = { 278 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len 279 }; 280 + 281 int err; 282 int cnt; 283 + if (debug && (verbose > 4)) { 284 u8 i; 285 + if (verbose > 4) { 286 + dprintk("%s writing", __FUNCTION__); 287 + for (i = 0; i < len; i++) 288 + dprintk(" %02x", data[i]); 289 + dprintk("\n"); 290 } 291 } 292 + for (cnt = 0; cnt < 2; cnt++) { 293 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 294 + dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]); 295 + dst_error_recovery(state); 296 continue; 297 } else 298 break; 299 } 300 + 301 + if (cnt >= 2) { 302 + if (verbose > 1) 303 + printk("%s: RDC 8820 RESET...\n", __FUNCTION__); 304 + dst_error_bailout(state); 305 + 306 + return -1; 307 + } 308 + 309 return 0; 310 } 311 + EXPORT_SYMBOL(write_dst); 312 313 + int read_dst(struct dst_state *state, u8 * ret, u8 len) 314 { 315 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; 316 int err; 317 int cnt; 318 319 + for (cnt = 0; cnt < 2; cnt++) { 320 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 321 + 322 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]); 323 + dst_error_recovery(state); 324 + 325 continue; 326 } else 327 break; 328 } 329 + if (cnt >= 2) { 330 + if (verbose > 1) 331 + printk("%s: RDC 8820 RESET...\n", __FUNCTION__); 332 + dst_error_bailout(state); 333 + 334 + return -1; 335 + } 336 + if (debug && (verbose > 4)) { 337 + dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); 338 for (err = 1; err < len; err++) 339 dprintk(" 0x%x", ret[err]); 340 if (err > 1) 341 dprintk("\n"); 342 } 343 + 344 return 0; 345 } 346 + EXPORT_SYMBOL(read_dst); 347 348 static int dst_set_freq(struct dst_state *state, u32 freq) 349 { ··· 422 return 0; 423 } 424 425 + u8 dst_check_sum(u8 * buf, u32 len) 426 { 427 u32 i; 428 u8 val = 0; ··· 433 } 434 return ((~val) + 1); 435 } 436 + EXPORT_SYMBOL(dst_check_sum); 437 438 static void dst_type_flags_print(u32 type_flags) 439 { ··· 465 printk(" 0x%x ts204", DST_TYPE_HAS_TS204); 466 if (type_flags & DST_TYPE_HAS_SYMDIV) 467 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV); 468 + if (type_flags & DST_TYPE_HAS_FW_1) 469 + printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1); 470 + if (type_flags & DST_TYPE_HAS_FW_2) 471 + printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2); 472 + if (type_flags & DST_TYPE_HAS_FW_3) 473 + printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3); 474 + 475 printk("\n"); 476 } 477 478 + 479 + static int dst_type_print (u8 type) 480 { 481 char *otype; 482 switch (type) { 483 case DST_TYPE_IS_SAT: 484 otype = "satellite"; 485 break; 486 + 487 case DST_TYPE_IS_TERR: 488 otype = "terrestrial"; 489 break; 490 + 491 case DST_TYPE_IS_CABLE: 492 otype = "cable"; 493 break; 494 + 495 default: 496 printk("%s: invalid dst type %d\n", __FUNCTION__, type); 497 return -EINVAL; 498 } 499 printk("DST type : %s\n", otype); 500 + 501 return 0; 502 } 503 504 + /* 505 + Known cards list 506 + Satellite 507 + ------------------- 508 + 509 + VP-1020 DST-MOT LG(old), TS=188 510 + 511 + VP-1020 DST-03T LG(new), TS=204 512 + VP-1022 DST-03T LG(new), TS=204 513 + VP-1025 DST-03T LG(new), TS=204 514 + 515 + VP-1030 DSTMCI, LG(new), TS=188 516 + VP-1032 DSTMCI, LG(new), TS=188 517 + 518 + Cable 519 + ------------------- 520 + VP-2030 DCT-CI, Samsung, TS=204 521 + VP-2021 DCT-CI, Unknown, TS=204 522 + VP-2031 DCT-CI, Philips, TS=188 523 + VP-2040 DCT-CI, Philips, TS=188, with CA daughter board 524 + VP-2040 DCT-CI, Philips, TS=204, without CA daughter board 525 + 526 + Terrestrial 527 + ------------------- 528 + VP-3050 DTTNXT TS=188 529 + VP-3040 DTT-CI, Philips, TS=188 530 + VP-3040 DTT-CI, Philips, TS=204 531 + 532 + ATSC 533 + ------------------- 534 + VP-3220 ATSCDI, TS=188 535 + VP-3250 ATSCAD, TS=188 536 + 537 + */ 538 + 539 + struct dst_types dst_tlist[] = { 540 + { 541 + .device_id = "DST-020", 542 + .offset = 0, 543 + .dst_type = DST_TYPE_IS_SAT, 544 + .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, 545 + .dst_feature = 0 546 + }, /* obsolete */ 547 + 548 + { 549 + .device_id = "DST-030", 550 + .offset = 0, 551 + .dst_type = DST_TYPE_IS_SAT, 552 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, 553 + .dst_feature = 0 554 + }, /* obsolete */ 555 + 556 + { 557 + .device_id = "DST-03T", 558 + .offset = 0, 559 + .dst_type = DST_TYPE_IS_SAT, 560 + .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 561 + .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 562 + | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO 563 + }, 564 + 565 + { 566 + .device_id = "DST-MOT", 567 + .offset = 0, 568 + .dst_type = DST_TYPE_IS_SAT, 569 + .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, 570 + .dst_feature = 0 571 + }, /* obsolete */ 572 + 573 + { 574 + .device_id = "DST-CI", 575 + .offset = 1, 576 + .dst_type = DST_TYPE_IS_SAT, 577 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, 578 + .dst_feature = DST_TYPE_HAS_CA 579 + }, /* unknown to vendor */ 580 + 581 + { 582 + .device_id = "DSTMCI", 583 + .offset = 1, 584 + .dst_type = DST_TYPE_IS_SAT, 585 + .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2, 586 + .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 587 + | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC 588 + }, 589 + 590 + { 591 + .device_id = "DSTFCI", 592 + .offset = 1, 593 + .dst_type = DST_TYPE_IS_SAT, 594 + .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, 595 + .dst_feature = 0 596 + }, /* unknown to vendor */ 597 + 598 + { 599 + .device_id = "DCT-CI", 600 + .offset = 1, 601 + .dst_type = DST_TYPE_IS_CABLE, 602 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2, 603 + .dst_feature = DST_TYPE_HAS_CA 604 + }, 605 + 606 + { 607 + .device_id = "DCTNEW", 608 + .offset = 1, 609 + .dst_type = DST_TYPE_IS_CABLE, 610 + .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3, 611 + .dst_feature = 0 612 + }, 613 + 614 + { 615 + .device_id = "DTT-CI", 616 + .offset = 1, 617 + .dst_type = DST_TYPE_IS_TERR, 618 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 619 + .dst_feature = 0 620 + }, 621 + 622 + { 623 + .device_id = "DTTDIG", 624 + .offset = 1, 625 + .dst_type = DST_TYPE_IS_TERR, 626 + .type_flags = DST_TYPE_HAS_FW_2, 627 + .dst_feature = 0 628 + }, 629 + 630 + { 631 + .device_id = "DTTNXT", 632 + .offset = 1, 633 + .dst_type = DST_TYPE_IS_TERR, 634 + .type_flags = DST_TYPE_HAS_FW_2, 635 + .dst_feature = DST_TYPE_HAS_ANALOG 636 + }, 637 + 638 + { 639 + .device_id = "ATSCDI", 640 + .offset = 1, 641 + .dst_type = DST_TYPE_IS_ATSC, 642 + .type_flags = DST_TYPE_HAS_FW_2, 643 + .dst_feature = 0 644 + }, 645 + 646 + { 647 + .device_id = "ATSCAD", 648 + .offset = 1, 649 + .dst_type = DST_TYPE_IS_ATSC, 650 + .type_flags = DST_TYPE_HAS_FW_2, 651 + .dst_feature = 0 652 + }, 653 + 654 + { } 655 + 656 + }; 657 + 658 + 659 + static int dst_get_device_id(struct dst_state *state) 660 { 661 + u8 reply; 662 + 663 int i; 664 + struct dst_types *p_dst_type; 665 + u8 use_dst_type = 0; 666 + u32 use_type_flags = 0; 667 668 + static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 669 670 + device_type[7] = dst_check_sum(device_type, 7); 671 + 672 + if (write_dst(state, device_type, FIXED_COMM)) 673 + return -1; /* Write failed */ 674 + 675 + if ((dst_pio_disable(state)) < 0) 676 + return -1; 677 + 678 + if (read_dst(state, &reply, GET_ACK)) 679 + return -1; /* Read failure */ 680 + 681 + if (reply != ACK) { 682 + dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply); 683 + return -1; /* Unack'd write */ 684 } 685 + 686 + if (!dst_wait_dst_ready(state, DEVICE_INIT)) 687 + return -1; /* DST not ready yet */ 688 + 689 + if (read_dst(state, state->rxbuffer, FIXED_COMM)) 690 + return -1; 691 + 692 + dst_pio_disable(state); 693 + 694 + if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 695 + dprintk("%s: Checksum failure! \n", __FUNCTION__); 696 + return -1; /* Checksum failure */ 697 } 698 + 699 + state->rxbuffer[7] = '\0'; 700 + 701 + for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) { 702 + if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) { 703 + use_type_flags = p_dst_type->type_flags; 704 + use_dst_type = p_dst_type->dst_type; 705 + 706 + /* Card capabilities */ 707 + state->dst_hw_cap = p_dst_type->dst_feature; 708 + printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id); 709 + 710 break; 711 } 712 } 713 + 714 + if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) { 715 + printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]); 716 + printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__); 717 use_dst_type = DST_TYPE_IS_SAT; 718 use_type_flags = DST_TYPE_HAS_SYMDIV; 719 } 720 721 + dst_type_print(use_dst_type); 722 state->type_flags = use_type_flags; 723 state->dst_type = use_dst_type; 724 dst_type_flags_print(state->type_flags); ··· 559 if (state->type_flags & DST_TYPE_HAS_TS204) { 560 dst_packsize(state, 204); 561 } 562 + 563 return 0; 564 } 565 566 + static int dst_probe(struct dst_state *state) 567 { 568 + if ((rdc_8820_reset(state)) < 0) { 569 + dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__); 570 + return -1; 571 + } 572 + msleep(4000); 573 + if ((dst_comm_init(state)) < 0) { 574 + dprintk("%s: DST Initialization Failed.\n", __FUNCTION__); 575 + return -1; 576 + } 577 578 + if (dst_get_device_id(state) < 0) { 579 + dprintk("%s: unknown device.\n", __FUNCTION__); 580 + return -1; 581 } 582 + 583 + return 0; 584 + } 585 + 586 + int dst_command(struct dst_state* state, u8 * data, u8 len) 587 + { 588 + u8 reply; 589 + if ((dst_comm_init(state)) < 0) { 590 + dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__); 591 + return -1; 592 } 593 + 594 + if (write_dst(state, data, len)) { 595 + if (verbose > 1) 596 + dprintk("%s: Tring to recover.. \n", __FUNCTION__); 597 + if ((dst_error_recovery(state)) < 0) { 598 + dprintk("%s: Recovery Failed.\n", __FUNCTION__); 599 + return -1; 600 + } 601 + return -1; 602 + } 603 + if ((dst_pio_disable(state)) < 0) { 604 + dprintk("%s: PIO Disable Failed.\n", __FUNCTION__); 605 + return -1; 606 + } 607 + 608 + if (read_dst(state, &reply, GET_ACK)) { 609 + if (verbose > 1) 610 + dprintk("%s: Trying to recover.. \n", __FUNCTION__); 611 + if ((dst_error_recovery(state)) < 0) { 612 + dprintk("%s: Recovery Failed.\n", __FUNCTION__); 613 + return -1; 614 + } 615 + return -1; 616 + } 617 + 618 + if (reply != ACK) { 619 + dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply); 620 + return -1; 621 } 622 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 623 return 0; 624 + if (!dst_wait_dst_ready(state, NO_DELAY)) 625 + return -1; 626 + 627 + if (read_dst(state, state->rxbuffer, FIXED_COMM)) { 628 + if (verbose > 1) 629 + dprintk("%s: Trying to recover.. \n", __FUNCTION__); 630 + if ((dst_error_recovery(state)) < 0) { 631 + dprintk("%s: Recovery failed.\n", __FUNCTION__); 632 + return -1; 633 + } 634 + return -1; 635 } 636 + 637 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 638 dprintk("%s: checksum failure\n", __FUNCTION__); 639 + return -1; 640 } 641 + 642 return 0; 643 } 644 + EXPORT_SYMBOL(dst_command); 645 646 static int dst_get_signal(struct dst_state* state) 647 { ··· 646 paket[4] = 0; 647 else 648 paket[4] = 1; 649 + 650 if (state->tone == SEC_TONE_ON) 651 + paket[2] = 0x02; 652 else 653 paket[2] = 0; 654 + if (state->minicmd == SEC_MINI_A) 655 + paket[3] = 0x02; 656 + else 657 + paket[3] = 0; 658 + 659 + paket[7] = dst_check_sum (paket, 7); 660 dst_command(state, paket, 8); 661 return 0; 662 } ··· 658 static int dst_get_tuna(struct dst_state* state) 659 { 660 int retval; 661 + 662 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) 663 return 0; 664 + 665 state->diseq_flags &= ~(HAS_LOCK); 666 + if (!dst_wait_dst_ready(state, NO_DELAY)) 667 return 0; 668 + 669 + msleep(10); 670 + 671 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 672 /* how to get variable length reply ???? */ 673 retval = read_dst(state, state->rx_tuna, 10); 674 } else { 675 + retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 676 } 677 + 678 if (retval < 0) { 679 dprintk("%s: read not successful\n", __FUNCTION__); 680 return 0; 681 } 682 + 683 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 684 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 685 dprintk("%s: checksum failure?\n", __FUNCTION__); ··· 717 dst_set_voltage(fe, SEC_VOLTAGE_13); 718 } 719 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 720 + 721 + if ((dst_comm_init(state)) < 0) { 722 + dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__); 723 + return -1; 724 + } 725 + 726 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 727 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 728 retval = write_dst(state, &state->tx_tuna[0], 10); 729 + 730 } else { 731 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); 732 + retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); 733 } 734 if (retval < 0) { 735 + dst_pio_disable(state); 736 dprintk("%s: write not successful\n", __FUNCTION__); 737 return retval; 738 } 739 + 740 + if ((dst_pio_disable(state)) < 0) { 741 + dprintk("%s: DST PIO disable failed !\n", __FUNCTION__); 742 + return -1; 743 } 744 + 745 + if ((read_dst(state, &reply, GET_ACK) < 0)) { 746 + dprintk("%s: read verify not successful.\n", __FUNCTION__); 747 + return -1; 748 + } 749 + if (reply != ACK) { 750 + dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply); 751 return 0; 752 } 753 state->diseq_flags |= ATTEMPT_TUNE; 754 + 755 return dst_get_tuna(state); 756 } 757 ··· 796 need_cmd = 1; 797 state->diseq_flags |= HAS_POWER; 798 break; 799 + 800 case SEC_VOLTAGE_18: 801 if ((state->diseq_flags & HAS_POWER) == 0) 802 need_cmd = 1; 803 state->diseq_flags |= HAS_POWER; 804 val[8] |= 0x40; 805 break; 806 + 807 case SEC_VOLTAGE_OFF: 808 need_cmd = 1; 809 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); 810 break; 811 + 812 default: 813 return -EINVAL; 814 } 815 + if (need_cmd) 816 dst_tone_power_cmd(state); 817 + 818 return 0; 819 } 820 ··· 832 switch (tone) { 833 case SEC_TONE_OFF: 834 break; 835 + 836 case SEC_TONE_ON: 837 val[8] |= 1; 838 break; 839 + 840 default: 841 return -EINVAL; 842 } 843 dst_tone_power_cmd(state); 844 + 845 return 0; 846 } 847 ··· 913 struct dst_state* state = (struct dst_state*) fe->demodulator_priv; 914 915 dst_set_freq(state, p->frequency); 916 + if (verbose > 4) 917 + dprintk("Set Frequency = [%d]\n", p->frequency); 918 + 919 dst_set_inversion(state, p->inversion); 920 if (state->dst_type == DST_TYPE_IS_SAT) { 921 dst_set_fec(state, p->u.qpsk.fec_inner); 922 dst_set_symbolrate(state, p->u.qpsk.symbol_rate); 923 + if (verbose > 4) 924 + dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate); 925 + 926 } else if (state->dst_type == DST_TYPE_IS_TERR) { 927 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 928 } else if (state->dst_type == DST_TYPE_IS_CABLE) { ··· 958 static struct dvb_frontend_ops dst_dvbs_ops; 959 static struct dvb_frontend_ops dst_dvbc_ops; 960 961 + struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) 962 { 963 964 + /* check if the ASIC is there */ 965 + if (dst_probe(state) < 0) { 966 + if (state) 967 + kfree(state); 968 969 + return NULL; 970 + } 971 /* determine settings based on type */ 972 switch (state->dst_type) { 973 case DST_TYPE_IS_TERR: 974 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 975 break; 976 + 977 case DST_TYPE_IS_CABLE: 978 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 979 break; 980 + 981 case DST_TYPE_IS_SAT: 982 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 983 break; 984 + 985 default: 986 + printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__); 987 + if (state) 988 + kfree(state); 989 + 990 + return NULL; 991 } 992 993 /* create dvb_frontend */ 994 state->frontend.ops = &state->ops; 995 state->frontend.demodulator_priv = state; 996 997 + return state; /* Manu (DST is a card not a frontend) */ 998 } 999 + 1000 + EXPORT_SYMBOL(dst_attach); 1001 1002 static struct dvb_frontend_ops dst_dvbt_ops = { 1003 ··· 1051 .read_signal_strength = dst_read_signal_strength, 1052 .read_snr = dst_read_snr, 1053 1054 + .diseqc_send_burst = dst_set_tone, 1055 .diseqc_send_master_cmd = dst_set_diseqc, 1056 .set_voltage = dst_set_voltage, 1057 .set_tone = dst_set_tone, ··· 1082 .read_snr = dst_read_snr, 1083 }; 1084 1085 1086 + MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); 1087 + MODULE_AUTHOR("Jamie Honan, Manu Abraham"); 1088 + MODULE_LICENSE("GPL");
-40
drivers/media/dvb/bt8xx/dst.h
··· 1 - /* 2 - Frontend-driver for TwinHan DST Frontend 3 - 4 - Copyright (C) 2003 Jamie Honan 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 - 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 - 23 - #ifndef DST_H 24 - #define DST_H 25 - 26 - #include <linux/dvb/frontend.h> 27 - #include <linux/device.h> 28 - #include "bt878.h" 29 - 30 - struct dst_config 31 - { 32 - /* the demodulator's i2c address */ 33 - u8 demod_address; 34 - }; 35 - 36 - extern struct dvb_frontend* dst_attach(const struct dst_config* config, 37 - struct i2c_adapter* i2c, 38 - struct bt878 *bt); 39 - 40 - #endif // DST_H
···
+868
drivers/media/dvb/bt8xx/dst_ca.c
···
··· 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 + 22 + 23 + #include <linux/kernel.h> 24 + #include <linux/module.h> 25 + #include <linux/init.h> 26 + #include <linux/string.h> 27 + 28 + #include <linux/dvb/ca.h> 29 + #include "dvbdev.h" 30 + #include "dvb_frontend.h" 31 + 32 + #include "dst_ca.h" 33 + #include "dst_common.h" 34 + 35 + static unsigned int verbose = 1; 36 + module_param(verbose, int, 0644); 37 + MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 38 + 39 + static unsigned int debug = 1; 40 + module_param(debug, int, 0644); 41 + MODULE_PARM_DESC(dst_ca_debug, "debug messages, default is 0 (yes)"); 42 + 43 + static unsigned int session; 44 + module_param(session, int, 0644); 45 + MODULE_PARM_DESC(session, "Support for hardware that has multiple sessions, default 0"); 46 + 47 + static unsigned int new_ca; 48 + module_param(new_ca, int, 0644); 49 + MODULE_PARM_DESC(new_ca, "Support for the new CA interface firmware, default 0"); 50 + 51 + #define dprintk if (debug) printk 52 + 53 + 54 + static int ca_set_slot_descr(void) 55 + { 56 + /* We could make this more graceful ? */ 57 + return -EOPNOTSUPP; 58 + } 59 + 60 + static int ca_set_pid(void) 61 + { 62 + /* We could make this more graceful ? */ 63 + return -EOPNOTSUPP; 64 + } 65 + 66 + 67 + static int put_checksum(u8 *check_string, int length) 68 + { 69 + u8 i = 0, checksum = 0; 70 + 71 + if (verbose > 3) { 72 + dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__); 73 + dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length); 74 + 75 + dprintk("%s: String=[", __FUNCTION__); 76 + } 77 + while (i < length) { 78 + if (verbose > 3) 79 + dprintk(" %02x", check_string[i]); 80 + checksum += check_string[i]; 81 + i++; 82 + } 83 + if (verbose > 3) { 84 + dprintk(" ]\n"); 85 + dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum); 86 + } 87 + check_string[length] = ~checksum + 1; 88 + if (verbose > 3) { 89 + dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]); 90 + dprintk("%s: ==========================================================================\n", __FUNCTION__); 91 + } 92 + 93 + return 0; 94 + } 95 + 96 + static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) 97 + { 98 + u8 reply; 99 + 100 + dst_comm_init(state); 101 + msleep(65); 102 + 103 + if (write_dst(state, data, len)) { 104 + dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__); 105 + dst_error_recovery(state); 106 + return -1; 107 + } 108 + 109 + if ((dst_pio_disable(state)) < 0) { 110 + dprintk("%s: DST PIO disable failed.\n", __FUNCTION__); 111 + return -1; 112 + } 113 + 114 + if (read_dst(state, &reply, GET_ACK) < 0) { 115 + dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__); 116 + dst_error_recovery(state); 117 + return -1; 118 + } 119 + 120 + if (read) { 121 + if (! dst_wait_dst_ready(state, LONG_DELAY)) { 122 + dprintk("%s: 8820 not ready\n", __FUNCTION__); 123 + return -1; 124 + } 125 + 126 + if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ 127 + dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__); 128 + dst_error_recovery(state); 129 + return -1; 130 + } 131 + } 132 + 133 + return 0; 134 + } 135 + 136 + 137 + static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read) 138 + { 139 + u8 dst_ca_comm_err = 0; 140 + 141 + while (dst_ca_comm_err < RETRIES) { 142 + dst_comm_init(state); 143 + if (verbose > 2) 144 + dprintk("%s: Put Command\n", __FUNCTION__); 145 + if (dst_ci_command(state, data, ca_string, len, read)) { // If error 146 + dst_error_recovery(state); 147 + dst_ca_comm_err++; // work required here. 148 + } 149 + break; 150 + } 151 + 152 + return 0; 153 + } 154 + 155 + 156 + 157 + static int ca_get_app_info(struct dst_state *state) 158 + { 159 + static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; 160 + 161 + put_checksum(&command[0], command[0]); 162 + if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) { 163 + dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); 164 + return -1; 165 + } 166 + if (verbose > 1) { 167 + dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__); 168 + 169 + dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__); 170 + dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n", 171 + __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9], 172 + (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[11])); 173 + dprintk("%s: ==================================================================================================\n", __FUNCTION__); 174 + } 175 + 176 + return 0; 177 + } 178 + 179 + static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) 180 + { 181 + int i; 182 + u8 slot_cap[256]; 183 + static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff}; 184 + 185 + put_checksum(&slot_command[0], slot_command[0]); 186 + if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) { 187 + dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); 188 + return -1; 189 + } 190 + if (verbose > 1) 191 + dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__); 192 + 193 + /* Will implement the rest soon */ 194 + 195 + if (verbose > 1) { 196 + dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]); 197 + dprintk("===================================\n"); 198 + for (i = 0; i < 8; i++) 199 + dprintk(" %d", slot_cap[i]); 200 + dprintk("\n"); 201 + } 202 + 203 + p_ca_caps->slot_num = 1; 204 + p_ca_caps->slot_type = 1; 205 + p_ca_caps->descr_num = slot_cap[7]; 206 + p_ca_caps->descr_type = 1; 207 + 208 + 209 + if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) { 210 + return -EFAULT; 211 + } 212 + 213 + return 0; 214 + } 215 + 216 + 217 + static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 218 + { 219 + return -EOPNOTSUPP; 220 + } 221 + 222 + 223 + static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) 224 + { 225 + int i; 226 + static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 227 + 228 + u8 *slot_info = state->rxbuffer; 229 + 230 + put_checksum(&slot_command[0], 7); 231 + if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { 232 + dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); 233 + return -1; 234 + } 235 + if (verbose > 1) 236 + dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__); 237 + 238 + /* Will implement the rest soon */ 239 + 240 + if (verbose > 1) { 241 + dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]); 242 + dprintk("===================================\n"); 243 + for (i = 0; i < 8; i++) 244 + dprintk(" %d", slot_info[i]); 245 + dprintk("\n"); 246 + } 247 + 248 + if (slot_info[4] & 0x80) { 249 + p_ca_slot_info->flags = CA_CI_MODULE_PRESENT; 250 + p_ca_slot_info->num = 1; 251 + p_ca_slot_info->type = CA_CI; 252 + } 253 + else if (slot_info[4] & 0x40) { 254 + p_ca_slot_info->flags = CA_CI_MODULE_READY; 255 + p_ca_slot_info->num = 1; 256 + p_ca_slot_info->type = CA_CI; 257 + } 258 + else { 259 + p_ca_slot_info->flags = 0; 260 + } 261 + 262 + if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) { 263 + return -EFAULT; 264 + } 265 + 266 + return 0; 267 + } 268 + 269 + 270 + 271 + 272 + static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 273 + { 274 + u8 i = 0; 275 + u32 command = 0; 276 + 277 + if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 278 + return -EFAULT; 279 + 280 + 281 + if (p_ca_message->msg) { 282 + if (verbose > 3) 283 + dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]); 284 + 285 + for (i = 0; i < 3; i++) { 286 + command = command | p_ca_message->msg[i]; 287 + if (i < 2) 288 + command = command << 8; 289 + } 290 + if (verbose > 3) 291 + dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command); 292 + 293 + switch (command) { 294 + case CA_APP_INFO: 295 + memcpy(p_ca_message->msg, state->messages, 128); 296 + if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) 297 + return -EFAULT; 298 + break; 299 + } 300 + } 301 + 302 + return 0; 303 + } 304 + 305 + static int handle_en50221_tag(struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) 306 + { 307 + if (session) { 308 + hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */ 309 + hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */ 310 + } 311 + else { 312 + hw_buffer->msg[2] = 0x03; 313 + hw_buffer->msg[3] = 0x00; 314 + } 315 + return 0; 316 + } 317 + 318 + static int debug_8820_buffer(struct ca_msg *hw_buffer) 319 + { 320 + unsigned int i; 321 + 322 + dprintk("%s:Debug=[", __FUNCTION__); 323 + for (i = 0; i < (hw_buffer->msg[0] + 1); i++) 324 + dprintk(" %02x", hw_buffer->msg[i]); 325 + dprintk("]\n"); 326 + 327 + return 0; 328 + } 329 + 330 + static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply) 331 + { 332 + if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) { 333 + dprintk("%s: DST-CI Command failed.\n", __FUNCTION__); 334 + dprintk("%s: Resetting DST.\n", __FUNCTION__); 335 + rdc_reset_state(state); 336 + return -1; 337 + } 338 + if (verbose > 2) 339 + dprintk("%s: DST-CI Command succes.\n", __FUNCTION__); 340 + 341 + return 0; 342 + } 343 + 344 + 345 + static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) 346 + { 347 + u32 hw_offset, buf_offset, i, k; 348 + u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0; 349 + u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0; 350 + 351 + if (verbose > 3) 352 + dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length ); 353 + 354 + handle_en50221_tag(p_ca_message, hw_buffer); /* EN50221 tag */ 355 + 356 + /* Handle the length field (variable) */ 357 + if (!(p_ca_message->msg[3] & 0x80)) { /* Length = 1 */ 358 + length = p_ca_message->msg[3] & 0x7f; 359 + words = 0; /* domi's suggestion */ 360 + } 361 + else { /* Length = words */ 362 + words = p_ca_message->msg[3] & 0x7f; 363 + for (i = 0; i < words; i++) { 364 + length = length << 8; 365 + length = length | p_ca_message->msg[4 + i]; 366 + } 367 + } 368 + if (verbose > 4) { 369 + dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words); 370 + 371 + /* Debug Input string */ 372 + for (i = 0; i < length; i++) 373 + dprintk(" %02x", p_ca_message->msg[i]); 374 + dprintk("]\n"); 375 + } 376 + 377 + hw_offset = 7; 378 + buf_offset = words + 4; 379 + 380 + /* Program Header */ 381 + if (verbose > 4) 382 + dprintk("\n%s:Program Header=[", __FUNCTION__); 383 + for (i = 0; i < 6; i++) { 384 + hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; 385 + if (verbose > 4) 386 + dprintk(" %02x", p_ca_message->msg[buf_offset]); 387 + hw_offset++, buf_offset++, hw_buffer_length++; 388 + } 389 + if (verbose > 4) 390 + dprintk("]\n"); 391 + 392 + program_info_length = 0; 393 + program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9]; 394 + if (verbose > 4) 395 + dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n", 396 + __FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset); 397 + 398 + if (program_info_length && (program_info_length < 256)) { /* If program_info_length */ 399 + hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f; /* req only 4 bits */ 400 + hw_buffer->msg[12] = hw_buffer->msg[12] + 1; /* increment! ASIC bug! */ 401 + 402 + if (p_ca_message->msg[buf_offset + 1] == 0x09) { /* Check CA descriptor */ 403 + found_prog_ca_desc = 1; 404 + if (verbose > 4) 405 + dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__); 406 + } 407 + 408 + if (found_prog_ca_desc) { /* Command only if CA descriptor */ 409 + hw_buffer->msg[13] = p_ca_message->msg[buf_offset]; /* CA PMT command ID */ 410 + hw_offset++, buf_offset++, hw_buffer_length++; 411 + } 412 + 413 + /* Program descriptors */ 414 + if (verbose > 4) { 415 + dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset); 416 + dprintk("%s:Program descriptors=[", __FUNCTION__); 417 + } 418 + while (program_info_length && !error_condition) { /* Copy prog descriptors */ 419 + if (program_info_length > p_ca_message->length) { /* Error situation */ 420 + dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n", 421 + __FUNCTION__, __LINE__, program_info_length); 422 + dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__); 423 + error_condition = 1; 424 + break; 425 + } 426 + 427 + hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; 428 + dprintk(" %02x", p_ca_message->msg[buf_offset]); 429 + hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--; 430 + } 431 + if (verbose > 4) { 432 + dprintk("]\n"); 433 + dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset); 434 + } 435 + if (found_prog_ca_desc) { 436 + if (!reply) { 437 + hw_buffer->msg[13] = 0x01; /* OK descrambling */ 438 + if (verbose > 1) 439 + dprintk("CA PMT Command = OK Descrambling\n"); 440 + } 441 + else { 442 + hw_buffer->msg[13] = 0x02; /* Ok MMI */ 443 + if (verbose > 1) 444 + dprintk("CA PMT Command = Ok MMI\n"); 445 + } 446 + if (query) { 447 + hw_buffer->msg[13] = 0x03; /* Query */ 448 + if (verbose > 1) 449 + dprintk("CA PMT Command = CA PMT query\n"); 450 + } 451 + } 452 + } 453 + else { 454 + hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0; /* Don't write to ASIC */ 455 + hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00; 456 + } 457 + if (verbose > 4) 458 + dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n", 459 + __FUNCTION__, p_ca_message->length, buf_offset, hw_offset); 460 + 461 + while ((buf_offset < p_ca_message->length) && !error_condition) { 462 + /* Bail out in case of an indefinite loop */ 463 + if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) { 464 + dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n", 465 + __FUNCTION__, __LINE__, program_info_length, buf_offset); 466 + 467 + dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__); 468 + error_condition = 1; 469 + break; 470 + } 471 + 472 + /* Stream Header */ 473 + 474 + for (k = 0; k < 5; k++) { 475 + hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k]; 476 + } 477 + 478 + es_info_length = 0; 479 + es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4]; 480 + 481 + if (verbose > 4) { 482 + dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__, 483 + p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1], 484 + p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3], 485 + p_ca_message->msg[buf_offset + 4]); 486 + 487 + dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__, 488 + p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length, 489 + p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset); 490 + } 491 + 492 + hw_buffer->msg[hw_offset + 3] &= 0x0f; /* req only 4 bits */ 493 + 494 + if (found_prog_ca_desc) { 495 + hw_buffer->msg[hw_offset + 3] = 0x00; 496 + hw_buffer->msg[hw_offset + 4] = 0x00; 497 + } 498 + 499 + hw_offset += 5, buf_offset += 5, hw_buffer_length += 5; 500 + 501 + /* Check for CA descriptor */ 502 + if (p_ca_message->msg[buf_offset + 1] == 0x09) { 503 + if (verbose > 4) 504 + dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__); 505 + found_stream_ca_desc = 1; 506 + } 507 + 508 + /* ES descriptors */ 509 + 510 + if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) { 511 + // if (!ca_pmt_done) { 512 + hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; /* CA PMT cmd(es) */ 513 + if (verbose > 4) 514 + printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]); 515 + // hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1; 516 + hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--; 517 + // } 518 + if (verbose > 4) 519 + dprintk("%s:----->ES descriptors=[", __FUNCTION__); 520 + 521 + while (es_info_length && !error_condition) { /* ES descriptors */ 522 + if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) { 523 + if (verbose > 4) { 524 + dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n", 525 + __FUNCTION__, __LINE__, es_info_length, buf_offset); 526 + 527 + dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__); 528 + } 529 + error_condition = 1; 530 + break; 531 + } 532 + 533 + hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; 534 + if (verbose > 3) 535 + dprintk("%02x ", hw_buffer->msg[hw_offset]); 536 + hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--; 537 + } 538 + found_stream_ca_desc = 0; /* unset for new streams */ 539 + dprintk("]\n"); 540 + } 541 + } 542 + 543 + /* MCU Magic words */ 544 + 545 + hw_buffer_length += 7; 546 + hw_buffer->msg[0] = hw_buffer_length; 547 + hw_buffer->msg[1] = 64; 548 + hw_buffer->msg[4] = 3; 549 + hw_buffer->msg[5] = hw_buffer->msg[0] - 7; 550 + hw_buffer->msg[6] = 0; 551 + 552 + 553 + /* Fix length */ 554 + hw_buffer->length = hw_buffer->msg[0]; 555 + 556 + put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]); 557 + /* Do the actual write */ 558 + if (verbose > 4) { 559 + dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__); 560 + dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length); 561 + } 562 + /* Only for debugging! */ 563 + if (verbose > 2) 564 + debug_8820_buffer(hw_buffer); 565 + if (verbose > 3) 566 + dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply); 567 + write_to_8820(state, hw_buffer, reply); 568 + 569 + return 0; 570 + } 571 + 572 + /* Board supports CA PMT reply ? */ 573 + static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) 574 + { 575 + int ca_pmt_reply_test = 0; 576 + 577 + /* Do test board */ 578 + /* Not there yet but soon */ 579 + 580 + 581 + /* CA PMT Reply capable */ 582 + if (ca_pmt_reply_test) { 583 + if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) { 584 + dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__); 585 + return -1; 586 + } 587 + 588 + /* Process CA PMT Reply */ 589 + /* will implement soon */ 590 + dprintk("%s: Not there yet\n", __FUNCTION__); 591 + } 592 + /* CA PMT Reply not capable */ 593 + if (!ca_pmt_reply_test) { 594 + if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) { 595 + dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__); 596 + return -1; 597 + } 598 + if (verbose > 3) 599 + dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__); 600 + /* put a dummy message */ 601 + 602 + } 603 + return 0; 604 + } 605 + 606 + static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 607 + { 608 + int i = 0; 609 + unsigned int ca_message_header_len; 610 + 611 + u32 command = 0; 612 + struct ca_msg *hw_buffer; 613 + 614 + if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 615 + printk("%s: Memory allocation failure\n", __FUNCTION__); 616 + return -ENOMEM; 617 + } 618 + if (verbose > 3) 619 + dprintk("%s\n", __FUNCTION__); 620 + 621 + if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 622 + return -EFAULT; 623 + 624 + if (p_ca_message->msg) { 625 + ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ 626 + /* EN50221 tag */ 627 + command = 0; 628 + 629 + for (i = 0; i < 3; i++) { 630 + command = command | p_ca_message->msg[i]; 631 + if (i < 2) 632 + command = command << 8; 633 + } 634 + if (verbose > 3) 635 + dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command); 636 + 637 + switch (command) { 638 + case CA_PMT: 639 + if (verbose > 3) 640 + dprintk("Command = SEND_CA_PMT\n"); 641 + if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { 642 + dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__); 643 + return -1; 644 + } 645 + if (verbose > 3) 646 + dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__); 647 + // retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0); 648 + 649 + break; 650 + 651 + case CA_PMT_REPLY: 652 + if (verbose > 3) 653 + dprintk("Command = CA_PMT_REPLY\n"); 654 + /* Have to handle the 2 basic types of cards here */ 655 + if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { 656 + dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__); 657 + return -1; 658 + } 659 + if (verbose > 3) 660 + dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__); 661 + 662 + /* Certain boards do behave different ? */ 663 + // retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1); 664 + 665 + case CA_APP_INFO_ENQUIRY: // only for debugging 666 + if (verbose > 3) 667 + dprintk("%s: Getting Cam Application information\n", __FUNCTION__); 668 + 669 + if ((ca_get_app_info(state)) < 0) { 670 + dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__); 671 + return -1; 672 + } 673 + if (verbose > 3) 674 + printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__); 675 + 676 + break; 677 + } 678 + } 679 + return 0; 680 + } 681 + 682 + static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 683 + { 684 + struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 685 + struct dst_state* state = (struct dst_state*) dvbdev->priv; 686 + struct ca_slot_info *p_ca_slot_info; 687 + struct ca_caps *p_ca_caps; 688 + struct ca_msg *p_ca_message; 689 + 690 + if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 691 + printk("%s: Memory allocation failure\n", __FUNCTION__); 692 + return -ENOMEM; 693 + } 694 + 695 + if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) { 696 + printk("%s: Memory allocation failure\n", __FUNCTION__); 697 + return -ENOMEM; 698 + } 699 + 700 + if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) { 701 + printk("%s: Memory allocation failure\n", __FUNCTION__); 702 + return -ENOMEM; 703 + } 704 + 705 + /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ 706 + switch (cmd) { 707 + case CA_SEND_MSG: 708 + if (verbose > 1) 709 + dprintk("%s: Sending message\n", __FUNCTION__); 710 + if ((ca_send_message(state, p_ca_message, arg)) < 0) { 711 + dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__); 712 + return -1; 713 + } 714 + 715 + break; 716 + 717 + case CA_GET_MSG: 718 + if (verbose > 1) 719 + dprintk("%s: Getting message\n", __FUNCTION__); 720 + if ((ca_get_message(state, p_ca_message, arg)) < 0) { 721 + dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__); 722 + return -1; 723 + } 724 + if (verbose > 1) 725 + dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__); 726 + 727 + break; 728 + 729 + case CA_RESET: 730 + if (verbose > 1) 731 + dprintk("%s: Resetting DST\n", __FUNCTION__); 732 + dst_error_bailout(state); 733 + msleep(4000); 734 + 735 + break; 736 + 737 + case CA_GET_SLOT_INFO: 738 + if (verbose > 1) 739 + dprintk("%s: Getting Slot info\n", __FUNCTION__); 740 + if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { 741 + dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__); 742 + return -1; 743 + } 744 + if (verbose > 1) 745 + dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__); 746 + 747 + break; 748 + 749 + case CA_GET_CAP: 750 + if (verbose > 1) 751 + dprintk("%s: Getting Slot capabilities\n", __FUNCTION__); 752 + if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { 753 + dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__); 754 + return -1; 755 + } 756 + if (verbose > 1) 757 + dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__); 758 + 759 + break; 760 + 761 + case CA_GET_DESCR_INFO: 762 + if (verbose > 1) 763 + dprintk("%s: Getting descrambler description\n", __FUNCTION__); 764 + if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { 765 + dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__); 766 + return -1; 767 + } 768 + if (verbose > 1) 769 + dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__); 770 + 771 + break; 772 + 773 + case CA_SET_DESCR: 774 + if (verbose > 1) 775 + dprintk("%s: Setting descrambler\n", __FUNCTION__); 776 + if ((ca_set_slot_descr()) < 0) { 777 + dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__); 778 + return -1; 779 + } 780 + if (verbose > 1) 781 + dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__); 782 + 783 + break; 784 + 785 + case CA_SET_PID: 786 + if (verbose > 1) 787 + dprintk("%s: Setting PID\n", __FUNCTION__); 788 + if ((ca_set_pid()) < 0) { 789 + dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__); 790 + return -1; 791 + } 792 + if (verbose > 1) 793 + dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__); 794 + 795 + default: 796 + return -EOPNOTSUPP; 797 + }; 798 + 799 + return 0; 800 + } 801 + 802 + static int dst_ca_open(struct inode *inode, struct file *file) 803 + { 804 + if (verbose > 4) 805 + dprintk("%s:Device opened [%p]\n", __FUNCTION__, file); 806 + try_module_get(THIS_MODULE); 807 + 808 + return 0; 809 + } 810 + 811 + static int dst_ca_release(struct inode *inode, struct file *file) 812 + { 813 + if (verbose > 4) 814 + dprintk("%s:Device closed.\n", __FUNCTION__); 815 + module_put(THIS_MODULE); 816 + 817 + return 0; 818 + } 819 + 820 + static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset) 821 + { 822 + int bytes_read = 0; 823 + 824 + if (verbose > 4) 825 + dprintk("%s:Device read.\n", __FUNCTION__); 826 + 827 + return bytes_read; 828 + } 829 + 830 + static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset) 831 + { 832 + if (verbose > 4) 833 + dprintk("%s:Device write.\n", __FUNCTION__); 834 + 835 + return 0; 836 + } 837 + 838 + static struct file_operations dst_ca_fops = { 839 + .owner = THIS_MODULE, 840 + .ioctl = (void *)dst_ca_ioctl, 841 + .open = dst_ca_open, 842 + .release = dst_ca_release, 843 + .read = dst_ca_read, 844 + .write = dst_ca_write 845 + }; 846 + 847 + static struct dvb_device dvbdev_ca = { 848 + .priv = NULL, 849 + .users = 1, 850 + .readers = 1, 851 + .writers = 1, 852 + .fops = &dst_ca_fops 853 + }; 854 + 855 + int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter) 856 + { 857 + struct dvb_device *dvbdev; 858 + if (verbose > 4) 859 + dprintk("%s:registering DST-CA device\n", __FUNCTION__); 860 + dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA); 861 + return 0; 862 + } 863 + 864 + EXPORT_SYMBOL(dst_ca_attach); 865 + 866 + MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver"); 867 + MODULE_AUTHOR("Manu Abraham"); 868 + MODULE_LICENSE("GPL");
+58
drivers/media/dvb/bt8xx/dst_ca.h
···
··· 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
+153
drivers/media/dvb/bt8xx/dst_common.h
···
··· 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 "bt878.h" 28 + 29 + #include "dst_ca.h" 30 + 31 + 32 + #define NO_DELAY 0 33 + #define LONG_DELAY 1 34 + #define DEVICE_INIT 2 35 + 36 + #define DELAY 1 37 + 38 + #define DST_TYPE_IS_SAT 0 39 + #define DST_TYPE_IS_TERR 1 40 + #define DST_TYPE_IS_CABLE 2 41 + #define DST_TYPE_IS_ATSC 3 42 + 43 + #define DST_TYPE_HAS_NEWTUNE 1 44 + #define DST_TYPE_HAS_TS204 2 45 + #define DST_TYPE_HAS_SYMDIV 4 46 + #define DST_TYPE_HAS_FW_1 8 47 + #define DST_TYPE_HAS_FW_2 16 48 + #define DST_TYPE_HAS_FW_3 32 49 + 50 + 51 + 52 + /* Card capability list */ 53 + 54 + #define DST_TYPE_HAS_MAC 1 55 + #define DST_TYPE_HAS_DISEQC3 2 56 + #define DST_TYPE_HAS_DISEQC4 4 57 + #define DST_TYPE_HAS_DISEQC5 8 58 + #define DST_TYPE_HAS_MOTO 16 59 + #define DST_TYPE_HAS_CA 32 60 + #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ 61 + 62 + 63 + #define RDC_8820_PIO_0_DISABLE 0 64 + #define RDC_8820_PIO_0_ENABLE 1 65 + #define RDC_8820_INT 2 66 + #define RDC_8820_RESET 4 67 + 68 + /* DST Communication */ 69 + #define GET_REPLY 1 70 + #define NO_REPLY 0 71 + 72 + #define GET_ACK 1 73 + #define FIXED_COMM 8 74 + 75 + #define ACK 0xff 76 + 77 + struct dst_state { 78 + 79 + struct i2c_adapter* i2c; 80 + 81 + struct bt878* bt; 82 + 83 + struct dvb_frontend_ops ops; 84 + 85 + /* configuration settings */ 86 + const struct dst_config* config; 87 + 88 + struct dvb_frontend frontend; 89 + 90 + /* private ASIC data */ 91 + u8 tx_tuna[10]; 92 + u8 rx_tuna[10]; 93 + u8 rxbuffer[10]; 94 + u8 diseq_flags; 95 + u8 dst_type; 96 + u32 type_flags; 97 + u32 frequency; /* intermediate frequency in kHz for QPSK */ 98 + fe_spectral_inversion_t inversion; 99 + u32 symbol_rate; /* symbol rate in Symbols per second */ 100 + fe_code_rate_t fec; 101 + fe_sec_voltage_t voltage; 102 + fe_sec_tone_mode_t tone; 103 + u32 decode_freq; 104 + u8 decode_lock; 105 + u16 decode_strength; 106 + u16 decode_snr; 107 + unsigned long cur_jiff; 108 + u8 k22; 109 + fe_bandwidth_t bandwidth; 110 + u8 dst_hw_cap; 111 + u8 dst_fw_version; 112 + fe_sec_mini_cmd_t minicmd; 113 + u8 messages[256]; 114 + }; 115 + 116 + struct dst_types { 117 + char *device_id; 118 + int offset; 119 + u8 dst_type; 120 + u32 type_flags; 121 + u8 dst_feature; 122 + }; 123 + 124 + 125 + 126 + struct dst_config 127 + { 128 + /* the ASIC i2c address */ 129 + u8 demod_address; 130 + }; 131 + 132 + 133 + int rdc_reset_state(struct dst_state *state); 134 + int rdc_8820_reset(struct dst_state *state); 135 + 136 + int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode); 137 + int dst_pio_enable(struct dst_state *state); 138 + int dst_pio_disable(struct dst_state *state); 139 + int dst_error_recovery(struct dst_state* state); 140 + int dst_error_bailout(struct dst_state *state); 141 + int dst_comm_init(struct dst_state* state); 142 + 143 + int write_dst(struct dst_state *state, u8 * data, u8 len); 144 + int read_dst(struct dst_state *state, u8 * ret, u8 len); 145 + u8 dst_check_sum(u8 * buf, u32 len); 146 + struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter); 147 + int dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter); 148 + int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay); 149 + 150 + int dst_command(struct dst_state* state, u8 * data, u8 len); 151 + 152 + 153 + #endif // DST_COMMON_H
-1
drivers/media/dvb/bt8xx/dst_priv.h
··· 33 struct bt878; 34 35 int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); 36 -
··· 33 struct bt878; 34 35 int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
+58 -37
drivers/media/dvb/bt8xx/dvb-bt8xx.c
··· 142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); 143 144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); 145 - mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); 146 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); 147 148 return 0; ··· 161 else if (params->frequency < 771000000) cp = 0xbc; 162 else cp = 0xf4; 163 164 - if (params->frequency == 0) bs = 0x03; 165 else if (params->frequency < 443250000) bs = 0x02; 166 else bs = 0x08; 167 ··· 190 191 192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, 193 - 1576000,1718000,1856000,2036000,2150000}; 194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, 195 - 0x00102000,0x00104000,0x00108000,0x00110000, 196 - 0x00120000,0x00140000}; 197 198 #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ 199 - printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); 200 201 - /* This is really the bit driving the tuner chip cx24108 */ 202 203 - if(freq<950000) freq=950000; /* kHz */ 204 - if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ 205 206 - /* decide which VCO to use for the input frequency */ 207 - for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); 208 - printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); 209 - band=bandsel[i]; 210 - /* the gain values must be set by SetSymbolrate */ 211 - /* compute the pll divider needed, from Conexant data sheet, 212 - resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, 213 - depending on the divider bit. It is set to /4 on the 2 lowest 214 - bands */ 215 - n=((i<=2?2:1)*freq*10L)/(XTAL/100); 216 - a=n%32; n/=32; if(a==0) n--; 217 - pump=(freq<(osci[i-1]+osci[i])/2); 218 - pll=0xf8000000| 219 - ((pump?1:2)<<(14+11))| 220 - ((n&0x1ff)<<(5+11))| 221 - ((a&0x1f)<<11); 222 - /* everything is shifted left 11 bits to left-align the bits in the 223 - 32bit word. Output to the tuner goes MSB-aligned, after all */ 224 - printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); 225 - cx24110_pll_write(fe,band); 226 - /* set vga and vca to their widest-band settings, as a precaution. 227 - SetSymbolrate might not be called to set this up */ 228 - cx24110_pll_write(fe,0x500c0000); 229 - cx24110_pll_write(fe,0x83f1f800); 230 - cx24110_pll_write(fe,pll); 231 /* writereg(client,0x56,0x7f);*/ 232 233 return 0; ··· 299 static u8 mt352_reset [] = { 0x50, 0x80 }; 300 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 301 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 302 - 0x00, 0xFF, 0x00, 0x40, 0x40 }; 303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; 304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; 305 ··· 463 464 static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 465 { 466 switch(type) { 467 #ifdef BTTV_DVICO_DVBT_LITE 468 case BTTV_DVICO_DVBT_LITE: ··· 506 break; 507 508 case BTTV_TWINHAN_DST: 509 - card->fe = dst_attach(&dst_config, card->i2c_adapter, card->bt); 510 if (card->fe != NULL) { 511 break; 512 } ··· 669 case BTTV_PINNACLESAT: 670 card->gpio_mode = 0x0400c060; 671 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 672 - BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 673 card->op_sync_orin = 0; 674 card->irq_err_ignore = 0; 675 break;
··· 142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); 143 144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); 145 + mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); 146 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); 147 148 return 0; ··· 161 else if (params->frequency < 771000000) cp = 0xbc; 162 else cp = 0xf4; 163 164 + if (params->frequency == 0) bs = 0x03; 165 else if (params->frequency < 443250000) bs = 0x02; 166 else bs = 0x08; 167 ··· 190 191 192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, 193 + 1576000,1718000,1856000,2036000,2150000}; 194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, 195 + 0x00102000,0x00104000,0x00108000,0x00110000, 196 + 0x00120000,0x00140000}; 197 198 #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ 199 + printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); 200 201 + /* This is really the bit driving the tuner chip cx24108 */ 202 203 + if(freq<950000) freq=950000; /* kHz */ 204 + if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ 205 206 + /* decide which VCO to use for the input frequency */ 207 + for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); 208 + printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); 209 + band=bandsel[i]; 210 + /* the gain values must be set by SetSymbolrate */ 211 + /* compute the pll divider needed, from Conexant data sheet, 212 + resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, 213 + depending on the divider bit. It is set to /4 on the 2 lowest 214 + bands */ 215 + n=((i<=2?2:1)*freq*10L)/(XTAL/100); 216 + a=n%32; n/=32; if(a==0) n--; 217 + pump=(freq<(osci[i-1]+osci[i])/2); 218 + pll=0xf8000000| 219 + ((pump?1:2)<<(14+11))| 220 + ((n&0x1ff)<<(5+11))| 221 + ((a&0x1f)<<11); 222 + /* everything is shifted left 11 bits to left-align the bits in the 223 + 32bit word. Output to the tuner goes MSB-aligned, after all */ 224 + printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); 225 + cx24110_pll_write(fe,band); 226 + /* set vga and vca to their widest-band settings, as a precaution. 227 + SetSymbolrate might not be called to set this up */ 228 + cx24110_pll_write(fe,0x500c0000); 229 + cx24110_pll_write(fe,0x83f1f800); 230 + cx24110_pll_write(fe,pll); 231 /* writereg(client,0x56,0x7f);*/ 232 233 return 0; ··· 299 static u8 mt352_reset [] = { 0x50, 0x80 }; 300 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 301 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 302 + 0x00, 0xFF, 0x00, 0x40, 0x40 }; 303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; 304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; 305 ··· 463 464 static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 465 { 466 + int ret; 467 + struct dst_state* state = NULL; 468 + 469 switch(type) { 470 #ifdef BTTV_DVICO_DVBT_LITE 471 case BTTV_DVICO_DVBT_LITE: ··· 503 break; 504 505 case BTTV_TWINHAN_DST: 506 + /* DST is not a frontend driver !!! */ 507 + state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); 508 + /* Setup the Card */ 509 + state->config = &dst_config; 510 + state->i2c = card->i2c_adapter; 511 + state->bt = card->bt; 512 + 513 + /* DST is not a frontend, attaching the ASIC */ 514 + if ((dst_attach(state, &card->dvb_adapter)) == NULL) { 515 + printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__); 516 + break; 517 + } 518 + card->fe = &state->frontend; 519 + 520 + /* Attach other DST peripherals if any */ 521 + /* Conditional Access device */ 522 + if (state->dst_hw_cap & DST_TYPE_HAS_CA) { 523 + ret = dst_ca_attach(state, &card->dvb_adapter); 524 + } 525 if (card->fe != NULL) { 526 break; 527 } ··· 648 case BTTV_PINNACLESAT: 649 card->gpio_mode = 0x0400c060; 650 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 651 + BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 652 card->op_sync_orin = 0; 653 card->irq_err_ignore = 0; 654 break;
+1 -1
drivers/media/dvb/bt8xx/dvb-bt8xx.h
··· 31 #include "bttv.h" 32 #include "mt352.h" 33 #include "sp887x.h" 34 - #include "dst.h" 35 #include "nxt6000.h" 36 #include "cx24110.h" 37 #include "or51211.h"
··· 31 #include "bttv.h" 32 #include "mt352.h" 33 #include "sp887x.h" 34 + #include "dst_common.h" 35 #include "nxt6000.h" 36 #include "cx24110.h" 37 #include "or51211.h"