[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 11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and 12 12 pcHDTV HD2000 cards. 13 13 14 - Since these cards have no MPEG decoder onboard, they transmit 14 + Since these cards have no MPEG decoder onboard, they transmit 15 15 only compressed MPEG data over the PCI bus, so you need 16 16 an external software decoder to watch TV on your computer. 17 17 18 18 Say Y if you own such a device and want to use it. 19 -
+1 -3
drivers/media/dvb/bt8xx/Makefile
··· 1 - 2 - obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o 1 + obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o 3 2 4 3 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends 5 -
+9 -9
drivers/media/dvb/bt8xx/bt878.c
··· 4 4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> 5 5 * 6 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) 7 + * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de) 8 + * & Marcus Metzler (mocm@metzlerbros.de) 9 9 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 10 * 11 11 * This program is free software; you can redistribute it and/or ··· 461 461 pci_set_drvdata(dev, bt); 462 462 463 463 /* if(init_bt878(btv) < 0) { 464 - bt878_remove(dev); 465 - return -EIO; 466 - } 464 + bt878_remove(dev); 465 + return -EIO; 466 + } 467 467 */ 468 468 469 469 if ((result = bt878_mem_alloc(bt))) { ··· 536 536 MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); 537 537 538 538 static struct pci_driver bt878_pci_driver = { 539 - .name = "bt878", 539 + .name = "bt878", 540 540 .id_table = bt878_pci_tbl, 541 - .probe = bt878_probe, 542 - .remove = bt878_remove, 541 + .probe = bt878_probe, 542 + .remove = bt878_remove, 543 543 }; 544 544 545 545 static int bt878_pci_driver_registered = 0; ··· 558 558 (BT878_VERSION_CODE >> 8) & 0xff, 559 559 BT878_VERSION_CODE & 0xff); 560 560 /* 561 - bt878_check_chipset(); 561 + bt878_check_chipset(); 562 562 */ 563 563 /* later we register inside of bt878_find_audio_dma() 564 564 * because we may want to ignore certain cards */
+549 -279
drivers/media/dvb/bt8xx/dst.c
··· 1 1 /* 2 - Frontend-driver for TwinHan DST Frontend 3 2 4 - Copyright (C) 2003 Jamie Honan 3 + Frontend/Card driver for TwinHan DST Frontend 4 + Copyright (C) 2003 Jamie Honan 5 + Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) 5 6 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. 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. 10 11 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 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. 14 16 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 - 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. 21 20 */ 21 + 22 22 23 23 #include <linux/kernel.h> 24 24 #include <linux/module.h> ··· 31 31 32 32 #include "dvb_frontend.h" 33 33 #include "dst_priv.h" 34 - #include "dst.h" 34 + #include "dst_common.h" 35 35 36 - struct dst_state { 37 36 38 - struct i2c_adapter* i2c; 37 + static unsigned int verbose = 1; 38 + module_param(verbose, int, 0644); 39 + MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 39 40 40 - struct bt878* bt; 41 + static unsigned int debug = 1; 42 + module_param(debug, int, 0644); 43 + MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)"); 41 44 42 - struct dvb_frontend_ops ops; 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)"); 43 48 44 - /* configuration settings */ 45 - const struct dst_config* config; 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"); 46 52 47 - struct dvb_frontend frontend; 48 53 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 54 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 55 + #define dprintk if (debug) printk 87 56 88 57 #define HAS_LOCK 1 89 58 #define ATTEMPT_TUNE 2 ··· 66 97 bt878_device_control(state->bt, DST_IG_TS, &bits); 67 98 } 68 99 69 - static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh) 100 + int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay) 70 101 { 71 102 union dst_gpio_packet enb; 72 103 union dst_gpio_packet bits; ··· 74 105 75 106 enb.enb.mask = mask; 76 107 enb.enb.enable = enbb; 108 + if (verbose > 4) 109 + dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh); 110 + 77 111 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); 112 + dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb); 79 113 return -EREMOTEIO; 80 114 } 115 + 116 + msleep(1); 81 117 82 118 /* because complete disabling means no output, no need to do output packet */ 83 119 if (enbb == 0) 84 120 return 0; 85 121 122 + if (delay) 123 + msleep(10); 124 + 86 125 bits.outp.mask = enbb; 87 126 bits.outp.highvals = outhigh; 88 127 89 128 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); 129 + dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh); 91 130 return -EREMOTEIO; 92 131 } 93 132 return 0; 94 133 } 134 + EXPORT_SYMBOL(dst_gpio_outb); 95 135 96 - static int dst_gpio_inb(struct dst_state *state, u8 * result) 136 + int dst_gpio_inb(struct dst_state *state, u8 * result) 97 137 { 98 138 union dst_gpio_packet rd_packet; 99 139 int err; ··· 117 139 *result = (u8) rd_packet.rd.value; 118 140 return 0; 119 141 } 142 + EXPORT_SYMBOL(dst_gpio_inb); 120 143 121 - #define DST_I2C_ENABLE 1 122 - #define DST_8820 2 123 - 124 - static int dst_reset8820(struct dst_state *state) 144 + int rdc_reset_state(struct dst_state *state) 125 145 { 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; 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 + 132 154 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 - */ 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 + 142 162 return 0; 143 163 } 164 + EXPORT_SYMBOL(rdc_reset_state); 144 165 145 - static int dst_i2c_enable(struct dst_state *state) 166 + int rdc_8820_reset(struct dst_state *state) 146 167 { 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); 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 + 155 182 return 0; 156 183 } 184 + EXPORT_SYMBOL(rdc_8820_reset); 157 185 158 - static int dst_i2c_disable(struct dst_state *state) 186 + int dst_pio_enable(struct dst_state *state) 159 187 { 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); 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 + 168 194 return 0; 169 195 } 196 + EXPORT_SYMBOL(dst_pio_enable); 170 197 171 - static int dst_wait_dst_ready(struct dst_state *state) 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) 172 210 { 173 211 u8 reply; 174 - int retval; 175 212 int i; 213 + 176 214 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); 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); 182 223 return 1; 183 224 } 184 - msleep(10); 225 + msleep(1); 185 226 } 186 - dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i); 227 + if (verbose > 1) 228 + dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i); 229 + 187 230 return 0; 188 231 } 232 + EXPORT_SYMBOL(dst_wait_dst_ready); 189 233 190 - static int write_dst(struct dst_state *state, u8 * data, u8 len) 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) 191 276 { 192 277 struct i2c_msg msg = { 193 278 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len 194 279 }; 280 + 195 281 int err; 196 282 int cnt; 197 - 198 - if (dst_debug && dst_verbose) { 283 + if (debug && (verbose > 4)) { 199 284 u8 i; 200 - dprintk("%s writing", __FUNCTION__); 201 - for (i = 0; i < len; i++) { 202 - dprintk(" 0x%02x", data[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"); 203 290 } 204 - dprintk("\n"); 205 291 } 206 - msleep(30); 207 - for (cnt = 0; cnt < 4; cnt++) { 292 + for (cnt = 0; cnt < 2; cnt++) { 208 293 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); 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); 214 296 continue; 215 297 } else 216 298 break; 217 299 } 218 - if (cnt >= 4) 219 - return -EREMOTEIO; 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 + 220 309 return 0; 221 310 } 311 + EXPORT_SYMBOL(write_dst); 222 312 223 - static int read_dst(struct dst_state *state, u8 * ret, u8 len) 313 + int read_dst(struct dst_state *state, u8 * ret, u8 len) 224 314 { 225 315 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; 226 316 int err; 227 317 int cnt; 228 318 229 - for (cnt = 0; cnt < 4; cnt++) { 319 + for (cnt = 0; cnt < 2; cnt++) { 230 320 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 321 + 231 322 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); 323 + dst_error_recovery(state); 324 + 234 325 continue; 235 326 } else 236 327 break; 237 328 } 238 - if (cnt >= 4) 239 - return -EREMOTEIO; 240 - dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); 241 - if (dst_debug && dst_verbose) { 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]); 242 338 for (err = 1; err < len; err++) 243 339 dprintk(" 0x%x", ret[err]); 244 340 if (err > 1) 245 341 dprintk("\n"); 246 342 } 343 + 247 344 return 0; 248 345 } 346 + EXPORT_SYMBOL(read_dst); 249 347 250 348 static int dst_set_freq(struct dst_state *state, u32 freq) 251 349 { ··· 476 422 return 0; 477 423 } 478 424 479 - static u8 dst_check_sum(u8 * buf, u32 len) 425 + u8 dst_check_sum(u8 * buf, u32 len) 480 426 { 481 427 u32 i; 482 428 u8 val = 0; ··· 487 433 } 488 434 return ((~val) + 1); 489 435 } 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 */ 436 + EXPORT_SYMBOL(dst_check_sum); 512 437 513 438 static void dst_type_flags_print(u32 type_flags) 514 439 { ··· 498 465 printk(" 0x%x ts204", DST_TYPE_HAS_TS204); 499 466 if (type_flags & DST_TYPE_HAS_SYMDIV) 500 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 + 501 475 printk("\n"); 502 476 } 503 477 504 - static int dst_type_print(u8 type) 478 + 479 + static int dst_type_print (u8 type) 505 480 { 506 481 char *otype; 507 482 switch (type) { 508 483 case DST_TYPE_IS_SAT: 509 484 otype = "satellite"; 510 485 break; 486 + 511 487 case DST_TYPE_IS_TERR: 512 488 otype = "terrestrial"; 513 489 break; 490 + 514 491 case DST_TYPE_IS_CABLE: 515 492 otype = "cable"; 516 493 break; 494 + 517 495 default: 518 496 printk("%s: invalid dst type %d\n", __FUNCTION__, type); 519 497 return -EINVAL; 520 498 } 521 499 printk("DST type : %s\n", otype); 500 + 522 501 return 0; 523 502 } 524 503 525 - static int dst_check_ci(struct dst_state *state) 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) 526 660 { 527 - u8 txbuf[8]; 528 - u8 rxbuf[8]; 529 - int retval; 661 + u8 reply; 662 + 530 663 int i; 531 - struct dst_types *dsp; 532 - u8 use_dst_type; 533 - u32 use_type_flags; 664 + struct dst_types *p_dst_type; 665 + u8 use_dst_type = 0; 666 + u32 use_type_flags = 0; 534 667 535 - memset(txbuf, 0, sizeof(txbuf)); 536 - txbuf[1] = 6; 537 - txbuf[7] = dst_check_sum(txbuf, 7); 668 + static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 538 669 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; 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 */ 546 684 } 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; 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 */ 553 697 } 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); 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 + 577 710 break; 578 711 } 579 712 } 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__); 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__); 583 717 use_dst_type = DST_TYPE_IS_SAT; 584 718 use_type_flags = DST_TYPE_HAS_SYMDIV; 585 719 } 586 - dst_type_print(use_dst_type); 587 720 721 + dst_type_print(use_dst_type); 588 722 state->type_flags = use_type_flags; 589 723 state->dst_type = use_dst_type; 590 724 dst_type_flags_print(state->type_flags); ··· 759 559 if (state->type_flags & DST_TYPE_HAS_TS204) { 760 560 dst_packsize(state, 204); 761 561 } 562 + 762 563 return 0; 763 564 } 764 565 765 - static int dst_command(struct dst_state* state, u8 * data, u8 len) 566 + static int dst_probe(struct dst_state *state) 766 567 { 767 - int retval; 768 - u8 reply; 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 + } 769 577 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; 578 + if (dst_get_device_id(state) < 0) { 579 + dprintk("%s: unknown device.\n", __FUNCTION__); 580 + return -1; 777 581 } 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; 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; 784 592 } 785 - if (reply != 0xff) { 786 - dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 787 - return 0; 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; 788 621 } 789 622 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 790 623 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; 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; 799 635 } 636 + 800 637 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 801 638 dprintk("%s: checksum failure\n", __FUNCTION__); 802 - return 0; 639 + return -1; 803 640 } 641 + 804 642 return 0; 805 643 } 644 + EXPORT_SYMBOL(dst_command); 806 645 807 646 static int dst_get_signal(struct dst_state* state) 808 647 { ··· 885 646 paket[4] = 0; 886 647 else 887 648 paket[4] = 1; 649 + 888 650 if (state->tone == SEC_TONE_ON) 889 - paket[2] = state->k22; 651 + paket[2] = 0x02; 890 652 else 891 653 paket[2] = 0; 892 - paket[7] = dst_check_sum(&paket[0], 7); 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); 893 660 dst_command(state, paket, 8); 894 661 return 0; 895 662 } ··· 903 658 static int dst_get_tuna(struct dst_state* state) 904 659 { 905 660 int retval; 661 + 906 662 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) 907 663 return 0; 664 + 908 665 state->diseq_flags &= ~(HAS_LOCK); 909 - if (!dst_wait_dst_ready(state)) 666 + if (!dst_wait_dst_ready(state, NO_DELAY)) 910 667 return 0; 668 + 669 + msleep(10); 670 + 911 671 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 912 672 /* how to get variable length reply ???? */ 913 673 retval = read_dst(state, state->rx_tuna, 10); 914 674 } else { 915 - retval = read_dst(state, &state->rx_tuna[2], 8); 675 + retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 916 676 } 677 + 917 678 if (retval < 0) { 918 679 dprintk("%s: read not successful\n", __FUNCTION__); 919 680 return 0; 920 681 } 682 + 921 683 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 922 684 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 923 685 dprintk("%s: checksum failure?\n", __FUNCTION__); ··· 969 717 dst_set_voltage(fe, SEC_VOLTAGE_13); 970 718 } 971 719 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 972 - dst_i2c_enable(state); 720 + 721 + if ((dst_comm_init(state)) < 0) { 722 + dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__); 723 + return -1; 724 + } 725 + 973 726 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 974 - dst_reset8820(state); 975 727 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 976 728 retval = write_dst(state, &state->tx_tuna[0], 10); 729 + 977 730 } else { 978 731 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); 979 - retval = write_dst(state, &state->tx_tuna[2], 8); 732 + retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); 980 733 } 981 734 if (retval < 0) { 982 - dst_i2c_disable(state); 735 + dst_pio_disable(state); 983 736 dprintk("%s: write not successful\n", __FUNCTION__); 984 737 return retval; 985 738 } 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; 739 + 740 + if ((dst_pio_disable(state)) < 0) { 741 + dprintk("%s: DST PIO disable failed !\n", __FUNCTION__); 742 + return -1; 992 743 } 993 - if (reply != 0xff) { 994 - dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); 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); 995 751 return 0; 996 752 } 997 753 state->diseq_flags |= ATTEMPT_TUNE; 754 + 998 755 return dst_get_tuna(state); 999 756 } 1000 757 ··· 1057 796 need_cmd = 1; 1058 797 state->diseq_flags |= HAS_POWER; 1059 798 break; 799 + 1060 800 case SEC_VOLTAGE_18: 1061 801 if ((state->diseq_flags & HAS_POWER) == 0) 1062 802 need_cmd = 1; 1063 803 state->diseq_flags |= HAS_POWER; 1064 804 val[8] |= 0x40; 1065 805 break; 806 + 1066 807 case SEC_VOLTAGE_OFF: 1067 808 need_cmd = 1; 1068 809 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); 1069 810 break; 811 + 1070 812 default: 1071 813 return -EINVAL; 1072 814 } 1073 - if (need_cmd) { 815 + if (need_cmd) 1074 816 dst_tone_power_cmd(state); 1075 - } 817 + 1076 818 return 0; 1077 819 } 1078 820 ··· 1096 832 switch (tone) { 1097 833 case SEC_TONE_OFF: 1098 834 break; 835 + 1099 836 case SEC_TONE_ON: 1100 837 val[8] |= 1; 1101 838 break; 839 + 1102 840 default: 1103 841 return -EINVAL; 1104 842 } 1105 843 dst_tone_power_cmd(state); 844 + 1106 845 return 0; 1107 846 } 1108 847 ··· 1180 913 struct dst_state* state = (struct dst_state*) fe->demodulator_priv; 1181 914 1182 915 dst_set_freq(state, p->frequency); 916 + if (verbose > 4) 917 + dprintk("Set Frequency = [%d]\n", p->frequency); 918 + 1183 919 dst_set_inversion(state, p->inversion); 1184 920 if (state->dst_type == DST_TYPE_IS_SAT) { 1185 921 dst_set_fec(state, p->u.qpsk.fec_inner); 1186 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 + 1187 926 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1188 927 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 1189 928 } else if (state->dst_type == DST_TYPE_IS_CABLE) { ··· 1231 958 static struct dvb_frontend_ops dst_dvbs_ops; 1232 959 static struct dvb_frontend_ops dst_dvbc_ops; 1233 960 1234 - struct dvb_frontend* dst_attach(const struct dst_config* config, 1235 - struct i2c_adapter* i2c, 1236 - struct bt878 *bt) 961 + struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) 1237 962 { 1238 - struct dst_state* state = NULL; 1239 963 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; 964 + /* check if the ASIC is there */ 965 + if (dst_probe(state) < 0) { 966 + if (state) 967 + kfree(state); 1243 968 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 - 969 + return NULL; 970 + } 1252 971 /* determine settings based on type */ 1253 972 switch (state->dst_type) { 1254 973 case DST_TYPE_IS_TERR: 1255 974 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 1256 975 break; 976 + 1257 977 case DST_TYPE_IS_CABLE: 1258 978 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 1259 979 break; 980 + 1260 981 case DST_TYPE_IS_SAT: 1261 982 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 1262 983 break; 984 + 1263 985 default: 1264 - printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n"); 1265 - goto error; 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; 1266 991 } 1267 992 1268 993 /* create dvb_frontend */ 1269 994 state->frontend.ops = &state->ops; 1270 995 state->frontend.demodulator_priv = state; 1271 - return &state->frontend; 1272 996 1273 - error: 1274 - kfree(state); 1275 - return NULL; 997 + return state; /* Manu (DST is a card not a frontend) */ 1276 998 } 999 + 1000 + EXPORT_SYMBOL(dst_attach); 1277 1001 1278 1002 static struct dvb_frontend_ops dst_dvbt_ops = { 1279 1003 ··· 1321 1051 .read_signal_strength = dst_read_signal_strength, 1322 1052 .read_snr = dst_read_snr, 1323 1053 1054 + .diseqc_send_burst = dst_set_tone, 1324 1055 .diseqc_send_master_cmd = dst_set_diseqc, 1325 1056 .set_voltage = dst_set_voltage, 1326 1057 .set_tone = dst_set_tone, ··· 1353 1082 .read_snr = dst_read_snr, 1354 1083 }; 1355 1084 1356 - MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); 1357 - MODULE_AUTHOR("Jamie Honan"); 1358 - MODULE_LICENSE("GPL"); 1359 1085 1360 - EXPORT_SYMBOL(dst_attach); 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 33 struct bt878; 34 34 35 35 int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); 36 -
+58 -37
drivers/media/dvb/bt8xx/dvb-bt8xx.c
··· 142 142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); 143 143 144 144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); 145 - mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); 145 + mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); 146 146 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); 147 147 148 148 return 0; ··· 161 161 else if (params->frequency < 771000000) cp = 0xbc; 162 162 else cp = 0xf4; 163 163 164 - if (params->frequency == 0) bs = 0x03; 164 + if (params->frequency == 0) bs = 0x03; 165 165 else if (params->frequency < 443250000) bs = 0x02; 166 166 else bs = 0x08; 167 167 ··· 190 190 191 191 192 192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, 193 - 1576000,1718000,1856000,2036000,2150000}; 193 + 1576000,1718000,1856000,2036000,2150000}; 194 194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, 195 - 0x00102000,0x00104000,0x00108000,0x00110000, 196 - 0x00120000,0x00140000}; 195 + 0x00102000,0x00104000,0x00108000,0x00110000, 196 + 0x00120000,0x00140000}; 197 197 198 198 #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ 199 - printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); 199 + printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); 200 200 201 - /* This is really the bit driving the tuner chip cx24108 */ 201 + /* This is really the bit driving the tuner chip cx24108 */ 202 202 203 - if(freq<950000) freq=950000; /* kHz */ 204 - if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ 203 + if(freq<950000) freq=950000; /* kHz */ 204 + if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ 205 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); 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 231 /* writereg(client,0x56,0x7f);*/ 232 232 233 233 return 0; ··· 299 299 static u8 mt352_reset [] = { 0x50, 0x80 }; 300 300 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 301 301 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 302 - 0x00, 0xFF, 0x00, 0x40, 0x40 }; 302 + 0x00, 0xFF, 0x00, 0x40, 0x40 }; 303 303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; 304 304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; 305 305 ··· 463 463 464 464 static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 465 465 { 466 + int ret; 467 + struct dst_state* state = NULL; 468 + 466 469 switch(type) { 467 470 #ifdef BTTV_DVICO_DVBT_LITE 468 471 case BTTV_DVICO_DVBT_LITE: ··· 506 503 break; 507 504 508 505 case BTTV_TWINHAN_DST: 509 - card->fe = dst_attach(&dst_config, card->i2c_adapter, card->bt); 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 + } 510 525 if (card->fe != NULL) { 511 526 break; 512 527 } ··· 669 648 case BTTV_PINNACLESAT: 670 649 card->gpio_mode = 0x0400c060; 671 650 /* 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. */ 651 + BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 673 652 card->op_sync_orin = 0; 674 653 card->irq_err_ignore = 0; 675 654 break;
+1 -1
drivers/media/dvb/bt8xx/dvb-bt8xx.h
··· 31 31 #include "bttv.h" 32 32 #include "mt352.h" 33 33 #include "sp887x.h" 34 - #include "dst.h" 34 + #include "dst_common.h" 35 35 #include "nxt6000.h" 36 36 #include "cx24110.h" 37 37 #include "or51211.h"