Merge branch 'mantis' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'mantis' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (117 commits)
V4L/DVB (13851): Fix Input dependency for Mantis
V4L/DVB(13824a): mantis: Fix __devexit bad annotations
V4L/DVB (13808b): mantis: replace DMA_nnBIT_MASK to DMA_BIT_MASK(32)
V4L/DVB (13808): [Mantis/Hopper] Build update for Mantis/Hopper based cards
V4L/DVB(13808a): mantis: convert it to the new ir-core register/unregister functions
V4L/DVB (13812): [Mantis/Hopper] Update Copyright header
V4L/DVB (13811): [MB86A16] Update Copyright header
V4L/DVB (13810): [MB86A16] Use DVB_* macros
V4L/DVB (13809): Fix Checkpatch violations
V4L/DVB (13807): Fix: Free device in the device registration failure case
V4L/DVB (13806): Register and Initialize Remote control
V4L/DVB (13805): Fix: Unregister the frontend before detaching
V4L/DVB (13804): Remove unused I2C Adapter ID
V4L/DVB (13803): Remove unused dependency on CU1216
V4L/DVB (13802): [Mantis/Hopper] Fix all build related warnings
V4L/DVB (13801): [MB86A16] Use the search callback
V4L/DVB (13800): [Mantis] I2C optimization. Required delay is much lesser than 1mS.
V4L/DVB (13799): [Mantis] Unregister frontend
V4L/DVB (13798): [Mantis] Enable power for all cards, use byte mode only on relevant devices
V4L/DVB (13797): [Mantis/Hopper/TDA665x] Large overhaul,
...

+7801 -1
+4
drivers/media/dvb/Kconfig
··· 72 72 depends on DVB_CORE && PCI && I2C 73 73 source "drivers/media/dvb/pt1/Kconfig" 74 74 75 + comment "Supported Mantis Adapters" 76 + depends on DVB_CORE && PCI && I2C 77 + source "drivers/media/dvb/mantis/Kconfig" 78 + 75 79 comment "Supported DVB Frontends" 76 80 depends on DVB_CORE 77 81 source "drivers/media/dvb/frontends/Kconfig"
+13 -1
drivers/media/dvb/Makefile
··· 2 2 # Makefile for the kernel multimedia device drivers. 3 3 # 4 4 5 - obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ pt1/ 5 + obj-y := dvb-core/ \ 6 + frontends/ \ 7 + ttpci/ \ 8 + ttusb-dec/ \ 9 + ttusb-budget/ \ 10 + b2c2/ \ 11 + bt8xx/ \ 12 + dvb-usb/ \ 13 + pluto2/ \ 14 + siano/ \ 15 + dm1105/ \ 16 + pt1/ \ 17 + mantis/ 6 18 7 19 obj-$(CONFIG_DVB_FIREDTV) += firewire/
+19
drivers/media/dvb/frontends/Kconfig
··· 208 208 help 209 209 A DVB-S/S2 tuner module. Say Y when you want to support this frontend. 210 210 211 + config DVB_MB86A16 212 + tristate "Fujitsu MB86A16 based" 213 + depends on DVB_CORE && I2C 214 + default m if DVB_FE_CUSTOMISE 215 + help 216 + A DVB-S/DSS Direct Conversion reveiver. 217 + Say Y when you want to support this frontend. 218 + 211 219 comment "DVB-T (terrestrial) frontends" 212 220 depends on DVB_CORE 213 221 ··· 594 586 default m if DVB_FE_CUSTOMISE 595 587 help 596 588 A DMB-TH tuner module. Say Y when you want to support this frontend. 589 + 590 + config DVB_TDA665x 591 + tristate "TDA665x tuner" 592 + depends on DVB_CORE && I2C 593 + default m if DVB_FE_CUSTOMISE 594 + help 595 + Support for tuner modules based on Philips TDA6650/TDA6651 chips. 596 + Say Y when you want to support this chip. 597 + 598 + Currently supported tuners: 599 + * Panasonic ENV57H12D5 (ET-50DT) 597 600 598 601 comment "Tools to develop new frontends" 599 602
+2
drivers/media/dvb/frontends/Makefile
··· 64 64 obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o 65 65 obj-$(CONFIG_DVB_S5H1411) += s5h1411.o 66 66 obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o 67 + obj-$(CONFIG_DVB_TDA665x) += tda665x.o 67 68 obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o 68 69 obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o 69 70 obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o ··· 81 80 obj-$(CONFIG_DVB_ISL6423) += isl6423.o 82 81 obj-$(CONFIG_DVB_EC100) += ec100.o 83 82 obj-$(CONFIG_DVB_DS3000) += ds3000.o 83 + obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
+1878
drivers/media/dvb/frontends/mb86a16.c
··· 1 + /* 2 + Fujitsu MB86A16 DVB-S/DSS DC Receiver driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/init.h> 22 + #include <linux/kernel.h> 23 + #include <linux/module.h> 24 + #include <linux/moduleparam.h> 25 + 26 + #include "dvb_frontend.h" 27 + #include "mb86a16.h" 28 + #include "mb86a16_priv.h" 29 + 30 + unsigned int verbose = 5; 31 + module_param(verbose, int, 0644); 32 + 33 + #define ABS(x) ((x) < 0 ? (-x) : (x)) 34 + 35 + struct mb86a16_state { 36 + struct i2c_adapter *i2c_adap; 37 + const struct mb86a16_config *config; 38 + struct dvb_frontend frontend; 39 + 40 + /* tuning parameters */ 41 + int frequency; 42 + int srate; 43 + 44 + /* Internal stuff */ 45 + int master_clk; 46 + int deci; 47 + int csel; 48 + int rsel; 49 + }; 50 + 51 + #define MB86A16_ERROR 0 52 + #define MB86A16_NOTICE 1 53 + #define MB86A16_INFO 2 54 + #define MB86A16_DEBUG 3 55 + 56 + #define dprintk(x, y, z, format, arg...) do { \ 57 + if (z) { \ 58 + if ((x > MB86A16_ERROR) && (x > y)) \ 59 + printk(KERN_ERR "%s: " format "\n", __func__, ##arg); \ 60 + else if ((x > MB86A16_NOTICE) && (x > y)) \ 61 + printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg); \ 62 + else if ((x > MB86A16_INFO) && (x > y)) \ 63 + printk(KERN_INFO "%s: " format "\n", __func__, ##arg); \ 64 + else if ((x > MB86A16_DEBUG) && (x > y)) \ 65 + printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg); \ 66 + } else { \ 67 + if (x > y) \ 68 + printk(format, ##arg); \ 69 + } \ 70 + } while (0) 71 + 72 + #define TRACE_IN dprintk(verbose, MB86A16_DEBUG, 1, "-->()") 73 + #define TRACE_OUT dprintk(verbose, MB86A16_DEBUG, 1, "()-->") 74 + 75 + static int mb86a16_write(struct mb86a16_state *state, u8 reg, u8 val) 76 + { 77 + int ret; 78 + u8 buf[] = { reg, val }; 79 + 80 + struct i2c_msg msg = { 81 + .addr = state->config->demod_address, 82 + .flags = 0, 83 + .buf = buf, 84 + .len = 2 85 + }; 86 + 87 + dprintk(verbose, MB86A16_DEBUG, 1, 88 + "writing to [0x%02x],Reg[0x%02x],Data[0x%02x]", 89 + state->config->demod_address, buf[0], buf[1]); 90 + 91 + ret = i2c_transfer(state->i2c_adap, &msg, 1); 92 + 93 + return (ret != 1) ? -EREMOTEIO : 0; 94 + } 95 + 96 + static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val) 97 + { 98 + int ret; 99 + u8 b0[] = { reg }; 100 + u8 b1[] = { 0 }; 101 + 102 + struct i2c_msg msg[] = { 103 + { 104 + .addr = state->config->demod_address, 105 + .flags = 0, 106 + .buf = b0, 107 + .len = 1 108 + }, { 109 + .addr = state->config->demod_address, 110 + .flags = I2C_M_RD, 111 + .buf = b1, 112 + .len = 1 113 + } 114 + }; 115 + ret = i2c_transfer(state->i2c_adap, msg, 2); 116 + if (ret != 2) { 117 + dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)", 118 + reg, ret); 119 + 120 + return -EREMOTEIO; 121 + } 122 + *val = b1[0]; 123 + 124 + return ret; 125 + } 126 + 127 + static int CNTM_set(struct mb86a16_state *state, 128 + unsigned char timint1, 129 + unsigned char timint2, 130 + unsigned char cnext) 131 + { 132 + unsigned char val; 133 + 134 + val = (timint1 << 4) | (timint2 << 2) | cnext; 135 + if (mb86a16_write(state, MB86A16_CNTMR, val) < 0) 136 + goto err; 137 + 138 + return 0; 139 + 140 + err: 141 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 142 + return -EREMOTEIO; 143 + } 144 + 145 + static int smrt_set(struct mb86a16_state *state, int rate) 146 + { 147 + int tmp ; 148 + int m ; 149 + unsigned char STOFS0, STOFS1; 150 + 151 + m = 1 << state->deci; 152 + tmp = (8192 * state->master_clk - 2 * m * rate * 8192 + state->master_clk / 2) / state->master_clk; 153 + 154 + STOFS0 = tmp & 0x0ff; 155 + STOFS1 = (tmp & 0xf00) >> 8; 156 + 157 + if (mb86a16_write(state, MB86A16_SRATE1, (state->deci << 2) | 158 + (state->csel << 1) | 159 + state->rsel) < 0) 160 + goto err; 161 + if (mb86a16_write(state, MB86A16_SRATE2, STOFS0) < 0) 162 + goto err; 163 + if (mb86a16_write(state, MB86A16_SRATE3, STOFS1) < 0) 164 + goto err; 165 + 166 + return 0; 167 + err: 168 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 169 + return -1; 170 + } 171 + 172 + static int srst(struct mb86a16_state *state) 173 + { 174 + if (mb86a16_write(state, MB86A16_RESET, 0x04) < 0) 175 + goto err; 176 + 177 + return 0; 178 + err: 179 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 180 + return -EREMOTEIO; 181 + 182 + } 183 + 184 + static int afcex_data_set(struct mb86a16_state *state, 185 + unsigned char AFCEX_L, 186 + unsigned char AFCEX_H) 187 + { 188 + if (mb86a16_write(state, MB86A16_AFCEXL, AFCEX_L) < 0) 189 + goto err; 190 + if (mb86a16_write(state, MB86A16_AFCEXH, AFCEX_H) < 0) 191 + goto err; 192 + 193 + return 0; 194 + err: 195 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 196 + 197 + return -1; 198 + } 199 + 200 + static int afcofs_data_set(struct mb86a16_state *state, 201 + unsigned char AFCEX_L, 202 + unsigned char AFCEX_H) 203 + { 204 + if (mb86a16_write(state, 0x58, AFCEX_L) < 0) 205 + goto err; 206 + if (mb86a16_write(state, 0x59, AFCEX_H) < 0) 207 + goto err; 208 + 209 + return 0; 210 + err: 211 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 212 + return -EREMOTEIO; 213 + } 214 + 215 + static int stlp_set(struct mb86a16_state *state, 216 + unsigned char STRAS, 217 + unsigned char STRBS) 218 + { 219 + if (mb86a16_write(state, MB86A16_STRFILTCOEF1, (STRBS << 3) | (STRAS)) < 0) 220 + goto err; 221 + 222 + return 0; 223 + err: 224 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 225 + return -EREMOTEIO; 226 + } 227 + 228 + static int Vi_set(struct mb86a16_state *state, unsigned char ETH, unsigned char VIA) 229 + { 230 + if (mb86a16_write(state, MB86A16_VISET2, 0x04) < 0) 231 + goto err; 232 + if (mb86a16_write(state, MB86A16_VISET3, 0xf5) < 0) 233 + goto err; 234 + 235 + return 0; 236 + err: 237 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 238 + return -EREMOTEIO; 239 + } 240 + 241 + static int initial_set(struct mb86a16_state *state) 242 + { 243 + if (stlp_set(state, 5, 7)) 244 + goto err; 245 + 246 + udelay(100); 247 + if (afcex_data_set(state, 0, 0)) 248 + goto err; 249 + 250 + udelay(100); 251 + if (afcofs_data_set(state, 0, 0)) 252 + goto err; 253 + 254 + udelay(100); 255 + if (mb86a16_write(state, MB86A16_CRLFILTCOEF1, 0x16) < 0) 256 + goto err; 257 + if (mb86a16_write(state, 0x2f, 0x21) < 0) 258 + goto err; 259 + if (mb86a16_write(state, MB86A16_VIMAG, 0x38) < 0) 260 + goto err; 261 + if (mb86a16_write(state, MB86A16_FAGCS1, 0x00) < 0) 262 + goto err; 263 + if (mb86a16_write(state, MB86A16_FAGCS2, 0x1c) < 0) 264 + goto err; 265 + if (mb86a16_write(state, MB86A16_FAGCS3, 0x20) < 0) 266 + goto err; 267 + if (mb86a16_write(state, MB86A16_FAGCS4, 0x1e) < 0) 268 + goto err; 269 + if (mb86a16_write(state, MB86A16_FAGCS5, 0x23) < 0) 270 + goto err; 271 + if (mb86a16_write(state, 0x54, 0xff) < 0) 272 + goto err; 273 + if (mb86a16_write(state, MB86A16_TSOUT, 0x00) < 0) 274 + goto err; 275 + 276 + return 0; 277 + 278 + err: 279 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 280 + return -EREMOTEIO; 281 + } 282 + 283 + static int S01T_set(struct mb86a16_state *state, 284 + unsigned char s1t, 285 + unsigned s0t) 286 + { 287 + if (mb86a16_write(state, 0x33, (s1t << 3) | s0t) < 0) 288 + goto err; 289 + 290 + return 0; 291 + err: 292 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 293 + return -EREMOTEIO; 294 + } 295 + 296 + 297 + static int EN_set(struct mb86a16_state *state, 298 + int cren, 299 + int afcen) 300 + { 301 + unsigned char val; 302 + 303 + val = 0x7a | (cren << 7) | (afcen << 2); 304 + if (mb86a16_write(state, 0x49, val) < 0) 305 + goto err; 306 + 307 + return 0; 308 + err: 309 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 310 + return -EREMOTEIO; 311 + } 312 + 313 + static int AFCEXEN_set(struct mb86a16_state *state, 314 + int afcexen, 315 + int smrt) 316 + { 317 + unsigned char AFCA ; 318 + 319 + if (smrt > 18875) 320 + AFCA = 4; 321 + else if (smrt > 9375) 322 + AFCA = 3; 323 + else if (smrt > 2250) 324 + AFCA = 2; 325 + else 326 + AFCA = 1; 327 + 328 + if (mb86a16_write(state, 0x2a, 0x02 | (afcexen << 5) | (AFCA << 2)) < 0) 329 + goto err; 330 + 331 + return 0; 332 + 333 + err: 334 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 335 + return -EREMOTEIO; 336 + } 337 + 338 + static int DAGC_data_set(struct mb86a16_state *state, 339 + unsigned char DAGCA, 340 + unsigned char DAGCW) 341 + { 342 + if (mb86a16_write(state, 0x2d, (DAGCA << 3) | DAGCW) < 0) 343 + goto err; 344 + 345 + return 0; 346 + 347 + err: 348 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 349 + return -EREMOTEIO; 350 + } 351 + 352 + static void smrt_info_get(struct mb86a16_state *state, int rate) 353 + { 354 + if (rate >= 37501) { 355 + state->deci = 0; state->csel = 0; state->rsel = 0; 356 + } else if (rate >= 30001) { 357 + state->deci = 0; state->csel = 0; state->rsel = 1; 358 + } else if (rate >= 26251) { 359 + state->deci = 0; state->csel = 1; state->rsel = 0; 360 + } else if (rate >= 22501) { 361 + state->deci = 0; state->csel = 1; state->rsel = 1; 362 + } else if (rate >= 18751) { 363 + state->deci = 1; state->csel = 0; state->rsel = 0; 364 + } else if (rate >= 15001) { 365 + state->deci = 1; state->csel = 0; state->rsel = 1; 366 + } else if (rate >= 13126) { 367 + state->deci = 1; state->csel = 1; state->rsel = 0; 368 + } else if (rate >= 11251) { 369 + state->deci = 1; state->csel = 1; state->rsel = 1; 370 + } else if (rate >= 9376) { 371 + state->deci = 2; state->csel = 0; state->rsel = 0; 372 + } else if (rate >= 7501) { 373 + state->deci = 2; state->csel = 0; state->rsel = 1; 374 + } else if (rate >= 6563) { 375 + state->deci = 2; state->csel = 1; state->rsel = 0; 376 + } else if (rate >= 5626) { 377 + state->deci = 2; state->csel = 1; state->rsel = 1; 378 + } else if (rate >= 4688) { 379 + state->deci = 3; state->csel = 0; state->rsel = 0; 380 + } else if (rate >= 3751) { 381 + state->deci = 3; state->csel = 0; state->rsel = 1; 382 + } else if (rate >= 3282) { 383 + state->deci = 3; state->csel = 1; state->rsel = 0; 384 + } else if (rate >= 2814) { 385 + state->deci = 3; state->csel = 1; state->rsel = 1; 386 + } else if (rate >= 2344) { 387 + state->deci = 4; state->csel = 0; state->rsel = 0; 388 + } else if (rate >= 1876) { 389 + state->deci = 4; state->csel = 0; state->rsel = 1; 390 + } else if (rate >= 1641) { 391 + state->deci = 4; state->csel = 1; state->rsel = 0; 392 + } else if (rate >= 1407) { 393 + state->deci = 4; state->csel = 1; state->rsel = 1; 394 + } else if (rate >= 1172) { 395 + state->deci = 5; state->csel = 0; state->rsel = 0; 396 + } else if (rate >= 939) { 397 + state->deci = 5; state->csel = 0; state->rsel = 1; 398 + } else if (rate >= 821) { 399 + state->deci = 5; state->csel = 1; state->rsel = 0; 400 + } else { 401 + state->deci = 5; state->csel = 1; state->rsel = 1; 402 + } 403 + 404 + if (state->csel == 0) 405 + state->master_clk = 92000; 406 + else 407 + state->master_clk = 61333; 408 + 409 + } 410 + 411 + static int signal_det(struct mb86a16_state *state, 412 + int smrt, 413 + unsigned char *SIG) 414 + { 415 + 416 + int ret ; 417 + int smrtd ; 418 + int wait_sym ; 419 + 420 + u32 wait_t; 421 + unsigned char S[3] ; 422 + int i ; 423 + 424 + if (*SIG > 45) { 425 + if (CNTM_set(state, 2, 1, 2) < 0) { 426 + dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); 427 + return -1; 428 + } 429 + wait_sym = 40000; 430 + } else { 431 + if (CNTM_set(state, 3, 1, 2) < 0) { 432 + dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); 433 + return -1; 434 + } 435 + wait_sym = 80000; 436 + } 437 + for (i = 0; i < 3; i++) { 438 + if (i == 0) 439 + smrtd = smrt * 98 / 100; 440 + else if (i == 1) 441 + smrtd = smrt; 442 + else 443 + smrtd = smrt * 102 / 100; 444 + smrt_info_get(state, smrtd); 445 + smrt_set(state, smrtd); 446 + srst(state); 447 + wait_t = (wait_sym + 99 * smrtd / 100) / smrtd; 448 + if (wait_t == 0) 449 + wait_t = 1; 450 + msleep_interruptible(10); 451 + if (mb86a16_read(state, 0x37, &(S[i])) != 2) { 452 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 453 + return -EREMOTEIO; 454 + } 455 + } 456 + if ((S[1] > S[0] * 112 / 100) && 457 + (S[1] > S[2] * 112 / 100)) { 458 + 459 + ret = 1; 460 + } else { 461 + ret = 0; 462 + } 463 + *SIG = S[1]; 464 + 465 + if (CNTM_set(state, 0, 1, 2) < 0) { 466 + dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); 467 + return -1; 468 + } 469 + 470 + return ret; 471 + } 472 + 473 + static int rf_val_set(struct mb86a16_state *state, 474 + int f, 475 + int smrt, 476 + unsigned char R) 477 + { 478 + unsigned char C, F, B; 479 + int M; 480 + unsigned char rf_val[5]; 481 + int ack = -1; 482 + 483 + if (smrt > 37750) 484 + C = 1; 485 + else if (smrt > 18875) 486 + C = 2; 487 + else if (smrt > 5500) 488 + C = 3; 489 + else 490 + C = 4; 491 + 492 + if (smrt > 30500) 493 + F = 3; 494 + else if (smrt > 9375) 495 + F = 1; 496 + else if (smrt > 4625) 497 + F = 0; 498 + else 499 + F = 2; 500 + 501 + if (f < 1060) 502 + B = 0; 503 + else if (f < 1175) 504 + B = 1; 505 + else if (f < 1305) 506 + B = 2; 507 + else if (f < 1435) 508 + B = 3; 509 + else if (f < 1570) 510 + B = 4; 511 + else if (f < 1715) 512 + B = 5; 513 + else if (f < 1845) 514 + B = 6; 515 + else if (f < 1980) 516 + B = 7; 517 + else if (f < 2080) 518 + B = 8; 519 + else 520 + B = 9; 521 + 522 + M = f * (1 << R) / 2; 523 + 524 + rf_val[0] = 0x01 | (C << 3) | (F << 1); 525 + rf_val[1] = (R << 5) | ((M & 0x1f000) >> 12); 526 + rf_val[2] = (M & 0x00ff0) >> 4; 527 + rf_val[3] = ((M & 0x0000f) << 4) | B; 528 + 529 + /* Frequency Set */ 530 + if (mb86a16_write(state, 0x21, rf_val[0]) < 0) 531 + ack = 0; 532 + if (mb86a16_write(state, 0x22, rf_val[1]) < 0) 533 + ack = 0; 534 + if (mb86a16_write(state, 0x23, rf_val[2]) < 0) 535 + ack = 0; 536 + if (mb86a16_write(state, 0x24, rf_val[3]) < 0) 537 + ack = 0; 538 + if (mb86a16_write(state, 0x25, 0x01) < 0) 539 + ack = 0; 540 + if (ack == 0) { 541 + dprintk(verbose, MB86A16_ERROR, 1, "RF Setup - I2C transfer error"); 542 + return -EREMOTEIO; 543 + } 544 + 545 + return 0; 546 + } 547 + 548 + static int afcerr_chk(struct mb86a16_state *state) 549 + { 550 + unsigned char AFCM_L, AFCM_H ; 551 + int AFCM ; 552 + int afcm, afcerr ; 553 + 554 + if (mb86a16_read(state, 0x0e, &AFCM_L) != 2) 555 + goto err; 556 + if (mb86a16_read(state, 0x0f, &AFCM_H) != 2) 557 + goto err; 558 + 559 + AFCM = (AFCM_H << 8) + AFCM_L; 560 + 561 + if (AFCM > 2048) 562 + afcm = AFCM - 4096; 563 + else 564 + afcm = AFCM; 565 + afcerr = afcm * state->master_clk / 8192; 566 + 567 + return afcerr; 568 + 569 + err: 570 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 571 + return -EREMOTEIO; 572 + } 573 + 574 + static int dagcm_val_get(struct mb86a16_state *state) 575 + { 576 + int DAGCM; 577 + unsigned char DAGCM_H, DAGCM_L; 578 + 579 + if (mb86a16_read(state, 0x45, &DAGCM_L) != 2) 580 + goto err; 581 + if (mb86a16_read(state, 0x46, &DAGCM_H) != 2) 582 + goto err; 583 + 584 + DAGCM = (DAGCM_H << 8) + DAGCM_L; 585 + 586 + return DAGCM; 587 + 588 + err: 589 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 590 + return -EREMOTEIO; 591 + } 592 + 593 + static int mb86a16_read_status(struct dvb_frontend *fe, fe_status_t *status) 594 + { 595 + u8 stat, stat2; 596 + struct mb86a16_state *state = fe->demodulator_priv; 597 + 598 + *status = 0; 599 + 600 + if (mb86a16_read(state, MB86A16_SIG1, &stat) != 2) 601 + goto err; 602 + if (mb86a16_read(state, MB86A16_SIG2, &stat2) != 2) 603 + goto err; 604 + if ((stat > 25) && (stat2 > 25)) 605 + *status |= FE_HAS_SIGNAL; 606 + if ((stat > 45) && (stat2 > 45)) 607 + *status |= FE_HAS_CARRIER; 608 + 609 + if (mb86a16_read(state, MB86A16_STATUS, &stat) != 2) 610 + goto err; 611 + 612 + if (stat & 0x01) 613 + *status |= FE_HAS_SYNC; 614 + if (stat & 0x01) 615 + *status |= FE_HAS_VITERBI; 616 + 617 + if (mb86a16_read(state, MB86A16_FRAMESYNC, &stat) != 2) 618 + goto err; 619 + 620 + if ((stat & 0x0f) && (*status & FE_HAS_VITERBI)) 621 + *status |= FE_HAS_LOCK; 622 + 623 + return 0; 624 + 625 + err: 626 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 627 + return -EREMOTEIO; 628 + } 629 + 630 + static int sync_chk(struct mb86a16_state *state, 631 + unsigned char *VIRM) 632 + { 633 + unsigned char val; 634 + int sync; 635 + 636 + if (mb86a16_read(state, 0x0d, &val) != 2) 637 + goto err; 638 + 639 + dprintk(verbose, MB86A16_INFO, 1, "Status = %02x,", val); 640 + sync = val & 0x01; 641 + *VIRM = (val & 0x1c) >> 2; 642 + 643 + return sync; 644 + err: 645 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 646 + return -EREMOTEIO; 647 + 648 + } 649 + 650 + static int freqerr_chk(struct mb86a16_state *state, 651 + int fTP, 652 + int smrt, 653 + int unit) 654 + { 655 + unsigned char CRM, AFCML, AFCMH; 656 + unsigned char temp1, temp2, temp3; 657 + int crm, afcm, AFCM; 658 + int crrerr, afcerr; /* kHz */ 659 + int frqerr; /* MHz */ 660 + int afcen, afcexen = 0; 661 + int R, M, fOSC, fOSC_OFS; 662 + 663 + if (mb86a16_read(state, 0x43, &CRM) != 2) 664 + goto err; 665 + 666 + if (CRM > 127) 667 + crm = CRM - 256; 668 + else 669 + crm = CRM; 670 + 671 + crrerr = smrt * crm / 256; 672 + if (mb86a16_read(state, 0x49, &temp1) != 2) 673 + goto err; 674 + 675 + afcen = (temp1 & 0x04) >> 2; 676 + if (afcen == 0) { 677 + if (mb86a16_read(state, 0x2a, &temp1) != 2) 678 + goto err; 679 + afcexen = (temp1 & 0x20) >> 5; 680 + } 681 + 682 + if (afcen == 1) { 683 + if (mb86a16_read(state, 0x0e, &AFCML) != 2) 684 + goto err; 685 + if (mb86a16_read(state, 0x0f, &AFCMH) != 2) 686 + goto err; 687 + } else if (afcexen == 1) { 688 + if (mb86a16_read(state, 0x2b, &AFCML) != 2) 689 + goto err; 690 + if (mb86a16_read(state, 0x2c, &AFCMH) != 2) 691 + goto err; 692 + } 693 + if ((afcen == 1) || (afcexen == 1)) { 694 + smrt_info_get(state, smrt); 695 + AFCM = ((AFCMH & 0x01) << 8) + AFCML; 696 + if (AFCM > 255) 697 + afcm = AFCM - 512; 698 + else 699 + afcm = AFCM; 700 + 701 + afcerr = afcm * state->master_clk / 8192; 702 + } else 703 + afcerr = 0; 704 + 705 + if (mb86a16_read(state, 0x22, &temp1) != 2) 706 + goto err; 707 + if (mb86a16_read(state, 0x23, &temp2) != 2) 708 + goto err; 709 + if (mb86a16_read(state, 0x24, &temp3) != 2) 710 + goto err; 711 + 712 + R = (temp1 & 0xe0) >> 5; 713 + M = ((temp1 & 0x1f) << 12) + (temp2 << 4) + (temp3 >> 4); 714 + if (R == 0) 715 + fOSC = 2 * M; 716 + else 717 + fOSC = M; 718 + 719 + fOSC_OFS = fOSC - fTP; 720 + 721 + if (unit == 0) { /* MHz */ 722 + if (crrerr + afcerr + fOSC_OFS * 1000 >= 0) 723 + frqerr = (crrerr + afcerr + fOSC_OFS * 1000 + 500) / 1000; 724 + else 725 + frqerr = (crrerr + afcerr + fOSC_OFS * 1000 - 500) / 1000; 726 + } else { /* kHz */ 727 + frqerr = crrerr + afcerr + fOSC_OFS * 1000; 728 + } 729 + 730 + return frqerr; 731 + err: 732 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 733 + return -EREMOTEIO; 734 + } 735 + 736 + static unsigned char vco_dev_get(struct mb86a16_state *state, int smrt) 737 + { 738 + unsigned char R; 739 + 740 + if (smrt > 9375) 741 + R = 0; 742 + else 743 + R = 1; 744 + 745 + return R; 746 + } 747 + 748 + static void swp_info_get(struct mb86a16_state *state, 749 + int fOSC_start, 750 + int smrt, 751 + int v, int R, 752 + int swp_ofs, 753 + int *fOSC, 754 + int *afcex_freq, 755 + unsigned char *AFCEX_L, 756 + unsigned char *AFCEX_H) 757 + { 758 + int AFCEX ; 759 + int crnt_swp_freq ; 760 + 761 + crnt_swp_freq = fOSC_start * 1000 + v * swp_ofs; 762 + 763 + if (R == 0) 764 + *fOSC = (crnt_swp_freq + 1000) / 2000 * 2; 765 + else 766 + *fOSC = (crnt_swp_freq + 500) / 1000; 767 + 768 + if (*fOSC >= crnt_swp_freq) 769 + *afcex_freq = *fOSC * 1000 - crnt_swp_freq; 770 + else 771 + *afcex_freq = crnt_swp_freq - *fOSC * 1000; 772 + 773 + AFCEX = *afcex_freq * 8192 / state->master_clk; 774 + *AFCEX_L = AFCEX & 0x00ff; 775 + *AFCEX_H = (AFCEX & 0x0f00) >> 8; 776 + } 777 + 778 + 779 + static int swp_freq_calcuation(struct mb86a16_state *state, int i, int v, int *V, int vmax, int vmin, 780 + int SIGMIN, int fOSC, int afcex_freq, int swp_ofs, unsigned char *SIG1) 781 + { 782 + int swp_freq ; 783 + 784 + if ((i % 2 == 1) && (v <= vmax)) { 785 + /* positive v (case 1) */ 786 + if ((v - 1 == vmin) && 787 + (*(V + 30 + v) >= 0) && 788 + (*(V + 30 + v - 1) >= 0) && 789 + (*(V + 30 + v - 1) > *(V + 30 + v)) && 790 + (*(V + 30 + v - 1) > SIGMIN)) { 791 + 792 + swp_freq = fOSC * 1000 + afcex_freq - swp_ofs; 793 + *SIG1 = *(V + 30 + v - 1); 794 + } else if ((v == vmax) && 795 + (*(V + 30 + v) >= 0) && 796 + (*(V + 30 + v - 1) >= 0) && 797 + (*(V + 30 + v) > *(V + 30 + v - 1)) && 798 + (*(V + 30 + v) > SIGMIN)) { 799 + /* (case 2) */ 800 + swp_freq = fOSC * 1000 + afcex_freq; 801 + *SIG1 = *(V + 30 + v); 802 + } else if ((*(V + 30 + v) > 0) && 803 + (*(V + 30 + v - 1) > 0) && 804 + (*(V + 30 + v - 2) > 0) && 805 + (*(V + 30 + v - 3) > 0) && 806 + (*(V + 30 + v - 1) > *(V + 30 + v)) && 807 + (*(V + 30 + v - 2) > *(V + 30 + v - 3)) && 808 + ((*(V + 30 + v - 1) > SIGMIN) || 809 + (*(V + 30 + v - 2) > SIGMIN))) { 810 + /* (case 3) */ 811 + if (*(V + 30 + v - 1) >= *(V + 30 + v - 2)) { 812 + swp_freq = fOSC * 1000 + afcex_freq - swp_ofs; 813 + *SIG1 = *(V + 30 + v - 1); 814 + } else { 815 + swp_freq = fOSC * 1000 + afcex_freq - swp_ofs * 2; 816 + *SIG1 = *(V + 30 + v - 2); 817 + } 818 + } else if ((v == vmax) && 819 + (*(V + 30 + v) >= 0) && 820 + (*(V + 30 + v - 1) >= 0) && 821 + (*(V + 30 + v - 2) >= 0) && 822 + (*(V + 30 + v) > *(V + 30 + v - 2)) && 823 + (*(V + 30 + v - 1) > *(V + 30 + v - 2)) && 824 + ((*(V + 30 + v) > SIGMIN) || 825 + (*(V + 30 + v - 1) > SIGMIN))) { 826 + /* (case 4) */ 827 + if (*(V + 30 + v) >= *(V + 30 + v - 1)) { 828 + swp_freq = fOSC * 1000 + afcex_freq; 829 + *SIG1 = *(V + 30 + v); 830 + } else { 831 + swp_freq = fOSC * 1000 + afcex_freq - swp_ofs; 832 + *SIG1 = *(V + 30 + v - 1); 833 + } 834 + } else { 835 + swp_freq = -1 ; 836 + } 837 + } else if ((i % 2 == 0) && (v >= vmin)) { 838 + /* Negative v (case 1) */ 839 + if ((*(V + 30 + v) > 0) && 840 + (*(V + 30 + v + 1) > 0) && 841 + (*(V + 30 + v + 2) > 0) && 842 + (*(V + 30 + v + 1) > *(V + 30 + v)) && 843 + (*(V + 30 + v + 1) > *(V + 30 + v + 2)) && 844 + (*(V + 30 + v + 1) > SIGMIN)) { 845 + 846 + swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; 847 + *SIG1 = *(V + 30 + v + 1); 848 + } else if ((v + 1 == vmax) && 849 + (*(V + 30 + v) >= 0) && 850 + (*(V + 30 + v + 1) >= 0) && 851 + (*(V + 30 + v + 1) > *(V + 30 + v)) && 852 + (*(V + 30 + v + 1) > SIGMIN)) { 853 + /* (case 2) */ 854 + swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; 855 + *SIG1 = *(V + 30 + v); 856 + } else if ((v == vmin) && 857 + (*(V + 30 + v) > 0) && 858 + (*(V + 30 + v + 1) > 0) && 859 + (*(V + 30 + v + 2) > 0) && 860 + (*(V + 30 + v) > *(V + 30 + v + 1)) && 861 + (*(V + 30 + v) > *(V + 30 + v + 2)) && 862 + (*(V + 30 + v) > SIGMIN)) { 863 + /* (case 3) */ 864 + swp_freq = fOSC * 1000 + afcex_freq; 865 + *SIG1 = *(V + 30 + v); 866 + } else if ((*(V + 30 + v) >= 0) && 867 + (*(V + 30 + v + 1) >= 0) && 868 + (*(V + 30 + v + 2) >= 0) && 869 + (*(V + 30 + v + 3) >= 0) && 870 + (*(V + 30 + v + 1) > *(V + 30 + v)) && 871 + (*(V + 30 + v + 2) > *(V + 30 + v + 3)) && 872 + ((*(V + 30 + v + 1) > SIGMIN) || 873 + (*(V + 30 + v + 2) > SIGMIN))) { 874 + /* (case 4) */ 875 + if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) { 876 + swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; 877 + *SIG1 = *(V + 30 + v + 1); 878 + } else { 879 + swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2; 880 + *SIG1 = *(V + 30 + v + 2); 881 + } 882 + } else if ((*(V + 30 + v) >= 0) && 883 + (*(V + 30 + v + 1) >= 0) && 884 + (*(V + 30 + v + 2) >= 0) && 885 + (*(V + 30 + v + 3) >= 0) && 886 + (*(V + 30 + v) > *(V + 30 + v + 2)) && 887 + (*(V + 30 + v + 1) > *(V + 30 + v + 2)) && 888 + (*(V + 30 + v) > *(V + 30 + v + 3)) && 889 + (*(V + 30 + v + 1) > *(V + 30 + v + 3)) && 890 + ((*(V + 30 + v) > SIGMIN) || 891 + (*(V + 30 + v + 1) > SIGMIN))) { 892 + /* (case 5) */ 893 + if (*(V + 30 + v) >= *(V + 30 + v + 1)) { 894 + swp_freq = fOSC * 1000 + afcex_freq; 895 + *SIG1 = *(V + 30 + v); 896 + } else { 897 + swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; 898 + *SIG1 = *(V + 30 + v + 1); 899 + } 900 + } else if ((v + 2 == vmin) && 901 + (*(V + 30 + v) >= 0) && 902 + (*(V + 30 + v + 1) >= 0) && 903 + (*(V + 30 + v + 2) >= 0) && 904 + (*(V + 30 + v + 1) > *(V + 30 + v)) && 905 + (*(V + 30 + v + 2) > *(V + 30 + v)) && 906 + ((*(V + 30 + v + 1) > SIGMIN) || 907 + (*(V + 30 + v + 2) > SIGMIN))) { 908 + /* (case 6) */ 909 + if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) { 910 + swp_freq = fOSC * 1000 + afcex_freq + swp_ofs; 911 + *SIG1 = *(V + 30 + v + 1); 912 + } else { 913 + swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2; 914 + *SIG1 = *(V + 30 + v + 2); 915 + } 916 + } else if ((vmax == 0) && (vmin == 0) && (*(V + 30 + v) > SIGMIN)) { 917 + swp_freq = fOSC * 1000; 918 + *SIG1 = *(V + 30 + v); 919 + } else 920 + swp_freq = -1; 921 + } else 922 + swp_freq = -1; 923 + 924 + return swp_freq; 925 + } 926 + 927 + static void swp_info_get2(struct mb86a16_state *state, 928 + int smrt, 929 + int R, 930 + int swp_freq, 931 + int *afcex_freq, 932 + int *fOSC, 933 + unsigned char *AFCEX_L, 934 + unsigned char *AFCEX_H) 935 + { 936 + int AFCEX ; 937 + 938 + if (R == 0) 939 + *fOSC = (swp_freq + 1000) / 2000 * 2; 940 + else 941 + *fOSC = (swp_freq + 500) / 1000; 942 + 943 + if (*fOSC >= swp_freq) 944 + *afcex_freq = *fOSC * 1000 - swp_freq; 945 + else 946 + *afcex_freq = swp_freq - *fOSC * 1000; 947 + 948 + AFCEX = *afcex_freq * 8192 / state->master_clk; 949 + *AFCEX_L = AFCEX & 0x00ff; 950 + *AFCEX_H = (AFCEX & 0x0f00) >> 8; 951 + } 952 + 953 + static void afcex_info_get(struct mb86a16_state *state, 954 + int afcex_freq, 955 + unsigned char *AFCEX_L, 956 + unsigned char *AFCEX_H) 957 + { 958 + int AFCEX ; 959 + 960 + AFCEX = afcex_freq * 8192 / state->master_clk; 961 + *AFCEX_L = AFCEX & 0x00ff; 962 + *AFCEX_H = (AFCEX & 0x0f00) >> 8; 963 + } 964 + 965 + static int SEQ_set(struct mb86a16_state *state, unsigned char loop) 966 + { 967 + /* SLOCK0 = 0 */ 968 + if (mb86a16_write(state, 0x32, 0x02 | (loop << 2)) < 0) { 969 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 970 + return -EREMOTEIO; 971 + } 972 + 973 + return 0; 974 + } 975 + 976 + static int iq_vt_set(struct mb86a16_state *state, unsigned char IQINV) 977 + { 978 + /* Viterbi Rate, IQ Settings */ 979 + if (mb86a16_write(state, 0x06, 0xdf | (IQINV << 5)) < 0) { 980 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 981 + return -EREMOTEIO; 982 + } 983 + 984 + return 0; 985 + } 986 + 987 + static int FEC_srst(struct mb86a16_state *state) 988 + { 989 + if (mb86a16_write(state, MB86A16_RESET, 0x02) < 0) { 990 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 991 + return -EREMOTEIO; 992 + } 993 + 994 + return 0; 995 + } 996 + 997 + static int S2T_set(struct mb86a16_state *state, unsigned char S2T) 998 + { 999 + if (mb86a16_write(state, 0x34, 0x70 | S2T) < 0) { 1000 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1001 + return -EREMOTEIO; 1002 + } 1003 + 1004 + return 0; 1005 + } 1006 + 1007 + static int S45T_set(struct mb86a16_state *state, unsigned char S4T, unsigned char S5T) 1008 + { 1009 + if (mb86a16_write(state, 0x35, 0x00 | (S5T << 4) | S4T) < 0) { 1010 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1011 + return -EREMOTEIO; 1012 + } 1013 + 1014 + return 0; 1015 + } 1016 + 1017 + 1018 + static int mb86a16_set_fe(struct mb86a16_state *state) 1019 + { 1020 + u8 agcval, cnmval; 1021 + 1022 + int i, j; 1023 + int fOSC = 0; 1024 + int fOSC_start = 0; 1025 + int wait_t; 1026 + int fcp; 1027 + int swp_ofs; 1028 + int V[60]; 1029 + u8 SIG1MIN; 1030 + 1031 + unsigned char CREN, AFCEN, AFCEXEN; 1032 + unsigned char SIG1; 1033 + unsigned char TIMINT1, TIMINT2, TIMEXT; 1034 + unsigned char S0T, S1T; 1035 + unsigned char S2T; 1036 + /* unsigned char S2T, S3T; */ 1037 + unsigned char S4T, S5T; 1038 + unsigned char AFCEX_L, AFCEX_H; 1039 + unsigned char R; 1040 + unsigned char VIRM; 1041 + unsigned char ETH, VIA; 1042 + unsigned char junk; 1043 + 1044 + int loop; 1045 + int ftemp; 1046 + int v, vmax, vmin; 1047 + int vmax_his, vmin_his; 1048 + int swp_freq, prev_swp_freq[20]; 1049 + int prev_freq_num; 1050 + int signal_dupl; 1051 + int afcex_freq; 1052 + int signal; 1053 + int afcerr; 1054 + int temp_freq, delta_freq; 1055 + int dagcm[4]; 1056 + int smrt_d; 1057 + /* int freq_err; */ 1058 + int n; 1059 + int ret = -1; 1060 + int sync; 1061 + 1062 + dprintk(verbose, MB86A16_INFO, 1, "freq=%d Mhz, symbrt=%d Ksps", state->frequency, state->srate); 1063 + 1064 + fcp = 3000; 1065 + swp_ofs = state->srate / 4; 1066 + 1067 + for (i = 0; i < 60; i++) 1068 + V[i] = -1; 1069 + 1070 + for (i = 0; i < 20; i++) 1071 + prev_swp_freq[i] = 0; 1072 + 1073 + SIG1MIN = 25; 1074 + 1075 + for (n = 0; ((n < 3) && (ret == -1)); n++) { 1076 + SEQ_set(state, 0); 1077 + iq_vt_set(state, 0); 1078 + 1079 + CREN = 0; 1080 + AFCEN = 0; 1081 + AFCEXEN = 1; 1082 + TIMINT1 = 0; 1083 + TIMINT2 = 1; 1084 + TIMEXT = 2; 1085 + S1T = 0; 1086 + S0T = 0; 1087 + 1088 + if (initial_set(state) < 0) { 1089 + dprintk(verbose, MB86A16_ERROR, 1, "initial set failed"); 1090 + return -1; 1091 + } 1092 + if (DAGC_data_set(state, 3, 2) < 0) { 1093 + dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error"); 1094 + return -1; 1095 + } 1096 + if (EN_set(state, CREN, AFCEN) < 0) { 1097 + dprintk(verbose, MB86A16_ERROR, 1, "EN set error"); 1098 + return -1; /* (0, 0) */ 1099 + } 1100 + if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) { 1101 + dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); 1102 + return -1; /* (1, smrt) = (1, symbolrate) */ 1103 + } 1104 + if (CNTM_set(state, TIMINT1, TIMINT2, TIMEXT) < 0) { 1105 + dprintk(verbose, MB86A16_ERROR, 1, "CNTM set error"); 1106 + return -1; /* (0, 1, 2) */ 1107 + } 1108 + if (S01T_set(state, S1T, S0T) < 0) { 1109 + dprintk(verbose, MB86A16_ERROR, 1, "S01T set error"); 1110 + return -1; /* (0, 0) */ 1111 + } 1112 + smrt_info_get(state, state->srate); 1113 + if (smrt_set(state, state->srate) < 0) { 1114 + dprintk(verbose, MB86A16_ERROR, 1, "smrt info get error"); 1115 + return -1; 1116 + } 1117 + 1118 + R = vco_dev_get(state, state->srate); 1119 + if (R == 1) 1120 + fOSC_start = state->frequency; 1121 + 1122 + else if (R == 0) { 1123 + if (state->frequency % 2 == 0) { 1124 + fOSC_start = state->frequency; 1125 + } else { 1126 + fOSC_start = state->frequency + 1; 1127 + if (fOSC_start > 2150) 1128 + fOSC_start = state->frequency - 1; 1129 + } 1130 + } 1131 + loop = 1; 1132 + ftemp = fOSC_start * 1000; 1133 + vmax = 0 ; 1134 + while (loop == 1) { 1135 + ftemp = ftemp + swp_ofs; 1136 + vmax++; 1137 + 1138 + /* Upper bound */ 1139 + if (ftemp > 2150000) { 1140 + loop = 0; 1141 + vmax--; 1142 + } else { 1143 + if ((ftemp == 2150000) || 1144 + (ftemp - state->frequency * 1000 >= fcp + state->srate / 4)) 1145 + loop = 0; 1146 + } 1147 + } 1148 + 1149 + loop = 1; 1150 + ftemp = fOSC_start * 1000; 1151 + vmin = 0 ; 1152 + while (loop == 1) { 1153 + ftemp = ftemp - swp_ofs; 1154 + vmin--; 1155 + 1156 + /* Lower bound */ 1157 + if (ftemp < 950000) { 1158 + loop = 0; 1159 + vmin++; 1160 + } else { 1161 + if ((ftemp == 950000) || 1162 + (state->frequency * 1000 - ftemp >= fcp + state->srate / 4)) 1163 + loop = 0; 1164 + } 1165 + } 1166 + 1167 + wait_t = (8000 + state->srate / 2) / state->srate; 1168 + if (wait_t == 0) 1169 + wait_t = 1; 1170 + 1171 + i = 0; 1172 + j = 0; 1173 + prev_freq_num = 0; 1174 + loop = 1; 1175 + signal = 0; 1176 + vmax_his = 0; 1177 + vmin_his = 0; 1178 + v = 0; 1179 + 1180 + while (loop == 1) { 1181 + swp_info_get(state, fOSC_start, state->srate, 1182 + v, R, swp_ofs, &fOSC, 1183 + &afcex_freq, &AFCEX_L, &AFCEX_H); 1184 + 1185 + udelay(100); 1186 + if (rf_val_set(state, fOSC, state->srate, R) < 0) { 1187 + dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); 1188 + return -1; 1189 + } 1190 + udelay(100); 1191 + if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { 1192 + dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); 1193 + return -1; 1194 + } 1195 + if (srst(state) < 0) { 1196 + dprintk(verbose, MB86A16_ERROR, 1, "srst error"); 1197 + return -1; 1198 + } 1199 + msleep_interruptible(wait_t); 1200 + 1201 + if (mb86a16_read(state, 0x37, &SIG1) != 2) { 1202 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1203 + return -1; 1204 + } 1205 + V[30 + v] = SIG1 ; 1206 + swp_freq = swp_freq_calcuation(state, i, v, V, vmax, vmin, 1207 + SIG1MIN, fOSC, afcex_freq, 1208 + swp_ofs, &SIG1); /* changed */ 1209 + 1210 + signal_dupl = 0; 1211 + for (j = 0; j < prev_freq_num; j++) { 1212 + if ((ABS(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) { 1213 + signal_dupl = 1; 1214 + dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j); 1215 + } 1216 + } 1217 + if ((signal_dupl == 0) && (swp_freq > 0) && (ABS(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) { 1218 + dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate); 1219 + prev_swp_freq[prev_freq_num] = swp_freq; 1220 + prev_freq_num++; 1221 + swp_info_get2(state, state->srate, R, swp_freq, 1222 + &afcex_freq, &fOSC, 1223 + &AFCEX_L, &AFCEX_H); 1224 + 1225 + if (rf_val_set(state, fOSC, state->srate, R) < 0) { 1226 + dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); 1227 + return -1; 1228 + } 1229 + if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { 1230 + dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); 1231 + return -1; 1232 + } 1233 + signal = signal_det(state, state->srate, &SIG1); 1234 + if (signal == 1) { 1235 + dprintk(verbose, MB86A16_ERROR, 1, "***** Signal Found *****"); 1236 + loop = 0; 1237 + } else { 1238 + dprintk(verbose, MB86A16_ERROR, 1, "!!!!! No signal !!!!!, try again..."); 1239 + smrt_info_get(state, state->srate); 1240 + if (smrt_set(state, state->srate) < 0) { 1241 + dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); 1242 + return -1; 1243 + } 1244 + } 1245 + } 1246 + if (v > vmax) 1247 + vmax_his = 1 ; 1248 + if (v < vmin) 1249 + vmin_his = 1 ; 1250 + i++; 1251 + 1252 + if ((i % 2 == 1) && (vmax_his == 1)) 1253 + i++; 1254 + if ((i % 2 == 0) && (vmin_his == 1)) 1255 + i++; 1256 + 1257 + if (i % 2 == 1) 1258 + v = (i + 1) / 2; 1259 + else 1260 + v = -i / 2; 1261 + 1262 + if ((vmax_his == 1) && (vmin_his == 1)) 1263 + loop = 0 ; 1264 + } 1265 + 1266 + if (signal == 1) { 1267 + dprintk(verbose, MB86A16_INFO, 1, " Start Freq Error Check"); 1268 + S1T = 7 ; 1269 + S0T = 1 ; 1270 + CREN = 0 ; 1271 + AFCEN = 1 ; 1272 + AFCEXEN = 0 ; 1273 + 1274 + if (S01T_set(state, S1T, S0T) < 0) { 1275 + dprintk(verbose, MB86A16_ERROR, 1, "S01T set error"); 1276 + return -1; 1277 + } 1278 + smrt_info_get(state, state->srate); 1279 + if (smrt_set(state, state->srate) < 0) { 1280 + dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); 1281 + return -1; 1282 + } 1283 + if (EN_set(state, CREN, AFCEN) < 0) { 1284 + dprintk(verbose, MB86A16_ERROR, 1, "EN set error"); 1285 + return -1; 1286 + } 1287 + if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) { 1288 + dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); 1289 + return -1; 1290 + } 1291 + afcex_info_get(state, afcex_freq, &AFCEX_L, &AFCEX_H); 1292 + if (afcofs_data_set(state, AFCEX_L, AFCEX_H) < 0) { 1293 + dprintk(verbose, MB86A16_ERROR, 1, "AFCOFS data set error"); 1294 + return -1; 1295 + } 1296 + if (srst(state) < 0) { 1297 + dprintk(verbose, MB86A16_ERROR, 1, "srst error"); 1298 + return -1; 1299 + } 1300 + /* delay 4~200 */ 1301 + wait_t = 200000 / state->master_clk + 200000 / state->srate; 1302 + msleep(wait_t); 1303 + afcerr = afcerr_chk(state); 1304 + if (afcerr == -1) 1305 + return -1; 1306 + 1307 + swp_freq = fOSC * 1000 + afcerr ; 1308 + AFCEXEN = 1 ; 1309 + if (state->srate >= 1500) 1310 + smrt_d = state->srate / 3; 1311 + else 1312 + smrt_d = state->srate / 2; 1313 + smrt_info_get(state, smrt_d); 1314 + if (smrt_set(state, smrt_d) < 0) { 1315 + dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); 1316 + return -1; 1317 + } 1318 + if (AFCEXEN_set(state, AFCEXEN, smrt_d) < 0) { 1319 + dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); 1320 + return -1; 1321 + } 1322 + R = vco_dev_get(state, smrt_d); 1323 + if (DAGC_data_set(state, 2, 0) < 0) { 1324 + dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error"); 1325 + return -1; 1326 + } 1327 + for (i = 0; i < 3; i++) { 1328 + temp_freq = swp_freq + (i - 1) * state->srate / 8; 1329 + swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); 1330 + if (rf_val_set(state, fOSC, smrt_d, R) < 0) { 1331 + dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); 1332 + return -1; 1333 + } 1334 + if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { 1335 + dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); 1336 + return -1; 1337 + } 1338 + wait_t = 200000 / state->master_clk + 40000 / smrt_d; 1339 + msleep(wait_t); 1340 + dagcm[i] = dagcm_val_get(state); 1341 + } 1342 + if ((dagcm[0] > dagcm[1]) && 1343 + (dagcm[0] > dagcm[2]) && 1344 + (dagcm[0] - dagcm[1] > 2 * (dagcm[2] - dagcm[1]))) { 1345 + 1346 + temp_freq = swp_freq - 2 * state->srate / 8; 1347 + swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); 1348 + if (rf_val_set(state, fOSC, smrt_d, R) < 0) { 1349 + dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); 1350 + return -1; 1351 + } 1352 + if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { 1353 + dprintk(verbose, MB86A16_ERROR, 1, "afcex data set"); 1354 + return -1; 1355 + } 1356 + wait_t = 200000 / state->master_clk + 40000 / smrt_d; 1357 + msleep(wait_t); 1358 + dagcm[3] = dagcm_val_get(state); 1359 + if (dagcm[3] > dagcm[1]) 1360 + delta_freq = (dagcm[2] - dagcm[0] + dagcm[1] - dagcm[3]) * state->srate / 300; 1361 + else 1362 + delta_freq = 0; 1363 + } else if ((dagcm[2] > dagcm[1]) && 1364 + (dagcm[2] > dagcm[0]) && 1365 + (dagcm[2] - dagcm[1] > 2 * (dagcm[0] - dagcm[1]))) { 1366 + 1367 + temp_freq = swp_freq + 2 * state->srate / 8; 1368 + swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); 1369 + if (rf_val_set(state, fOSC, smrt_d, R) < 0) { 1370 + dprintk(verbose, MB86A16_ERROR, 1, "rf val set"); 1371 + return -1; 1372 + } 1373 + if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { 1374 + dprintk(verbose, MB86A16_ERROR, 1, "afcex data set"); 1375 + return -1; 1376 + } 1377 + wait_t = 200000 / state->master_clk + 40000 / smrt_d; 1378 + msleep(wait_t); 1379 + dagcm[3] = dagcm_val_get(state); 1380 + if (dagcm[3] > dagcm[1]) 1381 + delta_freq = (dagcm[2] - dagcm[0] + dagcm[3] - dagcm[1]) * state->srate / 300; 1382 + else 1383 + delta_freq = 0 ; 1384 + 1385 + } else { 1386 + delta_freq = 0 ; 1387 + } 1388 + dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq); 1389 + swp_freq += delta_freq; 1390 + dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq); 1391 + if (ABS(state->frequency * 1000 - swp_freq) > 3800) { 1392 + dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL !"); 1393 + } else { 1394 + 1395 + S1T = 0; 1396 + S0T = 3; 1397 + CREN = 1; 1398 + AFCEN = 0; 1399 + AFCEXEN = 1; 1400 + 1401 + if (S01T_set(state, S1T, S0T) < 0) { 1402 + dprintk(verbose, MB86A16_ERROR, 1, "S01T set error"); 1403 + return -1; 1404 + } 1405 + if (DAGC_data_set(state, 0, 0) < 0) { 1406 + dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error"); 1407 + return -1; 1408 + } 1409 + R = vco_dev_get(state, state->srate); 1410 + smrt_info_get(state, state->srate); 1411 + if (smrt_set(state, state->srate) < 0) { 1412 + dprintk(verbose, MB86A16_ERROR, 1, "smrt set error"); 1413 + return -1; 1414 + } 1415 + if (EN_set(state, CREN, AFCEN) < 0) { 1416 + dprintk(verbose, MB86A16_ERROR, 1, "EN set error"); 1417 + return -1; 1418 + } 1419 + if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) { 1420 + dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error"); 1421 + return -1; 1422 + } 1423 + swp_info_get2(state, state->srate, R, swp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H); 1424 + if (rf_val_set(state, fOSC, state->srate, R) < 0) { 1425 + dprintk(verbose, MB86A16_ERROR, 1, "rf val set error"); 1426 + return -1; 1427 + } 1428 + if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) { 1429 + dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error"); 1430 + return -1; 1431 + } 1432 + if (srst(state) < 0) { 1433 + dprintk(verbose, MB86A16_ERROR, 1, "srst error"); 1434 + return -1; 1435 + } 1436 + wait_t = 7 + (10000 + state->srate / 2) / state->srate; 1437 + if (wait_t == 0) 1438 + wait_t = 1; 1439 + msleep_interruptible(wait_t); 1440 + if (mb86a16_read(state, 0x37, &SIG1) != 2) { 1441 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1442 + return -EREMOTEIO; 1443 + } 1444 + 1445 + if (SIG1 > 110) { 1446 + S2T = 4; S4T = 1; S5T = 6; ETH = 4; VIA = 6; 1447 + wait_t = 7 + (917504 + state->srate / 2) / state->srate; 1448 + } else if (SIG1 > 105) { 1449 + S2T = 4; S4T = 2; S5T = 8; ETH = 7; VIA = 2; 1450 + wait_t = 7 + (1048576 + state->srate / 2) / state->srate; 1451 + } else if (SIG1 > 85) { 1452 + S2T = 5; S4T = 2; S5T = 8; ETH = 7; VIA = 2; 1453 + wait_t = 7 + (1310720 + state->srate / 2) / state->srate; 1454 + } else if (SIG1 > 65) { 1455 + S2T = 6; S4T = 2; S5T = 8; ETH = 7; VIA = 2; 1456 + wait_t = 7 + (1572864 + state->srate / 2) / state->srate; 1457 + } else { 1458 + S2T = 7; S4T = 2; S5T = 8; ETH = 7; VIA = 2; 1459 + wait_t = 7 + (2097152 + state->srate / 2) / state->srate; 1460 + } 1461 + wait_t *= 2; /* FOS */ 1462 + S2T_set(state, S2T); 1463 + S45T_set(state, S4T, S5T); 1464 + Vi_set(state, ETH, VIA); 1465 + srst(state); 1466 + msleep_interruptible(wait_t); 1467 + sync = sync_chk(state, &VIRM); 1468 + dprintk(verbose, MB86A16_INFO, 1, "-------- Viterbi=[%d] SYNC=[%d] ---------", VIRM, sync); 1469 + if (VIRM) { 1470 + if (VIRM == 4) { 1471 + /* 5/6 */ 1472 + if (SIG1 > 110) 1473 + wait_t = (786432 + state->srate / 2) / state->srate; 1474 + else 1475 + wait_t = (1572864 + state->srate / 2) / state->srate; 1476 + if (state->srate < 5000) 1477 + /* FIXME ! , should be a long wait ! */ 1478 + msleep_interruptible(wait_t); 1479 + else 1480 + msleep_interruptible(wait_t); 1481 + 1482 + if (sync_chk(state, &junk) == 0) { 1483 + iq_vt_set(state, 1); 1484 + FEC_srst(state); 1485 + } 1486 + } 1487 + /* 1/2, 2/3, 3/4, 7/8 */ 1488 + if (SIG1 > 110) 1489 + wait_t = (786432 + state->srate / 2) / state->srate; 1490 + else 1491 + wait_t = (1572864 + state->srate / 2) / state->srate; 1492 + msleep_interruptible(wait_t); 1493 + SEQ_set(state, 1); 1494 + } else { 1495 + dprintk(verbose, MB86A16_INFO, 1, "NO -- SYNC"); 1496 + SEQ_set(state, 1); 1497 + ret = -1; 1498 + } 1499 + } 1500 + } else { 1501 + dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL"); 1502 + ret = -1; 1503 + } 1504 + 1505 + sync = sync_chk(state, &junk); 1506 + if (sync) { 1507 + dprintk(verbose, MB86A16_INFO, 1, "******* SYNC *******"); 1508 + freqerr_chk(state, state->frequency, state->srate, 1); 1509 + ret = 0; 1510 + break; 1511 + } 1512 + } 1513 + 1514 + mb86a16_read(state, 0x15, &agcval); 1515 + mb86a16_read(state, 0x26, &cnmval); 1516 + dprintk(verbose, MB86A16_INFO, 1, "AGC = %02x CNM = %02x", agcval, cnmval); 1517 + 1518 + return ret; 1519 + } 1520 + 1521 + static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe, 1522 + struct dvb_diseqc_master_cmd *cmd) 1523 + { 1524 + struct mb86a16_state *state = fe->demodulator_priv; 1525 + int i; 1526 + u8 regs; 1527 + 1528 + if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0) 1529 + goto err; 1530 + if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0) 1531 + goto err; 1532 + if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0) 1533 + goto err; 1534 + 1535 + regs = 0x18; 1536 + 1537 + if (cmd->msg_len > 5 || cmd->msg_len < 4) 1538 + return -EINVAL; 1539 + 1540 + for (i = 0; i < cmd->msg_len; i++) { 1541 + if (mb86a16_write(state, regs, cmd->msg[i]) < 0) 1542 + goto err; 1543 + 1544 + regs++; 1545 + } 1546 + i += 0x90; 1547 + 1548 + msleep_interruptible(10); 1549 + 1550 + if (mb86a16_write(state, MB86A16_DCC1, i) < 0) 1551 + goto err; 1552 + if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) 1553 + goto err; 1554 + 1555 + return 0; 1556 + 1557 + err: 1558 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1559 + return -EREMOTEIO; 1560 + } 1561 + 1562 + static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) 1563 + { 1564 + struct mb86a16_state *state = fe->demodulator_priv; 1565 + 1566 + switch (burst) { 1567 + case SEC_MINI_A: 1568 + if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA | 1569 + MB86A16_DCC1_TBEN | 1570 + MB86A16_DCC1_TBO) < 0) 1571 + goto err; 1572 + if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) 1573 + goto err; 1574 + break; 1575 + case SEC_MINI_B: 1576 + if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA | 1577 + MB86A16_DCC1_TBEN) < 0) 1578 + goto err; 1579 + if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) 1580 + goto err; 1581 + break; 1582 + } 1583 + 1584 + return 0; 1585 + err: 1586 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1587 + return -EREMOTEIO; 1588 + } 1589 + 1590 + static int mb86a16_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 1591 + { 1592 + struct mb86a16_state *state = fe->demodulator_priv; 1593 + 1594 + switch (tone) { 1595 + case SEC_TONE_ON: 1596 + if (mb86a16_write(state, MB86A16_TONEOUT2, 0x00) < 0) 1597 + goto err; 1598 + if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA | 1599 + MB86A16_DCC1_CTOE) < 0) 1600 + 1601 + goto err; 1602 + if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0) 1603 + goto err; 1604 + break; 1605 + case SEC_TONE_OFF: 1606 + if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0) 1607 + goto err; 1608 + if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0) 1609 + goto err; 1610 + if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0) 1611 + goto err; 1612 + break; 1613 + default: 1614 + return -EINVAL; 1615 + } 1616 + return 0; 1617 + 1618 + err: 1619 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1620 + return -EREMOTEIO; 1621 + } 1622 + 1623 + static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe, 1624 + struct dvb_frontend_parameters *p) 1625 + { 1626 + struct mb86a16_state *state = fe->demodulator_priv; 1627 + 1628 + state->frequency = p->frequency / 1000; 1629 + state->srate = p->u.qpsk.symbol_rate / 1000; 1630 + 1631 + if (!mb86a16_set_fe(state)) { 1632 + dprintk(verbose, MB86A16_ERROR, 1, "Succesfully acquired LOCK"); 1633 + return DVBFE_ALGO_SEARCH_SUCCESS; 1634 + } 1635 + 1636 + dprintk(verbose, MB86A16_ERROR, 1, "Lock acquisition failed!"); 1637 + return DVBFE_ALGO_SEARCH_FAILED; 1638 + } 1639 + 1640 + static void mb86a16_release(struct dvb_frontend *fe) 1641 + { 1642 + struct mb86a16_state *state = fe->demodulator_priv; 1643 + kfree(state); 1644 + } 1645 + 1646 + static int mb86a16_init(struct dvb_frontend *fe) 1647 + { 1648 + return 0; 1649 + } 1650 + 1651 + static int mb86a16_sleep(struct dvb_frontend *fe) 1652 + { 1653 + return 0; 1654 + } 1655 + 1656 + static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber) 1657 + { 1658 + u8 ber_mon, ber_tab, ber_lsb, ber_mid, ber_msb, ber_tim, ber_rst; 1659 + u32 timer; 1660 + 1661 + struct mb86a16_state *state = fe->demodulator_priv; 1662 + 1663 + *ber = 0; 1664 + if (mb86a16_read(state, MB86A16_BERMON, &ber_mon) != 2) 1665 + goto err; 1666 + if (mb86a16_read(state, MB86A16_BERTAB, &ber_tab) != 2) 1667 + goto err; 1668 + if (mb86a16_read(state, MB86A16_BERLSB, &ber_lsb) != 2) 1669 + goto err; 1670 + if (mb86a16_read(state, MB86A16_BERMID, &ber_mid) != 2) 1671 + goto err; 1672 + if (mb86a16_read(state, MB86A16_BERMSB, &ber_msb) != 2) 1673 + goto err; 1674 + /* BER monitor invalid when BER_EN = 0 */ 1675 + if (ber_mon & 0x04) { 1676 + /* coarse, fast calculation */ 1677 + *ber = ber_tab & 0x1f; 1678 + dprintk(verbose, MB86A16_DEBUG, 1, "BER coarse=[0x%02x]", *ber); 1679 + if (ber_mon & 0x01) { 1680 + /* 1681 + * BER_SEL = 1, The monitored BER is the estimated 1682 + * value with a Reed-Solomon decoder error amount at 1683 + * the deinterleaver output. 1684 + * monitored BER is expressed as a 20 bit output in total 1685 + */ 1686 + ber_rst = ber_mon >> 3; 1687 + *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb; 1688 + if (ber_rst == 0) 1689 + timer = 12500000; 1690 + if (ber_rst == 1) 1691 + timer = 25000000; 1692 + if (ber_rst == 2) 1693 + timer = 50000000; 1694 + if (ber_rst == 3) 1695 + timer = 100000000; 1696 + 1697 + *ber /= timer; 1698 + dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber); 1699 + } else { 1700 + /* 1701 + * BER_SEL = 0, The monitored BER is the estimated 1702 + * value with a Viterbi decoder error amount at the 1703 + * QPSK demodulator output. 1704 + * monitored BER is expressed as a 24 bit output in total 1705 + */ 1706 + ber_tim = ber_mon >> 1; 1707 + *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb; 1708 + if (ber_tim == 0) 1709 + timer = 16; 1710 + if (ber_tim == 1) 1711 + timer = 24; 1712 + 1713 + *ber /= 2 ^ timer; 1714 + dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber); 1715 + } 1716 + } 1717 + return 0; 1718 + err: 1719 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1720 + return -EREMOTEIO; 1721 + } 1722 + 1723 + static int mb86a16_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 1724 + { 1725 + u8 agcm = 0; 1726 + struct mb86a16_state *state = fe->demodulator_priv; 1727 + 1728 + *strength = 0; 1729 + if (mb86a16_read(state, MB86A16_AGCM, &agcm) != 2) { 1730 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1731 + return -EREMOTEIO; 1732 + } 1733 + 1734 + *strength = ((0xff - agcm) * 100) / 256; 1735 + dprintk(verbose, MB86A16_DEBUG, 1, "Signal strength=[%d %%]", (u8) *strength); 1736 + *strength = (0xffff - 0xff) + agcm; 1737 + 1738 + return 0; 1739 + } 1740 + 1741 + struct cnr { 1742 + u8 cn_reg; 1743 + u8 cn_val; 1744 + }; 1745 + 1746 + static const struct cnr cnr_tab[] = { 1747 + { 35, 2 }, 1748 + { 40, 3 }, 1749 + { 50, 4 }, 1750 + { 60, 5 }, 1751 + { 70, 6 }, 1752 + { 80, 7 }, 1753 + { 92, 8 }, 1754 + { 103, 9 }, 1755 + { 115, 10 }, 1756 + { 138, 12 }, 1757 + { 162, 15 }, 1758 + { 180, 18 }, 1759 + { 185, 19 }, 1760 + { 189, 20 }, 1761 + { 195, 22 }, 1762 + { 199, 24 }, 1763 + { 201, 25 }, 1764 + { 202, 26 }, 1765 + { 203, 27 }, 1766 + { 205, 28 }, 1767 + { 208, 30 } 1768 + }; 1769 + 1770 + static int mb86a16_read_snr(struct dvb_frontend *fe, u16 *snr) 1771 + { 1772 + struct mb86a16_state *state = fe->demodulator_priv; 1773 + int i = 0; 1774 + int low_tide = 2, high_tide = 30, q_level; 1775 + u8 cn; 1776 + 1777 + *snr = 0; 1778 + if (mb86a16_read(state, 0x26, &cn) != 2) { 1779 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1780 + return -EREMOTEIO; 1781 + } 1782 + 1783 + for (i = 0; i < ARRAY_SIZE(cnr_tab); i++) { 1784 + if (cn < cnr_tab[i].cn_reg) { 1785 + *snr = cnr_tab[i].cn_val; 1786 + break; 1787 + } 1788 + } 1789 + q_level = (*snr * 100) / (high_tide - low_tide); 1790 + dprintk(verbose, MB86A16_ERROR, 1, "SNR (Quality) = [%d dB], Level=%d %%", *snr, q_level); 1791 + *snr = (0xffff - 0xff) + *snr; 1792 + 1793 + return 0; 1794 + } 1795 + 1796 + static int mb86a16_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 1797 + { 1798 + u8 dist; 1799 + struct mb86a16_state *state = fe->demodulator_priv; 1800 + 1801 + if (mb86a16_read(state, MB86A16_DISTMON, &dist) != 2) { 1802 + dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); 1803 + return -EREMOTEIO; 1804 + } 1805 + *ucblocks = dist; 1806 + 1807 + return 0; 1808 + } 1809 + 1810 + static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe) 1811 + { 1812 + return DVBFE_ALGO_CUSTOM; 1813 + } 1814 + 1815 + static struct dvb_frontend_ops mb86a16_ops = { 1816 + .info = { 1817 + .name = "Fujitsu MB86A16 DVB-S", 1818 + .type = FE_QPSK, 1819 + .frequency_min = 950000, 1820 + .frequency_max = 2150000, 1821 + .frequency_stepsize = 3000, 1822 + .frequency_tolerance = 0, 1823 + .symbol_rate_min = 1000000, 1824 + .symbol_rate_max = 45000000, 1825 + .symbol_rate_tolerance = 500, 1826 + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | 1827 + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | 1828 + FE_CAN_FEC_7_8 | FE_CAN_QPSK | 1829 + FE_CAN_FEC_AUTO 1830 + }, 1831 + .release = mb86a16_release, 1832 + 1833 + .get_frontend_algo = mb86a16_frontend_algo, 1834 + .search = mb86a16_search, 1835 + .read_status = mb86a16_read_status, 1836 + .init = mb86a16_init, 1837 + .sleep = mb86a16_sleep, 1838 + .read_status = mb86a16_read_status, 1839 + 1840 + .read_ber = mb86a16_read_ber, 1841 + .read_signal_strength = mb86a16_read_signal_strength, 1842 + .read_snr = mb86a16_read_snr, 1843 + .read_ucblocks = mb86a16_read_ucblocks, 1844 + 1845 + .diseqc_send_master_cmd = mb86a16_send_diseqc_msg, 1846 + .diseqc_send_burst = mb86a16_send_diseqc_burst, 1847 + .set_tone = mb86a16_set_tone, 1848 + }; 1849 + 1850 + struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, 1851 + struct i2c_adapter *i2c_adap) 1852 + { 1853 + u8 dev_id = 0; 1854 + struct mb86a16_state *state = NULL; 1855 + 1856 + state = kmalloc(sizeof(struct mb86a16_state), GFP_KERNEL); 1857 + if (state == NULL) 1858 + goto error; 1859 + 1860 + state->config = config; 1861 + state->i2c_adap = i2c_adap; 1862 + 1863 + mb86a16_read(state, 0x7f, &dev_id); 1864 + if (dev_id != 0xfe) 1865 + goto error; 1866 + 1867 + memcpy(&state->frontend.ops, &mb86a16_ops, sizeof(struct dvb_frontend_ops)); 1868 + state->frontend.demodulator_priv = state; 1869 + state->frontend.ops.set_voltage = state->config->set_voltage; 1870 + 1871 + return &state->frontend; 1872 + error: 1873 + kfree(state); 1874 + return NULL; 1875 + } 1876 + EXPORT_SYMBOL(mb86a16_attach); 1877 + MODULE_LICENSE("GPL"); 1878 + MODULE_AUTHOR("Manu Abraham");
+52
drivers/media/dvb/frontends/mb86a16.h
··· 1 + /* 2 + Fujitsu MB86A16 DVB-S/DSS DC Receiver driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MB86A16_H 22 + #define __MB86A16_H 23 + 24 + #include <linux/dvb/frontend.h> 25 + #include "dvb_frontend.h" 26 + 27 + 28 + struct mb86a16_config { 29 + u8 demod_address; 30 + 31 + int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); 32 + }; 33 + 34 + 35 + 36 + #if defined(CONFIG_DVB_MB86A16) || (defined(CONFIG_DVB_MB86A16_MODULE) && defined(MODULE)) 37 + 38 + extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, 39 + struct i2c_adapter *i2c_adap); 40 + 41 + #else 42 + 43 + static inline struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, 44 + struct i2c_adapter *i2c_adap) 45 + { 46 + printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); 47 + return NULL; 48 + } 49 + 50 + #endif /* CONFIG_DVB_MB86A16 */ 51 + 52 + #endif /* __MB86A16_H */
+151
drivers/media/dvb/frontends/mb86a16_priv.h
··· 1 + /* 2 + Fujitsu MB86A16 DVB-S/DSS DC Receiver driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MB86A16_PRIV_H 22 + #define __MB86A16_PRIV_H 23 + 24 + #define MB86A16_TSOUT 0x00 25 + #define MB86A16_TSOUT_HIZSEL (0x01 << 5) 26 + #define MB86A16_TSOUT_HIZCNTI (0x01 << 4) 27 + #define MB86A16_TSOUT_MODE (0x01 << 3) 28 + #define MB86A16_TSOUT_ORDER (0x01 << 2) 29 + #define MB86A16_TSOUT_ERROR (0x01 << 1) 30 + #define Mb86A16_TSOUT_EDGE (0x01 << 0) 31 + 32 + #define MB86A16_FEC 0x01 33 + #define MB86A16_FEC_FSYNC (0x01 << 5) 34 + #define MB86A16_FEC_PCKB8 (0x01 << 4) 35 + #define MB86A16_FEC_DVDS (0x01 << 3) 36 + #define MB86A16_FEC_EREN (0x01 << 2) 37 + #define Mb86A16_FEC_RSEN (0x01 << 1) 38 + #define MB86A16_FEC_DIEN (0x01 << 0) 39 + 40 + #define MB86A16_AGC 0x02 41 + #define MB86A16_AGC_AGMD (0x01 << 6) 42 + #define MB86A16_AGC_AGCW (0x0f << 2) 43 + #define MB86A16_AGC_AGCP (0x01 << 1) 44 + #define MB86A16_AGC_AGCR (0x01 << 0) 45 + 46 + #define MB86A16_SRATE1 0x03 47 + #define MB86A16_SRATE1_DECI (0x07 << 2) 48 + #define MB86A16_SRATE1_CSEL (0x01 << 1) 49 + #define MB86A16_SRATE1_RSEL (0x01 << 0) 50 + 51 + #define MB86A16_SRATE2 0x04 52 + #define MB86A16_SRATE2_STOFSL (0xff << 0) 53 + 54 + #define MB86A16_SRATE3 0x05 55 + #define MB86A16_SRATE2_STOFSH (0xff << 0) 56 + 57 + #define MB86A16_VITERBI 0x06 58 + #define MB86A16_FRAMESYNC 0x07 59 + #define MB86A16_CRLFILTCOEF1 0x08 60 + #define MB86A16_CRLFILTCOEF2 0x09 61 + #define MB86A16_STRFILTCOEF1 0x0a 62 + #define MB86A16_STRFILTCOEF2 0x0b 63 + #define MB86A16_RESET 0x0c 64 + #define MB86A16_STATUS 0x0d 65 + #define MB86A16_AFCML 0x0e 66 + #define MB86A16_AFCMH 0x0f 67 + #define MB86A16_BERMON 0x10 68 + #define MB86A16_BERTAB 0x11 69 + #define MB86A16_BERLSB 0x12 70 + #define MB86A16_BERMID 0x13 71 + #define MB86A16_BERMSB 0x14 72 + #define MB86A16_AGCM 0x15 73 + 74 + #define MB86A16_DCC1 0x16 75 + #define MB86A16_DCC1_DISTA (0x01 << 7) 76 + #define MB86A16_DCC1_PRTY (0x01 << 6) 77 + #define MB86A16_DCC1_CTOE (0x01 << 5) 78 + #define MB86A16_DCC1_TBEN (0x01 << 4) 79 + #define MB86A16_DCC1_TBO (0x01 << 3) 80 + #define MB86A16_DCC1_NUM (0x07 << 0) 81 + 82 + #define MB86A16_DCC2 0x17 83 + #define MB86A16_DCC2_DCBST (0x01 << 0) 84 + 85 + #define MB86A16_DCC3 0x18 86 + #define MB86A16_DCC3_CODE0 (0xff << 0) 87 + 88 + #define MB86A16_DCC4 0x19 89 + #define MB86A16_DCC4_CODE1 (0xff << 0) 90 + 91 + #define MB86A16_DCC5 0x1a 92 + #define MB86A16_DCC5_CODE2 (0xff << 0) 93 + 94 + #define MB86A16_DCC6 0x1b 95 + #define MB86A16_DCC6_CODE3 (0xff << 0) 96 + 97 + #define MB86A16_DCC7 0x1c 98 + #define MB86A16_DCC7_CODE4 (0xff << 0) 99 + 100 + #define MB86A16_DCC8 0x1d 101 + #define MB86A16_DCC8_CODE5 (0xff << 0) 102 + 103 + #define MB86A16_DCCOUT 0x1e 104 + #define MB86A16_DCCOUT_DISEN (0x01 << 0) 105 + 106 + #define MB86A16_TONEOUT1 0x1f 107 + #define MB86A16_TONE_TDIVL (0xff << 0) 108 + 109 + #define MB86A16_TONEOUT2 0x20 110 + #define MB86A16_TONE_TMD (0x03 << 2) 111 + #define MB86A16_TONE_TDIVH (0x03 << 0) 112 + 113 + #define MB86A16_FREQ1 0x21 114 + #define MB86A16_FREQ2 0x22 115 + #define MB86A16_FREQ3 0x23 116 + #define MB86A16_FREQ4 0x24 117 + #define MB86A16_FREQSET 0x25 118 + #define MB86A16_CNM 0x26 119 + #define MB86A16_PORT0 0x27 120 + #define MB86A16_PORT1 0x28 121 + #define MB86A16_DRCFILT 0x29 122 + #define MB86A16_AFC 0x2a 123 + #define MB86A16_AFCEXL 0x2b 124 + #define MB86A16_AFCEXH 0x2c 125 + #define MB86A16_DAGC 0x2d 126 + #define MB86A16_SEQMODE 0x32 127 + #define MB86A16_S0S1T 0x33 128 + #define MB86A16_S2S3T 0x34 129 + #define MB86A16_S4S5T 0x35 130 + #define MB86A16_CNTMR 0x36 131 + #define MB86A16_SIG1 0x37 132 + #define MB86A16_SIG2 0x38 133 + #define MB86A16_VIMAG 0x39 134 + #define MB86A16_VISET1 0x3a 135 + #define MB86A16_VISET2 0x3b 136 + #define MB86A16_VISET3 0x3c 137 + #define MB86A16_FAGCS1 0x3d 138 + #define MB86A16_FAGCS2 0x3e 139 + #define MB86A16_FAGCS3 0x3f 140 + #define MB86A16_FAGCS4 0x40 141 + #define MB86A16_FAGCS5 0x41 142 + #define MB86A16_FAGCS6 0x42 143 + #define MB86A16_CRM 0x43 144 + #define MB86A16_STRM 0x44 145 + #define MB86A16_DAGCML 0x45 146 + #define MB86A16_DAGCMH 0x46 147 + #define MB86A16_QPSKTST 0x49 148 + #define MB86A16_DISTMON 0x52 149 + #define MB86A16_VERSION 0x7f 150 + 151 + #endif /* __MB86A16_PRIV_H */
+4
drivers/media/dvb/frontends/tda10021.c
··· 426 426 id = tda10021_readreg(state, 0x1a); 427 427 if ((id & 0xf0) != 0x70) goto error; 428 428 429 + /* Don't claim TDA10023 */ 430 + if (id == 0x7d) 431 + goto error; 432 + 429 433 printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n", 430 434 state->config->demod_address, id); 431 435
+257
drivers/media/dvb/frontends/tda665x.c
··· 1 + /* 2 + TDA665x tuner driver 3 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 4 + 5 + This program is free software; you can redistribute it and/or modify 6 + it under the terms of the GNU General Public License as published by 7 + the Free Software Foundation; either version 2 of the License, or 8 + (at your option) any later version. 9 + 10 + This program is distributed in the hope that it will be useful, 11 + but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + GNU General Public License for more details. 14 + 15 + You should have received a copy of the GNU General Public License 16 + along with this program; if not, write to the Free Software 17 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #include <linux/init.h> 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 + 24 + #include "dvb_frontend.h" 25 + #include "tda665x.h" 26 + 27 + struct tda665x_state { 28 + struct dvb_frontend *fe; 29 + struct i2c_adapter *i2c; 30 + const struct tda665x_config *config; 31 + 32 + u32 frequency; 33 + u32 bandwidth; 34 + }; 35 + 36 + static int tda665x_read(struct tda665x_state *state, u8 *buf) 37 + { 38 + const struct tda665x_config *config = state->config; 39 + int err = 0; 40 + struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 }; 41 + 42 + err = i2c_transfer(state->i2c, &msg, 1); 43 + if (err != 1) 44 + goto exit; 45 + 46 + return err; 47 + exit: 48 + printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err); 49 + return err; 50 + } 51 + 52 + static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length) 53 + { 54 + const struct tda665x_config *config = state->config; 55 + int err = 0; 56 + struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length }; 57 + 58 + err = i2c_transfer(state->i2c, &msg, 1); 59 + if (err != 1) 60 + goto exit; 61 + 62 + return err; 63 + exit: 64 + printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err); 65 + return err; 66 + } 67 + 68 + static int tda665x_get_state(struct dvb_frontend *fe, 69 + enum tuner_param param, 70 + struct tuner_state *tstate) 71 + { 72 + struct tda665x_state *state = fe->tuner_priv; 73 + int err = 0; 74 + 75 + switch (param) { 76 + case DVBFE_TUNER_FREQUENCY: 77 + tstate->frequency = state->frequency; 78 + break; 79 + case DVBFE_TUNER_BANDWIDTH: 80 + break; 81 + default: 82 + printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param); 83 + err = -EINVAL; 84 + break; 85 + } 86 + 87 + return err; 88 + } 89 + 90 + static int tda665x_get_status(struct dvb_frontend *fe, u32 *status) 91 + { 92 + struct tda665x_state *state = fe->tuner_priv; 93 + u8 result = 0; 94 + int err = 0; 95 + 96 + *status = 0; 97 + 98 + err = tda665x_read(state, &result); 99 + if (err < 0) 100 + goto exit; 101 + 102 + if ((result >> 6) & 0x01) { 103 + printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__); 104 + *status = 1; 105 + } 106 + 107 + return err; 108 + exit: 109 + printk(KERN_ERR "%s: I/O Error\n", __func__); 110 + return err; 111 + } 112 + 113 + static int tda665x_set_state(struct dvb_frontend *fe, 114 + enum tuner_param param, 115 + struct tuner_state *tstate) 116 + { 117 + struct tda665x_state *state = fe->tuner_priv; 118 + const struct tda665x_config *config = state->config; 119 + u32 frequency, status = 0; 120 + u8 buf[4]; 121 + int err = 0; 122 + 123 + if (param & DVBFE_TUNER_FREQUENCY) { 124 + 125 + frequency = tstate->frequency; 126 + if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) { 127 + printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency); 128 + return -EINVAL; 129 + } 130 + 131 + frequency += config->frequency_offst; 132 + frequency *= config->ref_multiplier; 133 + frequency += config->ref_divider >> 1; 134 + frequency /= config->ref_divider; 135 + 136 + buf[0] = (u8) (frequency & 0x7f00) >> 8; 137 + buf[1] = (u8) (frequency & 0x00ff) >> 0; 138 + buf[2] = 0x80 | 0x40 | 0x02; 139 + buf[3] = 0x00; 140 + 141 + /* restore frequency */ 142 + frequency = tstate->frequency; 143 + 144 + if (frequency < 153000000) { 145 + /* VHF-L */ 146 + buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */ 147 + if (frequency < 68000000) 148 + buf[3] |= 0x40; /* 83uA */ 149 + if (frequency < 1040000000) 150 + buf[3] |= 0x60; /* 122uA */ 151 + if (frequency < 1250000000) 152 + buf[3] |= 0x80; /* 163uA */ 153 + else 154 + buf[3] |= 0xa0; /* 254uA */ 155 + } else if (frequency < 438000000) { 156 + /* VHF-H */ 157 + buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */ 158 + if (frequency < 230000000) 159 + buf[3] |= 0x40; 160 + if (frequency < 300000000) 161 + buf[3] |= 0x60; 162 + else 163 + buf[3] |= 0x80; 164 + } else { 165 + /* UHF */ 166 + buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */ 167 + if (frequency < 470000000) 168 + buf[3] |= 0x60; 169 + if (frequency < 526000000) 170 + buf[3] |= 0x80; 171 + else 172 + buf[3] |= 0xa0; 173 + } 174 + 175 + /* Set params */ 176 + err = tda665x_write(state, buf, 5); 177 + if (err < 0) 178 + goto exit; 179 + 180 + /* sleep for some time */ 181 + printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__); 182 + msleep(20); 183 + /* check status */ 184 + err = tda665x_get_status(fe, &status); 185 + if (err < 0) 186 + goto exit; 187 + 188 + if (status == 1) { 189 + printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status); 190 + state->frequency = frequency; /* cache successful state */ 191 + } else { 192 + printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status); 193 + } 194 + } else { 195 + printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param); 196 + return -EINVAL; 197 + } 198 + 199 + return 0; 200 + exit: 201 + printk(KERN_ERR "%s: I/O Error\n", __func__); 202 + return err; 203 + } 204 + 205 + static int tda665x_release(struct dvb_frontend *fe) 206 + { 207 + struct tda665x_state *state = fe->tuner_priv; 208 + 209 + fe->tuner_priv = NULL; 210 + kfree(state); 211 + return 0; 212 + } 213 + 214 + static struct dvb_tuner_ops tda665x_ops = { 215 + 216 + .set_state = tda665x_set_state, 217 + .get_state = tda665x_get_state, 218 + .get_status = tda665x_get_status, 219 + .release = tda665x_release 220 + }; 221 + 222 + struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, 223 + const struct tda665x_config *config, 224 + struct i2c_adapter *i2c) 225 + { 226 + struct tda665x_state *state = NULL; 227 + struct dvb_tuner_info *info; 228 + 229 + state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL); 230 + if (state == NULL) 231 + goto exit; 232 + 233 + state->config = config; 234 + state->i2c = i2c; 235 + state->fe = fe; 236 + fe->tuner_priv = state; 237 + fe->ops.tuner_ops = tda665x_ops; 238 + info = &fe->ops.tuner_ops.info; 239 + 240 + memcpy(info->name, config->name, sizeof(config->name)); 241 + info->frequency_min = config->frequency_min; 242 + info->frequency_max = config->frequency_max; 243 + info->frequency_step = config->frequency_offst; 244 + 245 + printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name); 246 + 247 + return fe; 248 + 249 + exit: 250 + kfree(state); 251 + return NULL; 252 + } 253 + EXPORT_SYMBOL(tda665x_attach); 254 + 255 + MODULE_DESCRIPTION("TDA665x driver"); 256 + MODULE_AUTHOR("Manu Abraham"); 257 + MODULE_LICENSE("GPL");
+52
drivers/media/dvb/frontends/tda665x.h
··· 1 + /* 2 + TDA665x tuner driver 3 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 4 + 5 + This program is free software; you can redistribute it and/or modify 6 + it under the terms of the GNU General Public License as published by 7 + the Free Software Foundation; either version 2 of the License, or 8 + (at your option) any later version. 9 + 10 + This program is distributed in the hope that it will be useful, 11 + but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + GNU General Public License for more details. 14 + 15 + You should have received a copy of the GNU General Public License 16 + along with this program; if not, write to the Free Software 17 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #ifndef __TDA665x_H 21 + #define __TDA665x_H 22 + 23 + struct tda665x_config { 24 + char name[128]; 25 + 26 + u8 addr; 27 + u32 frequency_min; 28 + u32 frequency_max; 29 + u32 frequency_offst; 30 + u32 ref_multiplier; 31 + u32 ref_divider; 32 + }; 33 + 34 + #if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE)) 35 + 36 + extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, 37 + const struct tda665x_config *config, 38 + struct i2c_adapter *i2c); 39 + 40 + #else 41 + 42 + static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, 43 + const struct tda665x_config *config, 44 + struct i2c_adapter *i2c) 45 + { 46 + printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); 47 + return NULL; 48 + } 49 + 50 + #endif /* CONFIG_DVB_TDA665x */ 51 + 52 + #endif /* __TDA665x_H */
+32
drivers/media/dvb/mantis/Kconfig
··· 1 + config MANTIS_CORE 2 + tristate "Mantis/Hopper PCI bridge based devices" 3 + depends on PCI && I2C && INPUT 4 + 5 + help 6 + Support for PCI cards based on the Mantis and Hopper PCi bridge. 7 + 8 + Say Y if you own such a device and want to use it. 9 + 10 + config DVB_MANTIS 11 + tristate "MANTIS based cards" 12 + depends on MANTIS_CORE && DVB_CORE && PCI && I2C 13 + select DVB_MB86A16 14 + select DVB_ZL10353 15 + select DVB_STV0299 16 + select DVB_PLL 17 + help 18 + Support for PCI cards based on the Mantis PCI bridge. 19 + Say Y when you have a Mantis based DVB card and want to use it. 20 + 21 + If unsure say N. 22 + 23 + config DVB_HOPPER 24 + tristate "HOPPER based cards" 25 + depends on MANTIS_CORE && DVB_CORE && PCI && I2C 26 + select DVB_ZL10353 27 + select DVB_PLL 28 + help 29 + Support for PCI cards based on the Hopper PCI bridge. 30 + Say Y when you have a Hopper based DVB card and want to use it. 31 + 32 + If unsure say N
+28
drivers/media/dvb/mantis/Makefile
··· 1 + mantis_core-objs := mantis_ioc.o \ 2 + mantis_uart.o \ 3 + mantis_dma.o \ 4 + mantis_pci.o \ 5 + mantis_i2c.o \ 6 + mantis_dvb.o \ 7 + mantis_evm.o \ 8 + mantis_hif.o \ 9 + mantis_ca.o \ 10 + mantis_pcmcia.o \ 11 + mantis_input.o 12 + 13 + mantis-objs := mantis_cards.o \ 14 + mantis_vp1033.o \ 15 + mantis_vp1034.o \ 16 + mantis_vp1041.o \ 17 + mantis_vp2033.o \ 18 + mantis_vp2040.o \ 19 + mantis_vp3030.o 20 + 21 + hopper-objs := hopper_cards.o \ 22 + hopper_vp3028.o 23 + 24 + obj-$(CONFIG_MANTIS_CORE) += mantis_core.o 25 + obj-$(CONFIG_DVB_MANTIS) += mantis.o 26 + obj-$(CONFIG_DVB_HOPPER) += hopper.o 27 + 28 + EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
+275
drivers/media/dvb/mantis/hopper_cards.c
··· 1 + /* 2 + Hopper PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/moduleparam.h> 23 + #include <linux/kernel.h> 24 + #include <linux/pci.h> 25 + #include <asm/irq.h> 26 + #include <linux/interrupt.h> 27 + 28 + #include "dmxdev.h" 29 + #include "dvbdev.h" 30 + #include "dvb_demux.h" 31 + #include "dvb_frontend.h" 32 + #include "dvb_net.h" 33 + 34 + #include "mantis_common.h" 35 + #include "hopper_vp3028.h" 36 + #include "mantis_dma.h" 37 + #include "mantis_dvb.h" 38 + #include "mantis_uart.h" 39 + #include "mantis_ioc.h" 40 + #include "mantis_pci.h" 41 + #include "mantis_i2c.h" 42 + #include "mantis_reg.h" 43 + 44 + static unsigned int verbose; 45 + module_param(verbose, int, 0644); 46 + MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 47 + 48 + #define DRIVER_NAME "Hopper" 49 + 50 + static char *label[10] = { 51 + "DMA", 52 + "IRQ-0", 53 + "IRQ-1", 54 + "OCERR", 55 + "PABRT", 56 + "RIPRR", 57 + "PPERR", 58 + "FTRGT", 59 + "RISCI", 60 + "RACK" 61 + }; 62 + 63 + static int devs; 64 + 65 + static irqreturn_t hopper_irq_handler(int irq, void *dev_id) 66 + { 67 + u32 stat = 0, mask = 0, lstat = 0, mstat = 0; 68 + u32 rst_stat = 0, rst_mask = 0; 69 + 70 + struct mantis_pci *mantis; 71 + struct mantis_ca *ca; 72 + 73 + mantis = (struct mantis_pci *) dev_id; 74 + if (unlikely(mantis == NULL)) { 75 + dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); 76 + return IRQ_NONE; 77 + } 78 + ca = mantis->mantis_ca; 79 + 80 + stat = mmread(MANTIS_INT_STAT); 81 + mask = mmread(MANTIS_INT_MASK); 82 + mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; 83 + if (!(stat & mask)) 84 + return IRQ_NONE; 85 + 86 + rst_mask = MANTIS_GPIF_WRACK | 87 + MANTIS_GPIF_OTHERR | 88 + MANTIS_SBUF_WSTO | 89 + MANTIS_GPIF_EXTIRQ; 90 + 91 + rst_stat = mmread(MANTIS_GPIF_STATUS); 92 + rst_stat &= rst_mask; 93 + mmwrite(rst_stat, MANTIS_GPIF_STATUS); 94 + 95 + mantis->mantis_int_stat = stat; 96 + mantis->mantis_int_mask = mask; 97 + dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); 98 + if (stat & MANTIS_INT_RISCEN) { 99 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); 100 + } 101 + if (stat & MANTIS_INT_IRQ0) { 102 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); 103 + mantis->gpif_status = rst_stat; 104 + wake_up(&ca->hif_write_wq); 105 + schedule_work(&ca->hif_evm_work); 106 + } 107 + if (stat & MANTIS_INT_IRQ1) { 108 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); 109 + schedule_work(&mantis->uart_work); 110 + } 111 + if (stat & MANTIS_INT_OCERR) { 112 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); 113 + } 114 + if (stat & MANTIS_INT_PABORT) { 115 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); 116 + } 117 + if (stat & MANTIS_INT_RIPERR) { 118 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); 119 + } 120 + if (stat & MANTIS_INT_PPERR) { 121 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); 122 + } 123 + if (stat & MANTIS_INT_FTRGT) { 124 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); 125 + } 126 + if (stat & MANTIS_INT_RISCI) { 127 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); 128 + mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; 129 + tasklet_schedule(&mantis->tasklet); 130 + } 131 + if (stat & MANTIS_INT_I2CDONE) { 132 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); 133 + wake_up(&mantis->i2c_wq); 134 + } 135 + mmwrite(stat, MANTIS_INT_STAT); 136 + stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | 137 + MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | 138 + MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | 139 + MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | 140 + MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | 141 + MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | 142 + MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | 143 + MANTIS_INT_PABORT | MANTIS_INT_RIPERR | 144 + MANTIS_INT_PPERR | MANTIS_INT_FTRGT | 145 + MANTIS_INT_RISCI); 146 + 147 + if (stat) 148 + dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); 149 + 150 + dprintk(MANTIS_DEBUG, 0, "\n"); 151 + return IRQ_HANDLED; 152 + } 153 + 154 + static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) 155 + { 156 + struct mantis_pci *mantis; 157 + struct mantis_hwconfig *config; 158 + int err = 0; 159 + 160 + mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); 161 + if (mantis == NULL) { 162 + printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); 163 + err = -ENOMEM; 164 + goto fail0; 165 + } 166 + 167 + mantis->num = devs; 168 + mantis->verbose = verbose; 169 + mantis->pdev = pdev; 170 + config = (struct mantis_hwconfig *) pci_id->driver_data; 171 + config->irq_handler = &hopper_irq_handler; 172 + mantis->hwconfig = config; 173 + 174 + err = mantis_pci_init(mantis); 175 + if (err) { 176 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); 177 + goto fail1; 178 + } 179 + 180 + err = mantis_stream_control(mantis, STREAM_TO_HIF); 181 + if (err < 0) { 182 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); 183 + goto fail1; 184 + } 185 + 186 + err = mantis_i2c_init(mantis); 187 + if (err < 0) { 188 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); 189 + goto fail2; 190 + } 191 + 192 + err = mantis_get_mac(mantis); 193 + if (err < 0) { 194 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); 195 + goto fail2; 196 + } 197 + 198 + err = mantis_dma_init(mantis); 199 + if (err < 0) { 200 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); 201 + goto fail3; 202 + } 203 + 204 + err = mantis_dvb_init(mantis); 205 + if (err < 0) { 206 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); 207 + goto fail4; 208 + } 209 + devs++; 210 + 211 + return err; 212 + 213 + fail4: 214 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); 215 + mantis_dma_exit(mantis); 216 + 217 + fail3: 218 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); 219 + mantis_i2c_exit(mantis); 220 + 221 + fail2: 222 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); 223 + mantis_pci_exit(mantis); 224 + 225 + fail1: 226 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); 227 + kfree(mantis); 228 + 229 + fail0: 230 + return err; 231 + } 232 + 233 + static void __devexit hopper_pci_remove(struct pci_dev *pdev) 234 + { 235 + struct mantis_pci *mantis = pci_get_drvdata(pdev); 236 + 237 + if (mantis) { 238 + mantis_dvb_exit(mantis); 239 + mantis_dma_exit(mantis); 240 + mantis_i2c_exit(mantis); 241 + mantis_pci_exit(mantis); 242 + kfree(mantis); 243 + } 244 + return; 245 + 246 + } 247 + 248 + static struct pci_device_id hopper_pci_table[] = { 249 + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config), 250 + { } 251 + }; 252 + 253 + static struct pci_driver hopper_pci_driver = { 254 + .name = DRIVER_NAME, 255 + .id_table = hopper_pci_table, 256 + .probe = hopper_pci_probe, 257 + .remove = hopper_pci_remove, 258 + }; 259 + 260 + static int __devinit hopper_init(void) 261 + { 262 + return pci_register_driver(&hopper_pci_driver); 263 + } 264 + 265 + static void __devexit hopper_exit(void) 266 + { 267 + return pci_unregister_driver(&hopper_pci_driver); 268 + } 269 + 270 + module_init(hopper_init); 271 + module_exit(hopper_exit); 272 + 273 + MODULE_DESCRIPTION("HOPPER driver"); 274 + MODULE_AUTHOR("Manu Abraham"); 275 + MODULE_LICENSE("GPL");
+88
drivers/media/dvb/mantis/hopper_vp3028.c
··· 1 + /* 2 + Hopper VP-3028 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "zl10353.h" 32 + #include "mantis_common.h" 33 + #include "mantis_ioc.h" 34 + #include "mantis_dvb.h" 35 + #include "hopper_vp3028.h" 36 + 37 + struct zl10353_config hopper_vp3028_config = { 38 + .demod_address = 0x0f, 39 + }; 40 + 41 + #define MANTIS_MODEL_NAME "VP-3028" 42 + #define MANTIS_DEV_TYPE "DVB-T" 43 + 44 + static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 45 + { 46 + struct i2c_adapter *adapter = &mantis->adapter; 47 + struct mantis_hwconfig *config = mantis->hwconfig; 48 + int err = 0; 49 + 50 + gpio_set_bits(mantis, config->reset, 0); 51 + msleep(100); 52 + err = mantis_frontend_power(mantis, POWER_ON); 53 + msleep(100); 54 + gpio_set_bits(mantis, config->reset, 1); 55 + 56 + err = mantis_frontend_power(mantis, POWER_ON); 57 + if (err == 0) { 58 + msleep(250); 59 + dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); 60 + fe = zl10353_attach(&hopper_vp3028_config, adapter); 61 + 62 + if (!fe) 63 + return -1; 64 + } else { 65 + dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", 66 + adapter->name, 67 + err); 68 + 69 + return -EIO; 70 + } 71 + dprintk(MANTIS_ERROR, 1, "Done!"); 72 + 73 + return 0; 74 + } 75 + 76 + struct mantis_hwconfig vp3028_config = { 77 + .model_name = MANTIS_MODEL_NAME, 78 + .dev_type = MANTIS_DEV_TYPE, 79 + .ts_size = MANTIS_TS_188, 80 + 81 + .baud_rate = MANTIS_BAUD_9600, 82 + .parity = MANTIS_PARITY_NONE, 83 + .bytes = 0, 84 + 85 + .frontend_init = vp3028_frontend_init, 86 + .power = GPIF_A00, 87 + .reset = GPIF_A03, 88 + };
+30
drivers/media/dvb/mantis/hopper_vp3028.h
··· 1 + /* 2 + Hopper VP-3028 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP3028_H 22 + #define __MANTIS_VP3028_H 23 + 24 + #include "mantis_common.h" 25 + 26 + #define MANTIS_VP_3028_DVB_T 0x0028 27 + 28 + extern struct mantis_hwconfig vp3028_config; 29 + 30 + #endif /* __MANTIS_VP3028_H */
+207
drivers/media/dvb/mantis/mantis_ca.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "mantis_common.h" 32 + #include "mantis_link.h" 33 + #include "mantis_hif.h" 34 + #include "mantis_reg.h" 35 + 36 + #include "mantis_ca.h" 37 + 38 + static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr) 39 + { 40 + struct mantis_ca *ca = en50221->data; 41 + struct mantis_pci *mantis = ca->ca_priv; 42 + 43 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot); 44 + 45 + if (slot != 0) 46 + return -EINVAL; 47 + 48 + return mantis_hif_read_mem(ca, addr); 49 + } 50 + 51 + static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data) 52 + { 53 + struct mantis_ca *ca = en50221->data; 54 + struct mantis_pci *mantis = ca->ca_priv; 55 + 56 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot); 57 + 58 + if (slot != 0) 59 + return -EINVAL; 60 + 61 + return mantis_hif_write_mem(ca, addr, data); 62 + } 63 + 64 + static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) 65 + { 66 + struct mantis_ca *ca = en50221->data; 67 + struct mantis_pci *mantis = ca->ca_priv; 68 + 69 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot); 70 + 71 + if (slot != 0) 72 + return -EINVAL; 73 + 74 + return mantis_hif_read_iom(ca, addr); 75 + } 76 + 77 + static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data) 78 + { 79 + struct mantis_ca *ca = en50221->data; 80 + struct mantis_pci *mantis = ca->ca_priv; 81 + 82 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot); 83 + 84 + if (slot != 0) 85 + return -EINVAL; 86 + 87 + return mantis_hif_write_iom(ca, addr, data); 88 + } 89 + 90 + static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot) 91 + { 92 + struct mantis_ca *ca = en50221->data; 93 + struct mantis_pci *mantis = ca->ca_priv; 94 + 95 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot); 96 + udelay(500); /* Wait.. */ 97 + mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */ 98 + udelay(500); 99 + mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */ 100 + msleep(1000); 101 + dvb_ca_en50221_camready_irq(&ca->en50221, 0); 102 + 103 + return 0; 104 + } 105 + 106 + static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) 107 + { 108 + struct mantis_ca *ca = en50221->data; 109 + struct mantis_pci *mantis = ca->ca_priv; 110 + 111 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot); 112 + 113 + return 0; 114 + } 115 + 116 + static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot) 117 + { 118 + struct mantis_ca *ca = en50221->data; 119 + struct mantis_pci *mantis = ca->ca_priv; 120 + 121 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot); 122 + /* mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */ 123 + 124 + return 0; 125 + } 126 + 127 + static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open) 128 + { 129 + struct mantis_ca *ca = en50221->data; 130 + struct mantis_pci *mantis = ca->ca_priv; 131 + 132 + dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot); 133 + 134 + if (ca->slot_state == MODULE_INSERTED) { 135 + dprintk(MANTIS_DEBUG, 1, "CA Module present and ready"); 136 + return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; 137 + } else { 138 + dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready"); 139 + } 140 + 141 + return 0; 142 + } 143 + 144 + int mantis_ca_init(struct mantis_pci *mantis) 145 + { 146 + struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter; 147 + struct mantis_ca *ca; 148 + int ca_flags = 0, result; 149 + 150 + dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA"); 151 + ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL); 152 + if (!ca) { 153 + dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting .."); 154 + result = -ENOMEM; 155 + goto err; 156 + } 157 + 158 + ca->ca_priv = mantis; 159 + mantis->mantis_ca = ca; 160 + ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE; 161 + /* register CA interface */ 162 + ca->en50221.owner = THIS_MODULE; 163 + ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem; 164 + ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem; 165 + ca->en50221.read_cam_control = mantis_ca_read_cam_ctl; 166 + ca->en50221.write_cam_control = mantis_ca_write_cam_ctl; 167 + ca->en50221.slot_reset = mantis_ca_slot_reset; 168 + ca->en50221.slot_shutdown = mantis_ca_slot_shutdown; 169 + ca->en50221.slot_ts_enable = mantis_ts_control; 170 + ca->en50221.poll_slot_status = mantis_slot_status; 171 + ca->en50221.data = ca; 172 + 173 + mutex_init(&ca->ca_lock); 174 + 175 + init_waitqueue_head(&ca->hif_data_wq); 176 + init_waitqueue_head(&ca->hif_opdone_wq); 177 + init_waitqueue_head(&ca->hif_write_wq); 178 + 179 + dprintk(MANTIS_ERROR, 1, "Registering EN50221 device"); 180 + result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1); 181 + if (result != 0) { 182 + dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result); 183 + goto err; 184 + } 185 + dprintk(MANTIS_ERROR, 1, "Registered EN50221 device"); 186 + mantis_evmgr_init(ca); 187 + return 0; 188 + err: 189 + kfree(ca); 190 + return result; 191 + } 192 + EXPORT_SYMBOL_GPL(mantis_ca_init); 193 + 194 + void mantis_ca_exit(struct mantis_pci *mantis) 195 + { 196 + struct mantis_ca *ca = mantis->mantis_ca; 197 + 198 + dprintk(MANTIS_DEBUG, 1, "Mantis CA exit"); 199 + 200 + mantis_evmgr_exit(ca); 201 + dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device"); 202 + if (ca) 203 + dvb_ca_en50221_release(&ca->en50221); 204 + 205 + kfree(ca); 206 + } 207 + EXPORT_SYMBOL_GPL(mantis_ca_exit);
+27
drivers/media/dvb/mantis/mantis_ca.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_CA_H 22 + #define __MANTIS_CA_H 23 + 24 + extern int mantis_ca_init(struct mantis_pci *mantis); 25 + extern void mantis_ca_exit(struct mantis_pci *mantis); 26 + 27 + #endif /* __MANTIS_CA_H */
+305
drivers/media/dvb/mantis/mantis_cards.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/moduleparam.h> 23 + #include <linux/kernel.h> 24 + #include <linux/pci.h> 25 + #include <asm/irq.h> 26 + #include <linux/interrupt.h> 27 + 28 + #include "dmxdev.h" 29 + #include "dvbdev.h" 30 + #include "dvb_demux.h" 31 + #include "dvb_frontend.h" 32 + #include "dvb_net.h" 33 + 34 + #include "mantis_common.h" 35 + 36 + #include "mantis_vp1033.h" 37 + #include "mantis_vp1034.h" 38 + #include "mantis_vp1041.h" 39 + #include "mantis_vp2033.h" 40 + #include "mantis_vp2040.h" 41 + #include "mantis_vp3030.h" 42 + 43 + #include "mantis_dma.h" 44 + #include "mantis_ca.h" 45 + #include "mantis_dvb.h" 46 + #include "mantis_uart.h" 47 + #include "mantis_ioc.h" 48 + #include "mantis_pci.h" 49 + #include "mantis_i2c.h" 50 + #include "mantis_reg.h" 51 + 52 + static unsigned int verbose; 53 + module_param(verbose, int, 0644); 54 + MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 55 + 56 + static int devs; 57 + 58 + #define DRIVER_NAME "Mantis" 59 + 60 + static char *label[10] = { 61 + "DMA", 62 + "IRQ-0", 63 + "IRQ-1", 64 + "OCERR", 65 + "PABRT", 66 + "RIPRR", 67 + "PPERR", 68 + "FTRGT", 69 + "RISCI", 70 + "RACK" 71 + }; 72 + 73 + static irqreturn_t mantis_irq_handler(int irq, void *dev_id) 74 + { 75 + u32 stat = 0, mask = 0, lstat = 0, mstat = 0; 76 + u32 rst_stat = 0, rst_mask = 0; 77 + 78 + struct mantis_pci *mantis; 79 + struct mantis_ca *ca; 80 + 81 + mantis = (struct mantis_pci *) dev_id; 82 + if (unlikely(mantis == NULL)) { 83 + dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); 84 + return IRQ_NONE; 85 + } 86 + ca = mantis->mantis_ca; 87 + 88 + stat = mmread(MANTIS_INT_STAT); 89 + mask = mmread(MANTIS_INT_MASK); 90 + mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; 91 + if (!(stat & mask)) 92 + return IRQ_NONE; 93 + 94 + rst_mask = MANTIS_GPIF_WRACK | 95 + MANTIS_GPIF_OTHERR | 96 + MANTIS_SBUF_WSTO | 97 + MANTIS_GPIF_EXTIRQ; 98 + 99 + rst_stat = mmread(MANTIS_GPIF_STATUS); 100 + rst_stat &= rst_mask; 101 + mmwrite(rst_stat, MANTIS_GPIF_STATUS); 102 + 103 + mantis->mantis_int_stat = stat; 104 + mantis->mantis_int_mask = mask; 105 + dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); 106 + if (stat & MANTIS_INT_RISCEN) { 107 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); 108 + } 109 + if (stat & MANTIS_INT_IRQ0) { 110 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); 111 + mantis->gpif_status = rst_stat; 112 + wake_up(&ca->hif_write_wq); 113 + schedule_work(&ca->hif_evm_work); 114 + } 115 + if (stat & MANTIS_INT_IRQ1) { 116 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); 117 + schedule_work(&mantis->uart_work); 118 + } 119 + if (stat & MANTIS_INT_OCERR) { 120 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); 121 + } 122 + if (stat & MANTIS_INT_PABORT) { 123 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); 124 + } 125 + if (stat & MANTIS_INT_RIPERR) { 126 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); 127 + } 128 + if (stat & MANTIS_INT_PPERR) { 129 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); 130 + } 131 + if (stat & MANTIS_INT_FTRGT) { 132 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); 133 + } 134 + if (stat & MANTIS_INT_RISCI) { 135 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); 136 + mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; 137 + tasklet_schedule(&mantis->tasklet); 138 + } 139 + if (stat & MANTIS_INT_I2CDONE) { 140 + dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); 141 + wake_up(&mantis->i2c_wq); 142 + } 143 + mmwrite(stat, MANTIS_INT_STAT); 144 + stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | 145 + MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | 146 + MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | 147 + MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | 148 + MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | 149 + MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | 150 + MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | 151 + MANTIS_INT_PABORT | MANTIS_INT_RIPERR | 152 + MANTIS_INT_PPERR | MANTIS_INT_FTRGT | 153 + MANTIS_INT_RISCI); 154 + 155 + if (stat) 156 + dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); 157 + 158 + dprintk(MANTIS_DEBUG, 0, "\n"); 159 + return IRQ_HANDLED; 160 + } 161 + 162 + static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) 163 + { 164 + struct mantis_pci *mantis; 165 + struct mantis_hwconfig *config; 166 + int err = 0; 167 + 168 + mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); 169 + if (mantis == NULL) { 170 + printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); 171 + err = -ENOMEM; 172 + goto fail0; 173 + } 174 + 175 + mantis->num = devs; 176 + mantis->verbose = verbose; 177 + mantis->pdev = pdev; 178 + config = (struct mantis_hwconfig *) pci_id->driver_data; 179 + config->irq_handler = &mantis_irq_handler; 180 + mantis->hwconfig = config; 181 + 182 + err = mantis_pci_init(mantis); 183 + if (err) { 184 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); 185 + goto fail1; 186 + } 187 + 188 + err = mantis_stream_control(mantis, STREAM_TO_HIF); 189 + if (err < 0) { 190 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); 191 + goto fail1; 192 + } 193 + 194 + err = mantis_i2c_init(mantis); 195 + if (err < 0) { 196 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); 197 + goto fail2; 198 + } 199 + 200 + err = mantis_get_mac(mantis); 201 + if (err < 0) { 202 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); 203 + goto fail2; 204 + } 205 + 206 + err = mantis_dma_init(mantis); 207 + if (err < 0) { 208 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); 209 + goto fail3; 210 + } 211 + 212 + err = mantis_dvb_init(mantis); 213 + if (err < 0) { 214 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); 215 + goto fail4; 216 + } 217 + err = mantis_uart_init(mantis); 218 + if (err < 0) { 219 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); 220 + goto fail6; 221 + } 222 + 223 + devs++; 224 + 225 + return err; 226 + 227 + 228 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err); 229 + mantis_uart_exit(mantis); 230 + 231 + fail6: 232 + fail4: 233 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); 234 + mantis_dma_exit(mantis); 235 + 236 + fail3: 237 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); 238 + mantis_i2c_exit(mantis); 239 + 240 + fail2: 241 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); 242 + mantis_pci_exit(mantis); 243 + 244 + fail1: 245 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); 246 + kfree(mantis); 247 + 248 + fail0: 249 + return err; 250 + } 251 + 252 + static void __devexit mantis_pci_remove(struct pci_dev *pdev) 253 + { 254 + struct mantis_pci *mantis = pci_get_drvdata(pdev); 255 + 256 + if (mantis) { 257 + 258 + mantis_uart_exit(mantis); 259 + mantis_dvb_exit(mantis); 260 + mantis_dma_exit(mantis); 261 + mantis_i2c_exit(mantis); 262 + mantis_pci_exit(mantis); 263 + kfree(mantis); 264 + } 265 + return; 266 + } 267 + 268 + static struct pci_device_id mantis_pci_table[] = { 269 + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config), 270 + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config), 271 + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config), 272 + MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config), 273 + MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config), 274 + MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config), 275 + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config), 276 + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config), 277 + MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config), 278 + MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2033_config), 279 + MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config), 280 + { } 281 + }; 282 + 283 + static struct pci_driver mantis_pci_driver = { 284 + .name = DRIVER_NAME, 285 + .id_table = mantis_pci_table, 286 + .probe = mantis_pci_probe, 287 + .remove = mantis_pci_remove, 288 + }; 289 + 290 + static int __devinit mantis_init(void) 291 + { 292 + return pci_register_driver(&mantis_pci_driver); 293 + } 294 + 295 + static void __devexit mantis_exit(void) 296 + { 297 + return pci_unregister_driver(&mantis_pci_driver); 298 + } 299 + 300 + module_init(mantis_init); 301 + module_exit(mantis_exit); 302 + 303 + MODULE_DESCRIPTION("MANTIS driver"); 304 + MODULE_AUTHOR("Manu Abraham"); 305 + MODULE_LICENSE("GPL");
+179
drivers/media/dvb/mantis/mantis_common.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_COMMON_H 22 + #define __MANTIS_COMMON_H 23 + 24 + #include <linux/mutex.h> 25 + #include <linux/workqueue.h> 26 + 27 + #include "mantis_uart.h" 28 + 29 + #include "mantis_link.h" 30 + 31 + #define MANTIS_ERROR 0 32 + #define MANTIS_NOTICE 1 33 + #define MANTIS_INFO 2 34 + #define MANTIS_DEBUG 3 35 + #define MANTIS_TMG 9 36 + 37 + #define dprintk(y, z, format, arg...) do { \ 38 + if (z) { \ 39 + if ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y)) \ 40 + printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ 41 + else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y)) \ 42 + printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ 43 + else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y)) \ 44 + printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ 45 + else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y)) \ 46 + printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ 47 + else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y)) \ 48 + printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ 49 + } else { \ 50 + if (mantis->verbose > y) \ 51 + printk(format , ##arg); \ 52 + } \ 53 + } while(0) 54 + 55 + #define mwrite(dat, addr) writel((dat), addr) 56 + #define mread(addr) readl(addr) 57 + 58 + #define mmwrite(dat, addr) mwrite((dat), (mantis->mmio + (addr))) 59 + #define mmread(addr) mread(mantis->mmio + (addr)) 60 + 61 + #define MANTIS_TS_188 0 62 + #define MANTIS_TS_204 1 63 + 64 + #define TWINHAN_TECHNOLOGIES 0x1822 65 + #define MANTIS 0x4e35 66 + 67 + #define TECHNISAT 0x1ae4 68 + #define TERRATEC 0x153b 69 + 70 + #define MAKE_ENTRY(__subven, __subdev, __configptr) { \ 71 + .vendor = TWINHAN_TECHNOLOGIES, \ 72 + .device = MANTIS, \ 73 + .subvendor = (__subven), \ 74 + .subdevice = (__subdev), \ 75 + .driver_data = (unsigned long) (__configptr) \ 76 + } 77 + 78 + enum mantis_i2c_mode { 79 + MANTIS_PAGE_MODE = 0, 80 + MANTIS_BYTE_MODE, 81 + }; 82 + 83 + struct mantis_pci; 84 + 85 + struct mantis_hwconfig { 86 + char *model_name; 87 + char *dev_type; 88 + u32 ts_size; 89 + 90 + enum mantis_baud baud_rate; 91 + enum mantis_parity parity; 92 + u32 bytes; 93 + 94 + irqreturn_t (*irq_handler)(int irq, void *dev_id); 95 + int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe); 96 + 97 + u8 power; 98 + u8 reset; 99 + 100 + enum mantis_i2c_mode i2c_mode; 101 + }; 102 + 103 + struct mantis_pci { 104 + unsigned int verbose; 105 + 106 + /* PCI stuff */ 107 + u16 vendor_id; 108 + u16 device_id; 109 + u16 subsystem_vendor; 110 + u16 subsystem_device; 111 + 112 + u8 latency; 113 + 114 + struct pci_dev *pdev; 115 + 116 + unsigned long mantis_addr; 117 + void __iomem *mmio; 118 + 119 + u8 irq; 120 + u8 revision; 121 + 122 + unsigned int num; 123 + 124 + /* RISC Core */ 125 + u32 finished_block; 126 + u32 last_block; 127 + u32 line_bytes; 128 + u32 line_count; 129 + u32 risc_pos; 130 + u8 *buf_cpu; 131 + dma_addr_t buf_dma; 132 + u32 *risc_cpu; 133 + dma_addr_t risc_dma; 134 + 135 + struct tasklet_struct tasklet; 136 + 137 + struct i2c_adapter adapter; 138 + int i2c_rc; 139 + wait_queue_head_t i2c_wq; 140 + struct mutex i2c_lock; 141 + 142 + /* DVB stuff */ 143 + struct dvb_adapter dvb_adapter; 144 + struct dvb_frontend *fe; 145 + struct dvb_demux demux; 146 + struct dmxdev dmxdev; 147 + struct dmx_frontend fe_hw; 148 + struct dmx_frontend fe_mem; 149 + struct dvb_net dvbnet; 150 + 151 + u8 feeds; 152 + 153 + struct mantis_hwconfig *hwconfig; 154 + 155 + u32 mantis_int_stat; 156 + u32 mantis_int_mask; 157 + 158 + /* board specific */ 159 + u8 mac_address[8]; 160 + u32 sub_vendor_id; 161 + u32 sub_device_id; 162 + 163 + /* A12 A13 A14 */ 164 + u32 gpio_status; 165 + 166 + u32 gpif_status; 167 + 168 + struct mantis_ca *mantis_ca; 169 + 170 + wait_queue_head_t uart_wq; 171 + struct work_struct uart_work; 172 + spinlock_t uart_lock; 173 + 174 + struct input_dev *rc; 175 + }; 176 + 177 + #define MANTIS_HIF_STATUS (mantis->gpio_status) 178 + 179 + #endif /* __MANTIS_COMMON_H */
+238
drivers/media/dvb/mantis/mantis_core.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include "mantis_common.h" 22 + #include "mantis_core.h" 23 + #include "mantis_vp1033.h" 24 + #include "mantis_vp1034.h" 25 + #include "mantis_vp1041.h" 26 + #include "mantis_vp2033.h" 27 + #include "mantis_vp2040.h" 28 + #include "mantis_vp3030.h" 29 + 30 + static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) 31 + { 32 + int err; 33 + struct i2c_msg msg[] = { 34 + { 35 + .addr = 0x50, 36 + .flags = 0, 37 + .buf = data, 38 + .len = 1 39 + }, { 40 + .addr = 0x50, 41 + .flags = I2C_M_RD, 42 + .buf = data, 43 + .len = length 44 + }, 45 + }; 46 + 47 + err = i2c_transfer(&mantis->adapter, msg, 2); 48 + if (err < 0) { 49 + dprintk(verbose, MANTIS_ERROR, 1, 50 + "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", 51 + err, data[0], data[1]); 52 + 53 + return err; 54 + } 55 + 56 + return 0; 57 + } 58 + 59 + static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) 60 + { 61 + int err; 62 + 63 + struct i2c_msg msg = { 64 + .addr = 0x50, 65 + .flags = 0, 66 + .buf = data, 67 + .len = length 68 + }; 69 + 70 + err = i2c_transfer(&mantis->adapter, &msg, 1); 71 + if (err < 0) { 72 + dprintk(verbose, MANTIS_ERROR, 1, 73 + "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >", 74 + err, length, data[0], data[1]); 75 + 76 + return err; 77 + } 78 + 79 + return 0; 80 + } 81 + 82 + static int get_mac_address(struct mantis_pci *mantis) 83 + { 84 + int err; 85 + 86 + mantis->mac_address[0] = 0x08; 87 + err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6); 88 + if (err < 0) { 89 + dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error"); 90 + 91 + return err; 92 + } 93 + dprintk(verbose, MANTIS_ERROR, 0, 94 + " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", 95 + mantis->mac_address[0], mantis->mac_address[1], 96 + mantis->mac_address[2], mantis->mac_address[3], 97 + mantis->mac_address[4], mantis->mac_address[5]); 98 + 99 + return 0; 100 + } 101 + 102 + #define MANTIS_MODEL_UNKNOWN "UNKNOWN" 103 + #define MANTIS_DEV_UNKNOWN "UNKNOWN" 104 + 105 + struct mantis_hwconfig unknown_device = { 106 + .model_name = MANTIS_MODEL_UNKNOWN, 107 + .dev_type = MANTIS_DEV_UNKNOWN, 108 + }; 109 + 110 + static void mantis_load_config(struct mantis_pci *mantis) 111 + { 112 + switch (mantis->subsystem_device) { 113 + case MANTIS_VP_1033_DVB_S: /* VP-1033 */ 114 + mantis->hwconfig = &vp1033_mantis_config; 115 + break; 116 + case MANTIS_VP_1034_DVB_S: /* VP-1034 */ 117 + mantis->hwconfig = &vp1034_mantis_config; 118 + break; 119 + case MANTIS_VP_1041_DVB_S2: /* VP-1041 */ 120 + case TECHNISAT_SKYSTAR_HD2: 121 + mantis->hwconfig = &vp1041_mantis_config; 122 + break; 123 + case MANTIS_VP_2033_DVB_C: /* VP-2033 */ 124 + mantis->hwconfig = &vp2033_mantis_config; 125 + break; 126 + case MANTIS_VP_2040_DVB_C: /* VP-2040 */ 127 + case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */ 128 + case TECHNISAT_CABLESTAR_HD2: 129 + mantis->hwconfig = &vp2040_mantis_config; 130 + break; 131 + case MANTIS_VP_3030_DVB_T: /* VP-3030 */ 132 + mantis->hwconfig = &vp3030_mantis_config; 133 + break; 134 + default: 135 + mantis->hwconfig = &unknown_device; 136 + break; 137 + } 138 + } 139 + 140 + int mantis_core_init(struct mantis_pci *mantis) 141 + { 142 + int err = 0; 143 + 144 + mantis_load_config(mantis); 145 + dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", 146 + mantis->hwconfig->model_name, mantis->hwconfig->dev_type, 147 + mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn)); 148 + dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", 149 + mantis->revision, 150 + mantis->subsystem_vendor, mantis->subsystem_device); 151 + dprintk(verbose, MANTIS_ERROR, 0, 152 + "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", 153 + mantis->pdev->irq, mantis->latency, 154 + mantis->mantis_addr, mantis->mantis_mmio); 155 + 156 + err = mantis_i2c_init(mantis); 157 + if (err < 0) { 158 + dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed"); 159 + return err; 160 + } 161 + err = get_mac_address(mantis); 162 + if (err < 0) { 163 + dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed"); 164 + return err; 165 + } 166 + err = mantis_dma_init(mantis); 167 + if (err < 0) { 168 + dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed"); 169 + return err; 170 + } 171 + err = mantis_dvb_init(mantis); 172 + if (err < 0) { 173 + dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed"); 174 + return err; 175 + } 176 + err = mantis_uart_init(mantis); 177 + if (err < 0) { 178 + dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed"); 179 + return err; 180 + } 181 + 182 + return 0; 183 + } 184 + 185 + int mantis_core_exit(struct mantis_pci *mantis) 186 + { 187 + mantis_dma_stop(mantis); 188 + dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping"); 189 + 190 + mantis_uart_exit(mantis); 191 + dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed"); 192 + 193 + if (mantis_dma_exit(mantis) < 0) 194 + dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); 195 + if (mantis_dvb_exit(mantis) < 0) 196 + dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed"); 197 + if (mantis_i2c_exit(mantis) < 0) 198 + dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed"); 199 + 200 + return 0; 201 + } 202 + 203 + /* Turn the given bit on or off. */ 204 + void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) 205 + { 206 + u32 cur; 207 + 208 + cur = mmread(MANTIS_GPIF_ADDR); 209 + if (value) 210 + mantis->gpio_status = cur | (1 << bitpos); 211 + else 212 + mantis->gpio_status = cur & (~(1 << bitpos)); 213 + 214 + mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); 215 + mmwrite(0x00, MANTIS_GPIF_DOUT); 216 + udelay(100); 217 + } 218 + 219 + /* direction = 0 , no CI passthrough ; 1 , CI passthrough */ 220 + void mantis_set_direction(struct mantis_pci *mantis, int direction) 221 + { 222 + u32 reg; 223 + 224 + reg = mmread(0x28); 225 + dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup"); 226 + if (direction == 0x01) { 227 + /* to CI */ 228 + reg |= 0x04; 229 + mmwrite(reg, 0x28); 230 + reg &= 0xff - 0x04; 231 + mmwrite(reg, 0x28); 232 + } else { 233 + reg &= 0xff - 0x04; 234 + mmwrite(reg, 0x28); 235 + reg |= 0x04; 236 + mmwrite(reg, 0x28); 237 + } 238 + }
+57
drivers/media/dvb/mantis/mantis_core.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_CORE_H 22 + #define __MANTIS_CORE_H 23 + 24 + #include "mantis_common.h" 25 + 26 + 27 + #define FE_TYPE_SAT 0 28 + #define FE_TYPE_CAB 1 29 + #define FE_TYPE_TER 2 30 + 31 + #define FE_TYPE_TS204 0 32 + #define FE_TYPE_TS188 1 33 + 34 + 35 + struct vendorname { 36 + u8 *sub_vendor_name; 37 + u32 sub_vendor_id; 38 + }; 39 + 40 + struct devicetype { 41 + u8 *sub_device_name; 42 + u32 sub_device_id; 43 + u8 device_type; 44 + u32 type_flags; 45 + }; 46 + 47 + 48 + extern int mantis_dma_init(struct mantis_pci *mantis); 49 + extern int mantis_dma_exit(struct mantis_pci *mantis); 50 + extern void mantis_dma_start(struct mantis_pci *mantis); 51 + extern void mantis_dma_stop(struct mantis_pci *mantis); 52 + extern int mantis_i2c_init(struct mantis_pci *mantis); 53 + extern int mantis_i2c_exit(struct mantis_pci *mantis); 54 + extern int mantis_core_init(struct mantis_pci *mantis); 55 + extern int mantis_core_exit(struct mantis_pci *mantis); 56 + 57 + #endif /* __MANTIS_CORE_H */
+256
drivers/media/dvb/mantis/mantis_dma.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <asm/page.h> 23 + #include <linux/vmalloc.h> 24 + #include <linux/pci.h> 25 + 26 + #include <asm/irq.h> 27 + #include <linux/signal.h> 28 + #include <linux/sched.h> 29 + #include <linux/interrupt.h> 30 + 31 + #include "dmxdev.h" 32 + #include "dvbdev.h" 33 + #include "dvb_demux.h" 34 + #include "dvb_frontend.h" 35 + #include "dvb_net.h" 36 + 37 + #include "mantis_common.h" 38 + #include "mantis_reg.h" 39 + #include "mantis_dma.h" 40 + 41 + #define RISC_WRITE (0x01 << 28) 42 + #define RISC_JUMP (0x07 << 28) 43 + #define RISC_IRQ (0x01 << 24) 44 + 45 + #define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) 46 + #define RISC_FLUSH() (mantis->risc_pos = 0) 47 + #define RISC_INSTR(opcode) (mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode)) 48 + 49 + #define MANTIS_BUF_SIZE (64 * 1024) 50 + #define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE >> 4) 51 + #define MANTIS_BLOCK_COUNT (1 << 4) 52 + #define MANTIS_RISC_SIZE PAGE_SIZE 53 + 54 + int mantis_dma_exit(struct mantis_pci *mantis) 55 + { 56 + if (mantis->buf_cpu) { 57 + dprintk(MANTIS_ERROR, 1, 58 + "DMA=0x%lx cpu=0x%p size=%d", 59 + (unsigned long) mantis->buf_dma, 60 + mantis->buf_cpu, 61 + MANTIS_BUF_SIZE); 62 + 63 + pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE, 64 + mantis->buf_cpu, mantis->buf_dma); 65 + 66 + mantis->buf_cpu = NULL; 67 + } 68 + if (mantis->risc_cpu) { 69 + dprintk(MANTIS_ERROR, 1, 70 + "RISC=0x%lx cpu=0x%p size=%lx", 71 + (unsigned long) mantis->risc_dma, 72 + mantis->risc_cpu, 73 + MANTIS_RISC_SIZE); 74 + 75 + pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE, 76 + mantis->risc_cpu, mantis->risc_dma); 77 + 78 + mantis->risc_cpu = NULL; 79 + } 80 + 81 + return 0; 82 + } 83 + EXPORT_SYMBOL_GPL(mantis_dma_exit); 84 + 85 + static inline int mantis_alloc_buffers(struct mantis_pci *mantis) 86 + { 87 + if (!mantis->buf_cpu) { 88 + mantis->buf_cpu = pci_alloc_consistent(mantis->pdev, 89 + MANTIS_BUF_SIZE, 90 + &mantis->buf_dma); 91 + if (!mantis->buf_cpu) { 92 + dprintk(MANTIS_ERROR, 1, 93 + "DMA buffer allocation failed"); 94 + 95 + goto err; 96 + } 97 + dprintk(MANTIS_ERROR, 1, 98 + "DMA=0x%lx cpu=0x%p size=%d", 99 + (unsigned long) mantis->buf_dma, 100 + mantis->buf_cpu, MANTIS_BUF_SIZE); 101 + } 102 + if (!mantis->risc_cpu) { 103 + mantis->risc_cpu = pci_alloc_consistent(mantis->pdev, 104 + MANTIS_RISC_SIZE, 105 + &mantis->risc_dma); 106 + 107 + if (!mantis->risc_cpu) { 108 + dprintk(MANTIS_ERROR, 1, 109 + "RISC program allocation failed"); 110 + 111 + mantis_dma_exit(mantis); 112 + 113 + goto err; 114 + } 115 + dprintk(MANTIS_ERROR, 1, 116 + "RISC=0x%lx cpu=0x%p size=%lx", 117 + (unsigned long) mantis->risc_dma, 118 + mantis->risc_cpu, MANTIS_RISC_SIZE); 119 + } 120 + 121 + return 0; 122 + err: 123 + dprintk(MANTIS_ERROR, 1, "Out of memory (?) ....."); 124 + return -ENOMEM; 125 + } 126 + 127 + static inline int mantis_calc_lines(struct mantis_pci *mantis) 128 + { 129 + mantis->line_bytes = MANTIS_BLOCK_BYTES; 130 + mantis->line_count = MANTIS_BLOCK_COUNT; 131 + 132 + while (mantis->line_bytes > 4095) { 133 + mantis->line_bytes >>= 1; 134 + mantis->line_count <<= 1; 135 + } 136 + 137 + dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]", 138 + MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count); 139 + 140 + if (mantis->line_count > 255) { 141 + dprintk(MANTIS_ERROR, 1, "Buffer size error"); 142 + return -EINVAL; 143 + } 144 + 145 + return 0; 146 + } 147 + 148 + int mantis_dma_init(struct mantis_pci *mantis) 149 + { 150 + int err = 0; 151 + 152 + dprintk(MANTIS_DEBUG, 1, "Mantis DMA init"); 153 + if (mantis_alloc_buffers(mantis) < 0) { 154 + dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer"); 155 + 156 + /* Stop RISC Engine */ 157 + mmwrite(0, MANTIS_DMA_CTL); 158 + 159 + goto err; 160 + } 161 + err = mantis_calc_lines(mantis); 162 + if (err < 0) { 163 + dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed"); 164 + 165 + goto err; 166 + } 167 + 168 + return 0; 169 + err: 170 + return err; 171 + } 172 + EXPORT_SYMBOL_GPL(mantis_dma_init); 173 + 174 + static inline void mantis_risc_program(struct mantis_pci *mantis) 175 + { 176 + u32 buf_pos = 0; 177 + u32 line; 178 + 179 + dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); 180 + RISC_FLUSH(); 181 + 182 + dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u", 183 + mantis->line_count, mantis->line_bytes); 184 + 185 + for (line = 0; line < mantis->line_count; line++) { 186 + dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line); 187 + if (!(buf_pos % MANTIS_BLOCK_BYTES)) { 188 + RISC_INSTR(RISC_WRITE | 189 + RISC_IRQ | 190 + RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) + 191 + (MANTIS_BLOCK_COUNT - 1)) % 192 + MANTIS_BLOCK_COUNT) | 193 + mantis->line_bytes); 194 + } else { 195 + RISC_INSTR(RISC_WRITE | mantis->line_bytes); 196 + } 197 + RISC_INSTR(mantis->buf_dma + buf_pos); 198 + buf_pos += mantis->line_bytes; 199 + } 200 + RISC_INSTR(RISC_JUMP); 201 + RISC_INSTR(mantis->risc_dma); 202 + } 203 + 204 + void mantis_dma_start(struct mantis_pci *mantis) 205 + { 206 + dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine"); 207 + 208 + mantis_risc_program(mantis); 209 + mmwrite(mantis->risc_dma, MANTIS_RISC_START); 210 + mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 211 + 212 + mmwrite(0, MANTIS_DMA_CTL); 213 + mantis->last_block = mantis->finished_block = 0; 214 + 215 + mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); 216 + 217 + mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN 218 + | MANTIS_RISC_EN, MANTIS_DMA_CTL); 219 + 220 + } 221 + 222 + void mantis_dma_stop(struct mantis_pci *mantis) 223 + { 224 + u32 stat = 0, mask = 0; 225 + 226 + stat = mmread(MANTIS_INT_STAT); 227 + mask = mmread(MANTIS_INT_MASK); 228 + dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine"); 229 + 230 + mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR); 231 + 232 + mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN | 233 + MANTIS_DCAP_EN | 234 + MANTIS_RISC_EN)), MANTIS_DMA_CTL); 235 + 236 + mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); 237 + 238 + mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | 239 + MANTIS_INT_RISCEN), MANTIS_INT_MASK); 240 + } 241 + 242 + 243 + void mantis_dma_xfer(unsigned long data) 244 + { 245 + struct mantis_pci *mantis = (struct mantis_pci *) data; 246 + struct mantis_hwconfig *config = mantis->hwconfig; 247 + 248 + while (mantis->last_block != mantis->finished_block) { 249 + dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", 250 + mantis->last_block, mantis->finished_block); 251 + 252 + (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) 253 + (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); 254 + mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT; 255 + } 256 + }
+30
drivers/media/dvb/mantis/mantis_dma.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_DMA_H 22 + #define __MANTIS_DMA_H 23 + 24 + extern int mantis_dma_init(struct mantis_pci *mantis); 25 + extern int mantis_dma_exit(struct mantis_pci *mantis); 26 + extern void mantis_dma_start(struct mantis_pci *mantis); 27 + extern void mantis_dma_stop(struct mantis_pci *mantis); 28 + extern void mantis_dma_xfer(unsigned long data); 29 + 30 + #endif /* __MANTIS_DMA_H */
+296
drivers/media/dvb/mantis/mantis_dvb.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 4 + 5 + This program is free software; you can redistribute it and/or modify 6 + it under the terms of the GNU General Public License as published by 7 + the Free Software Foundation; either version 2 of the License, or 8 + (at your option) any later version. 9 + 10 + This program is distributed in the hope that it will be useful, 11 + but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + GNU General Public License for more details. 14 + 15 + You should have received a copy of the GNU General Public License 16 + along with this program; if not, write to the Free Software 17 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #include <linux/kernel.h> 21 + #include <linux/bitops.h> 22 + 23 + #include <linux/signal.h> 24 + #include <linux/sched.h> 25 + #include <linux/interrupt.h> 26 + #include <linux/pci.h> 27 + #include <linux/i2c.h> 28 + 29 + #include "dmxdev.h" 30 + #include "dvbdev.h" 31 + #include "dvb_demux.h" 32 + #include "dvb_frontend.h" 33 + #include "dvb_net.h" 34 + 35 + #include "mantis_common.h" 36 + #include "mantis_dma.h" 37 + #include "mantis_ca.h" 38 + #include "mantis_ioc.h" 39 + #include "mantis_dvb.h" 40 + 41 + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 42 + 43 + int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power) 44 + { 45 + struct mantis_hwconfig *config = mantis->hwconfig; 46 + 47 + switch (power) { 48 + case POWER_ON: 49 + dprintk(MANTIS_DEBUG, 1, "Power ON"); 50 + gpio_set_bits(mantis, config->power, POWER_ON); 51 + msleep(100); 52 + gpio_set_bits(mantis, config->power, POWER_ON); 53 + msleep(100); 54 + break; 55 + 56 + case POWER_OFF: 57 + dprintk(MANTIS_DEBUG, 1, "Power OFF"); 58 + gpio_set_bits(mantis, config->power, POWER_OFF); 59 + msleep(100); 60 + break; 61 + 62 + default: 63 + dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power); 64 + return -1; 65 + } 66 + 67 + return 0; 68 + } 69 + EXPORT_SYMBOL_GPL(mantis_frontend_power); 70 + 71 + void mantis_frontend_soft_reset(struct mantis_pci *mantis) 72 + { 73 + struct mantis_hwconfig *config = mantis->hwconfig; 74 + 75 + dprintk(MANTIS_DEBUG, 1, "Frontend RESET"); 76 + gpio_set_bits(mantis, config->reset, 0); 77 + msleep(100); 78 + gpio_set_bits(mantis, config->reset, 0); 79 + msleep(100); 80 + gpio_set_bits(mantis, config->reset, 1); 81 + msleep(100); 82 + gpio_set_bits(mantis, config->reset, 1); 83 + msleep(100); 84 + 85 + return; 86 + } 87 + EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset); 88 + 89 + static int mantis_frontend_shutdown(struct mantis_pci *mantis) 90 + { 91 + int err; 92 + 93 + mantis_frontend_soft_reset(mantis); 94 + err = mantis_frontend_power(mantis, POWER_OFF); 95 + if (err != 0) { 96 + dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err); 97 + return 1; 98 + } 99 + 100 + return 0; 101 + } 102 + 103 + static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) 104 + { 105 + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 106 + struct mantis_pci *mantis = dvbdmx->priv; 107 + 108 + dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed"); 109 + if (!dvbdmx->dmx.frontend) { 110 + dprintk(MANTIS_DEBUG, 1, "no frontend ?"); 111 + return -EINVAL; 112 + } 113 + 114 + mantis->feeds++; 115 + dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds); 116 + 117 + if (mantis->feeds == 1) { 118 + dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); 119 + mantis_dma_start(mantis); 120 + } 121 + 122 + return mantis->feeds; 123 + } 124 + 125 + static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) 126 + { 127 + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 128 + struct mantis_pci *mantis = dvbdmx->priv; 129 + 130 + dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed"); 131 + if (!dvbdmx->dmx.frontend) { 132 + dprintk(MANTIS_DEBUG, 1, "no frontend ?"); 133 + return -EINVAL; 134 + } 135 + 136 + mantis->feeds--; 137 + if (mantis->feeds == 0) { 138 + dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); 139 + mantis_dma_stop(mantis); 140 + } 141 + 142 + return 0; 143 + } 144 + 145 + int __devinit mantis_dvb_init(struct mantis_pci *mantis) 146 + { 147 + struct mantis_hwconfig *config = mantis->hwconfig; 148 + int result = -1; 149 + 150 + dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter"); 151 + 152 + result = dvb_register_adapter(&mantis->dvb_adapter, 153 + "Mantis DVB adapter", 154 + THIS_MODULE, 155 + &mantis->pdev->dev, 156 + adapter_nr); 157 + 158 + if (result < 0) { 159 + 160 + dprintk(MANTIS_ERROR, 1, "Error registering adapter"); 161 + return -ENODEV; 162 + } 163 + 164 + mantis->dvb_adapter.priv = mantis; 165 + mantis->demux.dmx.capabilities = DMX_TS_FILTERING | 166 + DMX_SECTION_FILTERING | 167 + DMX_MEMORY_BASED_FILTERING; 168 + 169 + mantis->demux.priv = mantis; 170 + mantis->demux.filternum = 256; 171 + mantis->demux.feednum = 256; 172 + mantis->demux.start_feed = mantis_dvb_start_feed; 173 + mantis->demux.stop_feed = mantis_dvb_stop_feed; 174 + mantis->demux.write_to_decoder = NULL; 175 + 176 + dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init"); 177 + result = dvb_dmx_init(&mantis->demux); 178 + if (result < 0) { 179 + dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 180 + 181 + goto err0; 182 + } 183 + 184 + mantis->dmxdev.filternum = 256; 185 + mantis->dmxdev.demux = &mantis->demux.dmx; 186 + mantis->dmxdev.capabilities = 0; 187 + dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init"); 188 + 189 + result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter); 190 + if (result < 0) { 191 + 192 + dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); 193 + goto err1; 194 + } 195 + 196 + mantis->fe_hw.source = DMX_FRONTEND_0; 197 + result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw); 198 + if (result < 0) { 199 + 200 + dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 201 + goto err2; 202 + } 203 + 204 + mantis->fe_mem.source = DMX_MEMORY_FE; 205 + result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem); 206 + if (result < 0) { 207 + dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 208 + goto err3; 209 + } 210 + 211 + result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw); 212 + if (result < 0) { 213 + dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 214 + goto err4; 215 + } 216 + 217 + dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); 218 + tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); 219 + if (mantis->hwconfig) { 220 + result = config->frontend_init(mantis, mantis->fe); 221 + if (result < 0) { 222 + dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!"); 223 + goto err5; 224 + } else { 225 + if (mantis->fe == NULL) { 226 + dprintk(MANTIS_ERROR, 1, "FE <NULL>"); 227 + goto err5; 228 + } 229 + 230 + if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) { 231 + dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed"); 232 + 233 + if (mantis->fe->ops.release) 234 + mantis->fe->ops.release(mantis->fe); 235 + 236 + mantis->fe = NULL; 237 + goto err5; 238 + } 239 + } 240 + } 241 + 242 + return 0; 243 + 244 + /* Error conditions .. */ 245 + err5: 246 + tasklet_kill(&mantis->tasklet); 247 + dvb_net_release(&mantis->dvbnet); 248 + dvb_unregister_frontend(mantis->fe); 249 + dvb_frontend_detach(mantis->fe); 250 + err4: 251 + mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); 252 + 253 + err3: 254 + mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); 255 + 256 + err2: 257 + dvb_dmxdev_release(&mantis->dmxdev); 258 + 259 + err1: 260 + dvb_dmx_release(&mantis->demux); 261 + 262 + err0: 263 + dvb_unregister_adapter(&mantis->dvb_adapter); 264 + 265 + return result; 266 + } 267 + EXPORT_SYMBOL_GPL(mantis_dvb_init); 268 + 269 + int __devexit mantis_dvb_exit(struct mantis_pci *mantis) 270 + { 271 + int err; 272 + 273 + if (mantis->fe) { 274 + /* mantis_ca_exit(mantis); */ 275 + err = mantis_frontend_shutdown(mantis); 276 + if (err != 0) 277 + dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err); 278 + dvb_unregister_frontend(mantis->fe); 279 + dvb_frontend_detach(mantis->fe); 280 + } 281 + 282 + tasklet_kill(&mantis->tasklet); 283 + dvb_net_release(&mantis->dvbnet); 284 + 285 + mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); 286 + mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); 287 + 288 + dvb_dmxdev_release(&mantis->dmxdev); 289 + dvb_dmx_release(&mantis->demux); 290 + 291 + dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter"); 292 + dvb_unregister_adapter(&mantis->dvb_adapter); 293 + 294 + return 0; 295 + } 296 + EXPORT_SYMBOL_GPL(mantis_dvb_exit);
+35
drivers/media/dvb/mantis/mantis_dvb.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_DVB_H 22 + #define __MANTIS_DVB_H 23 + 24 + enum mantis_power { 25 + POWER_OFF = 0, 26 + POWER_ON = 1 27 + }; 28 + 29 + extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power); 30 + extern void mantis_frontend_soft_reset(struct mantis_pci *mantis); 31 + 32 + extern int mantis_dvb_init(struct mantis_pci *mantis); 33 + extern int mantis_dvb_exit(struct mantis_pci *mantis); 34 + 35 + #endif /* __MANTIS_DVB_H */
+117
drivers/media/dvb/mantis/mantis_evm.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + 23 + #include <linux/signal.h> 24 + #include <linux/sched.h> 25 + #include <linux/interrupt.h> 26 + 27 + #include "dmxdev.h" 28 + #include "dvbdev.h" 29 + #include "dvb_demux.h" 30 + #include "dvb_frontend.h" 31 + #include "dvb_net.h" 32 + 33 + #include "mantis_common.h" 34 + #include "mantis_link.h" 35 + #include "mantis_hif.h" 36 + #include "mantis_reg.h" 37 + 38 + static void mantis_hifevm_work(struct work_struct *work) 39 + { 40 + struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work); 41 + struct mantis_pci *mantis = ca->ca_priv; 42 + 43 + u32 gpif_stat, gpif_mask; 44 + 45 + gpif_stat = mmread(MANTIS_GPIF_STATUS); 46 + gpif_mask = mmread(MANTIS_GPIF_IRQCFG); 47 + 48 + if (gpif_stat & MANTIS_GPIF_DETSTAT) { 49 + if (gpif_stat & MANTIS_CARD_PLUGIN) { 50 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num); 51 + mmwrite(0xdada0000, MANTIS_CARD_RESET); 52 + mantis_event_cam_plugin(ca); 53 + dvb_ca_en50221_camchange_irq(&ca->en50221, 54 + 0, 55 + DVB_CA_EN50221_CAMCHANGE_INSERTED); 56 + } 57 + } else { 58 + if (gpif_stat & MANTIS_CARD_PLUGOUT) { 59 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num); 60 + mmwrite(0xdada0000, MANTIS_CARD_RESET); 61 + mantis_event_cam_unplug(ca); 62 + dvb_ca_en50221_camchange_irq(&ca->en50221, 63 + 0, 64 + DVB_CA_EN50221_CAMCHANGE_REMOVED); 65 + } 66 + } 67 + 68 + if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ) 69 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num); 70 + 71 + if (mantis->gpif_status & MANTIS_SBUF_WSTO) 72 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num); 73 + 74 + if (mantis->gpif_status & MANTIS_GPIF_OTHERR) 75 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num); 76 + 77 + if (gpif_stat & MANTIS_SBUF_OVFLW) 78 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num); 79 + 80 + if (gpif_stat & MANTIS_GPIF_BRRDY) 81 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num); 82 + 83 + if (gpif_stat & MANTIS_GPIF_INTSTAT) 84 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num); 85 + 86 + if (gpif_stat & MANTIS_SBUF_EMPTY) 87 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num); 88 + 89 + if (gpif_stat & MANTIS_SBUF_OPDONE) { 90 + dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num); 91 + ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL; 92 + ca->hif_event = MANTIS_SBUF_OPDONE; 93 + wake_up(&ca->hif_opdone_wq); 94 + } 95 + } 96 + 97 + int mantis_evmgr_init(struct mantis_ca *ca) 98 + { 99 + struct mantis_pci *mantis = ca->ca_priv; 100 + 101 + dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager"); 102 + INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work); 103 + mantis_pcmcia_init(ca); 104 + schedule_work(&ca->hif_evm_work); 105 + mantis_hif_init(ca); 106 + return 0; 107 + } 108 + 109 + void mantis_evmgr_exit(struct mantis_ca *ca) 110 + { 111 + struct mantis_pci *mantis = ca->ca_priv; 112 + 113 + dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); 114 + flush_scheduled_work(); 115 + mantis_hif_exit(ca); 116 + mantis_pcmcia_exit(ca); 117 + }
+240
drivers/media/dvb/mantis/mantis_hif.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/signal.h> 23 + #include <linux/sched.h> 24 + 25 + #include <linux/signal.h> 26 + #include <linux/sched.h> 27 + #include <linux/interrupt.h> 28 + 29 + #include "dmxdev.h" 30 + #include "dvbdev.h" 31 + #include "dvb_demux.h" 32 + #include "dvb_frontend.h" 33 + #include "dvb_net.h" 34 + 35 + #include "mantis_common.h" 36 + 37 + #include "mantis_hif.h" 38 + #include "mantis_link.h" /* temporary due to physical layer stuff */ 39 + 40 + #include "mantis_reg.h" 41 + 42 + 43 + static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca) 44 + { 45 + struct mantis_pci *mantis = ca->ca_priv; 46 + int rc = 0; 47 + 48 + if (wait_event_timeout(ca->hif_opdone_wq, 49 + ca->hif_event & MANTIS_SBUF_OPDONE, 50 + msecs_to_jiffies(500)) == -ERESTARTSYS) { 51 + 52 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num); 53 + rc = -EREMOTEIO; 54 + } 55 + dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete"); 56 + ca->hif_event &= ~MANTIS_SBUF_OPDONE; 57 + return rc; 58 + } 59 + 60 + static int mantis_hif_write_wait(struct mantis_ca *ca) 61 + { 62 + struct mantis_pci *mantis = ca->ca_priv; 63 + u32 opdone = 0, timeout = 0; 64 + int rc = 0; 65 + 66 + if (wait_event_timeout(ca->hif_write_wq, 67 + mantis->gpif_status & MANTIS_GPIF_WRACK, 68 + msecs_to_jiffies(500)) == -ERESTARTSYS) { 69 + 70 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num); 71 + rc = -EREMOTEIO; 72 + } 73 + dprintk(MANTIS_DEBUG, 1, "Write Acknowledged"); 74 + mantis->gpif_status &= ~MANTIS_GPIF_WRACK; 75 + while (!opdone) { 76 + opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE); 77 + udelay(500); 78 + timeout++; 79 + if (timeout > 100) { 80 + dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num); 81 + rc = -ETIMEDOUT; 82 + break; 83 + } 84 + } 85 + dprintk(MANTIS_DEBUG, 1, "HIF Write success"); 86 + return rc; 87 + } 88 + 89 + 90 + int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr) 91 + { 92 + struct mantis_pci *mantis = ca->ca_priv; 93 + u32 hif_addr = 0, data, count = 4; 94 + 95 + dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num); 96 + mutex_lock(&ca->ca_lock); 97 + hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 98 + hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; 99 + hif_addr |= MANTIS_HIF_STATUS; 100 + hif_addr |= addr; 101 + 102 + mmwrite(hif_addr, MANTIS_GPIF_BRADDR); 103 + mmwrite(count, MANTIS_GPIF_BRBYTES); 104 + udelay(20); 105 + mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 106 + 107 + if (mantis_hif_sbuf_opdone_wait(ca) != 0) { 108 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num); 109 + mutex_unlock(&ca->ca_lock); 110 + return -EREMOTEIO; 111 + } 112 + data = mmread(MANTIS_GPIF_DIN); 113 + mutex_unlock(&ca->ca_lock); 114 + dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data); 115 + return (data >> 24) & 0xff; 116 + } 117 + 118 + int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data) 119 + { 120 + struct mantis_slot *slot = ca->slot; 121 + struct mantis_pci *mantis = ca->ca_priv; 122 + u32 hif_addr = 0; 123 + 124 + dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num); 125 + mutex_lock(&ca->ca_lock); 126 + hif_addr &= ~MANTIS_GPIF_HIFRDWRN; 127 + hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 128 + hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; 129 + hif_addr |= MANTIS_HIF_STATUS; 130 + hif_addr |= addr; 131 + 132 + mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */ 133 + mmwrite(hif_addr, MANTIS_GPIF_ADDR); 134 + mmwrite(data, MANTIS_GPIF_DOUT); 135 + 136 + if (mantis_hif_write_wait(ca) != 0) { 137 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 138 + mutex_unlock(&ca->ca_lock); 139 + return -EREMOTEIO; 140 + } 141 + dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr); 142 + mutex_unlock(&ca->ca_lock); 143 + 144 + return 0; 145 + } 146 + 147 + int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr) 148 + { 149 + struct mantis_pci *mantis = ca->ca_priv; 150 + u32 data, hif_addr = 0; 151 + 152 + dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num); 153 + mutex_lock(&ca->ca_lock); 154 + hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 155 + hif_addr |= MANTIS_GPIF_PCMCIAIOM; 156 + hif_addr |= MANTIS_HIF_STATUS; 157 + hif_addr |= addr; 158 + 159 + mmwrite(hif_addr, MANTIS_GPIF_BRADDR); 160 + mmwrite(1, MANTIS_GPIF_BRBYTES); 161 + udelay(20); 162 + mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 163 + 164 + if (mantis_hif_sbuf_opdone_wait(ca) != 0) { 165 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 166 + mutex_unlock(&ca->ca_lock); 167 + return -EREMOTEIO; 168 + } 169 + data = mmread(MANTIS_GPIF_DIN); 170 + dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data); 171 + udelay(50); 172 + mutex_unlock(&ca->ca_lock); 173 + 174 + return (u8) data; 175 + } 176 + 177 + int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data) 178 + { 179 + struct mantis_pci *mantis = ca->ca_priv; 180 + u32 hif_addr = 0; 181 + 182 + dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num); 183 + mutex_lock(&ca->ca_lock); 184 + hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 185 + hif_addr &= ~MANTIS_GPIF_HIFRDWRN; 186 + hif_addr |= MANTIS_GPIF_PCMCIAIOM; 187 + hif_addr |= MANTIS_HIF_STATUS; 188 + hif_addr |= addr; 189 + 190 + mmwrite(hif_addr, MANTIS_GPIF_ADDR); 191 + mmwrite(data, MANTIS_GPIF_DOUT); 192 + 193 + if (mantis_hif_write_wait(ca) != 0) { 194 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 195 + mutex_unlock(&ca->ca_lock); 196 + return -EREMOTEIO; 197 + } 198 + dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr); 199 + mutex_unlock(&ca->ca_lock); 200 + udelay(50); 201 + 202 + return 0; 203 + } 204 + 205 + int mantis_hif_init(struct mantis_ca *ca) 206 + { 207 + struct mantis_slot *slot = ca->slot; 208 + struct mantis_pci *mantis = ca->ca_priv; 209 + u32 irqcfg; 210 + 211 + slot[0].slave_cfg = 0x70773028; 212 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num); 213 + 214 + mutex_lock(&ca->ca_lock); 215 + irqcfg = mmread(MANTIS_GPIF_IRQCFG); 216 + irqcfg = MANTIS_MASK_BRRDY | 217 + MANTIS_MASK_WRACK | 218 + MANTIS_MASK_EXTIRQ | 219 + MANTIS_MASK_WSTO | 220 + MANTIS_MASK_OTHERR | 221 + MANTIS_MASK_OVFLW; 222 + 223 + mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); 224 + mutex_unlock(&ca->ca_lock); 225 + 226 + return 0; 227 + } 228 + 229 + void mantis_hif_exit(struct mantis_ca *ca) 230 + { 231 + struct mantis_pci *mantis = ca->ca_priv; 232 + u32 irqcfg; 233 + 234 + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num); 235 + mutex_lock(&ca->ca_lock); 236 + irqcfg = mmread(MANTIS_GPIF_IRQCFG); 237 + irqcfg &= ~MANTIS_MASK_BRRDY; 238 + mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); 239 + mutex_unlock(&ca->ca_lock); 240 + }
+29
drivers/media/dvb/mantis/mantis_hif.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_HIF_H 22 + #define __MANTIS_HIF_H 23 + 24 + #define MANTIS_HIF_MEMRD 1 25 + #define MANTIS_HIF_MEMWR 2 26 + #define MANTIS_HIF_IOMRD 3 27 + #define MANTIS_HIF_IOMWR 4 28 + 29 + #endif /* __MANTIS_HIF_H */
+267
drivers/media/dvb/mantis/mantis_i2c.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <asm/io.h> 22 + #include <linux/ioport.h> 23 + #include <linux/pci.h> 24 + #include <linux/i2c.h> 25 + 26 + #include "dmxdev.h" 27 + #include "dvbdev.h" 28 + #include "dvb_demux.h" 29 + #include "dvb_frontend.h" 30 + #include "dvb_net.h" 31 + 32 + #include "mantis_common.h" 33 + #include "mantis_reg.h" 34 + #include "mantis_i2c.h" 35 + 36 + #define TRIALS 10000 37 + 38 + static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg) 39 + { 40 + u32 rxd, i, stat, trials; 41 + 42 + dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ", 43 + __func__, msg->addr); 44 + 45 + for (i = 0; i < msg->len; i++) { 46 + rxd = (msg->addr << 25) | (1 << 24) 47 + | MANTIS_I2C_RATE_3 48 + | MANTIS_I2C_STOP 49 + | MANTIS_I2C_PGMODE; 50 + 51 + if (i == (msg->len - 1)) 52 + rxd &= ~MANTIS_I2C_STOP; 53 + 54 + mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); 55 + mmwrite(rxd, MANTIS_I2CDATA_CTL); 56 + 57 + /* wait for xfer completion */ 58 + for (trials = 0; trials < TRIALS; trials++) { 59 + stat = mmread(MANTIS_INT_STAT); 60 + if (stat & MANTIS_INT_I2CDONE) 61 + break; 62 + } 63 + 64 + dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); 65 + 66 + /* wait for xfer completion */ 67 + for (trials = 0; trials < TRIALS; trials++) { 68 + stat = mmread(MANTIS_INT_STAT); 69 + if (stat & MANTIS_INT_I2CRACK) 70 + break; 71 + } 72 + 73 + dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); 74 + 75 + rxd = mmread(MANTIS_I2CDATA_CTL); 76 + msg->buf[i] = (u8)((rxd >> 8) & 0xFF); 77 + dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); 78 + } 79 + dprintk(MANTIS_INFO, 0, "]\n"); 80 + 81 + return 0; 82 + } 83 + 84 + static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg) 85 + { 86 + int i; 87 + u32 txd = 0, stat, trials; 88 + 89 + dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ", 90 + __func__, msg->addr); 91 + 92 + for (i = 0; i < msg->len; i++) { 93 + dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); 94 + txd = (msg->addr << 25) | (msg->buf[i] << 8) 95 + | MANTIS_I2C_RATE_3 96 + | MANTIS_I2C_STOP 97 + | MANTIS_I2C_PGMODE; 98 + 99 + if (i == (msg->len - 1)) 100 + txd &= ~MANTIS_I2C_STOP; 101 + 102 + mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); 103 + mmwrite(txd, MANTIS_I2CDATA_CTL); 104 + 105 + /* wait for xfer completion */ 106 + for (trials = 0; trials < TRIALS; trials++) { 107 + stat = mmread(MANTIS_INT_STAT); 108 + if (stat & MANTIS_INT_I2CDONE) 109 + break; 110 + } 111 + 112 + dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); 113 + 114 + /* wait for xfer completion */ 115 + for (trials = 0; trials < TRIALS; trials++) { 116 + stat = mmread(MANTIS_INT_STAT); 117 + if (stat & MANTIS_INT_I2CRACK) 118 + break; 119 + } 120 + 121 + dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); 122 + } 123 + dprintk(MANTIS_INFO, 0, "]\n"); 124 + 125 + return 0; 126 + } 127 + 128 + static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) 129 + { 130 + int ret = 0, i = 0, trials; 131 + u32 stat, data, txd; 132 + struct mantis_pci *mantis; 133 + struct mantis_hwconfig *config; 134 + 135 + mantis = i2c_get_adapdata(adapter); 136 + BUG_ON(!mantis); 137 + config = mantis->hwconfig; 138 + BUG_ON(!config); 139 + 140 + dprintk(MANTIS_DEBUG, 1, "Messages:%d", num); 141 + mutex_lock(&mantis->i2c_lock); 142 + 143 + while (i < num) { 144 + /* Byte MODE */ 145 + if ((config->i2c_mode & MANTIS_BYTE_MODE) && 146 + ((i + 1) < num) && 147 + (msgs[i].len < 2) && 148 + (msgs[i + 1].len < 2) && 149 + (msgs[i + 1].flags & I2C_M_RD)) { 150 + 151 + dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n"); 152 + 153 + /* Read operation */ 154 + txd = msgs[i].addr << 25 | (0x1 << 24) 155 + | (msgs[i].buf[0] << 16) 156 + | MANTIS_I2C_RATE_3; 157 + 158 + mmwrite(txd, MANTIS_I2CDATA_CTL); 159 + /* wait for xfer completion */ 160 + for (trials = 0; trials < TRIALS; trials++) { 161 + stat = mmread(MANTIS_INT_STAT); 162 + if (stat & MANTIS_INT_I2CDONE) 163 + break; 164 + } 165 + 166 + /* check for xfer completion */ 167 + if (stat & MANTIS_INT_I2CDONE) { 168 + /* check xfer was acknowledged */ 169 + if (stat & MANTIS_INT_I2CRACK) { 170 + data = mmread(MANTIS_I2CDATA_CTL); 171 + msgs[i + 1].buf[0] = (data >> 8) & 0xff; 172 + dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]); 173 + } else { 174 + /* I/O error */ 175 + dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); 176 + ret = -EIO; 177 + break; 178 + } 179 + } else { 180 + /* I/O error */ 181 + dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); 182 + ret = -EIO; 183 + break; 184 + } 185 + i += 2; /* Write/Read operation in one go */ 186 + } 187 + 188 + if (i < num) { 189 + if (msgs[i].flags & I2C_M_RD) 190 + ret = mantis_i2c_read(mantis, &msgs[i]); 191 + else 192 + ret = mantis_i2c_write(mantis, &msgs[i]); 193 + 194 + i++; 195 + if (ret < 0) 196 + goto bail_out; 197 + } 198 + 199 + } 200 + 201 + mutex_unlock(&mantis->i2c_lock); 202 + 203 + return num; 204 + 205 + bail_out: 206 + mutex_unlock(&mantis->i2c_lock); 207 + return ret; 208 + } 209 + 210 + static u32 mantis_i2c_func(struct i2c_adapter *adapter) 211 + { 212 + return I2C_FUNC_SMBUS_EMUL; 213 + } 214 + 215 + static struct i2c_algorithm mantis_algo = { 216 + .master_xfer = mantis_i2c_xfer, 217 + .functionality = mantis_i2c_func, 218 + }; 219 + 220 + int __devinit mantis_i2c_init(struct mantis_pci *mantis) 221 + { 222 + u32 intstat, intmask; 223 + struct i2c_adapter *i2c_adapter = &mantis->adapter; 224 + struct pci_dev *pdev = mantis->pdev; 225 + 226 + init_waitqueue_head(&mantis->i2c_wq); 227 + mutex_init(&mantis->i2c_lock); 228 + strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name)); 229 + i2c_set_adapdata(i2c_adapter, mantis); 230 + 231 + i2c_adapter->owner = THIS_MODULE; 232 + i2c_adapter->class = I2C_CLASS_TV_DIGITAL; 233 + i2c_adapter->algo = &mantis_algo; 234 + i2c_adapter->algo_data = NULL; 235 + i2c_adapter->timeout = 500; 236 + i2c_adapter->retries = 3; 237 + i2c_adapter->dev.parent = &pdev->dev; 238 + 239 + mantis->i2c_rc = i2c_add_adapter(i2c_adapter); 240 + if (mantis->i2c_rc < 0) 241 + return mantis->i2c_rc; 242 + 243 + dprintk(MANTIS_DEBUG, 1, "Initializing I2C .."); 244 + 245 + intstat = mmread(MANTIS_INT_STAT); 246 + intmask = mmread(MANTIS_INT_MASK); 247 + mmwrite(intstat, MANTIS_INT_STAT); 248 + dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); 249 + intmask = mmread(MANTIS_INT_MASK); 250 + mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); 251 + 252 + return 0; 253 + } 254 + EXPORT_SYMBOL_GPL(mantis_i2c_init); 255 + 256 + int mantis_i2c_exit(struct mantis_pci *mantis) 257 + { 258 + u32 intmask; 259 + 260 + dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); 261 + intmask = mmread(MANTIS_INT_MASK); 262 + mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); 263 + 264 + dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); 265 + return i2c_del_adapter(&mantis->adapter); 266 + } 267 + EXPORT_SYMBOL_GPL(mantis_i2c_exit);
+30
drivers/media/dvb/mantis/mantis_i2c.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_I2C_H 22 + #define __MANTIS_I2C_H 23 + 24 + #define I2C_STOP (1 << 0) 25 + #define I2C_READ (1 << 1) 26 + 27 + extern int mantis_i2c_init(struct mantis_pci *mantis); 28 + extern int mantis_i2c_exit(struct mantis_pci *mantis); 29 + 30 + #endif /* __MANTIS_I2C_H */
+148
drivers/media/dvb/mantis/mantis_input.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/input.h> 22 + #include <media/ir-common.h> 23 + #include <linux/pci.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "mantis_common.h" 32 + #include "mantis_reg.h" 33 + #include "mantis_uart.h" 34 + 35 + static struct ir_scancode mantis_ir_table[] = { 36 + { 0x29, KEY_POWER }, 37 + { 0x28, KEY_FAVORITES }, 38 + { 0x30, KEY_TEXT }, 39 + { 0x17, KEY_INFO }, /* Preview */ 40 + { 0x23, KEY_EPG }, 41 + { 0x3b, KEY_F22 }, /* Record List */ 42 + { 0x3c, KEY_1 }, 43 + { 0x3e, KEY_2 }, 44 + { 0x39, KEY_3 }, 45 + { 0x36, KEY_4 }, 46 + { 0x22, KEY_5 }, 47 + { 0x20, KEY_6 }, 48 + { 0x32, KEY_7 }, 49 + { 0x26, KEY_8 }, 50 + { 0x24, KEY_9 }, 51 + { 0x2a, KEY_0 }, 52 + 53 + { 0x33, KEY_CANCEL }, 54 + { 0x2c, KEY_BACK }, 55 + { 0x15, KEY_CLEAR }, 56 + { 0x3f, KEY_TAB }, 57 + { 0x10, KEY_ENTER }, 58 + { 0x14, KEY_UP }, 59 + { 0x0d, KEY_RIGHT }, 60 + { 0x0e, KEY_DOWN }, 61 + { 0x11, KEY_LEFT }, 62 + 63 + { 0x21, KEY_VOLUMEUP }, 64 + { 0x35, KEY_VOLUMEDOWN }, 65 + { 0x3d, KEY_CHANNELDOWN }, 66 + { 0x3a, KEY_CHANNELUP }, 67 + { 0x2e, KEY_RECORD }, 68 + { 0x2b, KEY_PLAY }, 69 + { 0x13, KEY_PAUSE }, 70 + { 0x25, KEY_STOP }, 71 + 72 + { 0x1f, KEY_REWIND }, 73 + { 0x2d, KEY_FASTFORWARD }, 74 + { 0x1e, KEY_PREVIOUS }, /* Replay |< */ 75 + { 0x1d, KEY_NEXT }, /* Skip >| */ 76 + 77 + { 0x0b, KEY_CAMERA }, /* Capture */ 78 + { 0x0f, KEY_LANGUAGE }, /* SAP */ 79 + { 0x18, KEY_MODE }, /* PIP */ 80 + { 0x12, KEY_ZOOM }, /* Full screen */ 81 + { 0x1c, KEY_SUBTITLE }, 82 + { 0x2f, KEY_MUTE }, 83 + { 0x16, KEY_F20 }, /* L/R */ 84 + { 0x38, KEY_F21 }, /* Hibernate */ 85 + 86 + { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */ 87 + { 0x31, KEY_AGAIN }, /* Recall */ 88 + { 0x1a, KEY_KPPLUS }, /* Zoom+ */ 89 + { 0x19, KEY_KPMINUS }, /* Zoom- */ 90 + { 0x27, KEY_RED }, 91 + { 0x0C, KEY_GREEN }, 92 + { 0x01, KEY_YELLOW }, 93 + { 0x00, KEY_BLUE }, 94 + }; 95 + 96 + struct ir_scancode_table ir_mantis = { 97 + .scan = mantis_ir_table, 98 + .size = ARRAY_SIZE(mantis_ir_table), 99 + }; 100 + EXPORT_SYMBOL_GPL(ir_mantis); 101 + 102 + int mantis_input_init(struct mantis_pci *mantis) 103 + { 104 + struct input_dev *rc; 105 + struct ir_input_state rc_state; 106 + char name[80], dev[80]; 107 + int err; 108 + 109 + rc = input_allocate_device(); 110 + if (!rc) { 111 + dprintk(MANTIS_ERROR, 1, "Input device allocate failed"); 112 + return -ENOMEM; 113 + } 114 + 115 + sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name); 116 + sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev)); 117 + 118 + rc->name = name; 119 + rc->phys = dev; 120 + 121 + ir_input_init(rc, &rc_state, IR_TYPE_OTHER); 122 + 123 + rc->id.bustype = BUS_PCI; 124 + rc->id.vendor = mantis->vendor_id; 125 + rc->id.product = mantis->device_id; 126 + rc->id.version = 1; 127 + rc->dev = mantis->pdev->dev; 128 + 129 + err = ir_input_register(rc, &ir_mantis); 130 + if (err) { 131 + dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); 132 + input_free_device(rc); 133 + return -ENODEV; 134 + } 135 + 136 + mantis->rc = rc; 137 + 138 + return 0; 139 + } 140 + 141 + int mantis_exit(struct mantis_pci *mantis) 142 + { 143 + struct input_dev *rc = mantis->rc; 144 + 145 + ir_input_unregister(rc); 146 + 147 + return 0; 148 + }
+130
drivers/media/dvb/mantis/mantis_ioc.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/i2c.h> 23 + 24 + #include <linux/signal.h> 25 + #include <linux/sched.h> 26 + #include <linux/interrupt.h> 27 + 28 + #include "dmxdev.h" 29 + #include "dvbdev.h" 30 + #include "dvb_demux.h" 31 + #include "dvb_frontend.h" 32 + #include "dvb_net.h" 33 + 34 + #include "mantis_common.h" 35 + #include "mantis_reg.h" 36 + #include "mantis_ioc.h" 37 + 38 + static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length) 39 + { 40 + struct i2c_adapter *adapter = &mantis->adapter; 41 + int err; 42 + u8 buf = reg; 43 + 44 + struct i2c_msg msg[] = { 45 + { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 }, 46 + { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length }, 47 + }; 48 + 49 + err = i2c_transfer(adapter, msg, 2); 50 + if (err < 0) { 51 + dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", 52 + err, data[0], data[1]); 53 + 54 + return err; 55 + } 56 + 57 + return 0; 58 + } 59 + int mantis_get_mac(struct mantis_pci *mantis) 60 + { 61 + int err; 62 + u8 mac_addr[6] = {0}; 63 + 64 + err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6); 65 + if (err < 0) { 66 + dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err); 67 + 68 + return err; 69 + } 70 + 71 + dprintk(MANTIS_ERROR, 0, 72 + " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", 73 + mac_addr[0], 74 + mac_addr[1], 75 + mac_addr[2], 76 + mac_addr[3], 77 + mac_addr[4], 78 + mac_addr[5]); 79 + 80 + return 0; 81 + } 82 + EXPORT_SYMBOL_GPL(mantis_get_mac); 83 + 84 + /* Turn the given bit on or off. */ 85 + void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) 86 + { 87 + u32 cur; 88 + 89 + dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value); 90 + cur = mmread(MANTIS_GPIF_ADDR); 91 + if (value) 92 + mantis->gpio_status = cur | (1 << bitpos); 93 + else 94 + mantis->gpio_status = cur & (~(1 << bitpos)); 95 + 96 + dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status); 97 + mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); 98 + mmwrite(0x00, MANTIS_GPIF_DOUT); 99 + } 100 + EXPORT_SYMBOL_GPL(gpio_set_bits); 101 + 102 + int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl) 103 + { 104 + u32 reg; 105 + 106 + reg = mmread(MANTIS_CONTROL); 107 + switch (stream_ctl) { 108 + case STREAM_TO_HIF: 109 + dprintk(MANTIS_DEBUG, 1, "Set stream to HIF"); 110 + reg &= 0xff - MANTIS_BYPASS; 111 + mmwrite(reg, MANTIS_CONTROL); 112 + reg |= MANTIS_BYPASS; 113 + mmwrite(reg, MANTIS_CONTROL); 114 + break; 115 + 116 + case STREAM_TO_CAM: 117 + dprintk(MANTIS_DEBUG, 1, "Set stream to CAM"); 118 + reg |= MANTIS_BYPASS; 119 + mmwrite(reg, MANTIS_CONTROL); 120 + reg &= 0xff - MANTIS_BYPASS; 121 + mmwrite(reg, MANTIS_CONTROL); 122 + break; 123 + default: 124 + dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl); 125 + return -1; 126 + } 127 + 128 + return 0; 129 + } 130 + EXPORT_SYMBOL_GPL(mantis_stream_control);
+51
drivers/media/dvb/mantis/mantis_ioc.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_IOC_H 22 + #define __MANTIS_IOC_H 23 + 24 + #define GPIF_A00 0x00 25 + #define GPIF_A01 0x01 26 + #define GPIF_A02 0x02 27 + #define GPIF_A03 0x03 28 + #define GPIF_A04 0x04 29 + #define GPIF_A05 0x05 30 + #define GPIF_A06 0x06 31 + #define GPIF_A07 0x07 32 + #define GPIF_A08 0x08 33 + #define GPIF_A09 0x09 34 + #define GPIF_A10 0x0a 35 + #define GPIF_A11 0x0b 36 + 37 + #define GPIF_A12 0x0c 38 + #define GPIF_A13 0x0d 39 + #define GPIF_A14 0x0e 40 + 41 + enum mantis_stream_control { 42 + STREAM_TO_HIF = 0, 43 + STREAM_TO_CAM 44 + }; 45 + 46 + extern int mantis_get_mac(struct mantis_pci *mantis); 47 + extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value); 48 + 49 + extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl); 50 + 51 + #endif /* __MANTIS_IOC_H */
+83
drivers/media/dvb/mantis/mantis_link.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_LINK_H 22 + #define __MANTIS_LINK_H 23 + 24 + #include <linux/mutex.h> 25 + #include <linux/workqueue.h> 26 + #include "dvb_ca_en50221.h" 27 + 28 + enum mantis_sbuf_status { 29 + MANTIS_SBUF_DATA_AVAIL = 1, 30 + MANTIS_SBUF_DATA_EMPTY = 2, 31 + MANTIS_SBUF_DATA_OVFLW = 3 32 + }; 33 + 34 + struct mantis_slot { 35 + u32 timeout; 36 + u32 slave_cfg; 37 + u32 bar; 38 + }; 39 + 40 + /* Physical layer */ 41 + enum mantis_slot_state { 42 + MODULE_INSERTED = 3, 43 + MODULE_XTRACTED = 4 44 + }; 45 + 46 + struct mantis_ca { 47 + struct mantis_slot slot[4]; 48 + 49 + struct work_struct hif_evm_work; 50 + 51 + u32 hif_event; 52 + wait_queue_head_t hif_opdone_wq; 53 + wait_queue_head_t hif_brrdyw_wq; 54 + wait_queue_head_t hif_data_wq; 55 + wait_queue_head_t hif_write_wq; /* HIF Write op */ 56 + 57 + enum mantis_sbuf_status sbuf_status; 58 + 59 + enum mantis_slot_state slot_state; 60 + 61 + void *ca_priv; 62 + 63 + struct dvb_ca_en50221 en50221; 64 + struct mutex ca_lock; 65 + }; 66 + 67 + /* CA */ 68 + extern void mantis_event_cam_plugin(struct mantis_ca *ca); 69 + extern void mantis_event_cam_unplug(struct mantis_ca *ca); 70 + extern int mantis_pcmcia_init(struct mantis_ca *ca); 71 + extern void mantis_pcmcia_exit(struct mantis_ca *ca); 72 + extern int mantis_evmgr_init(struct mantis_ca *ca); 73 + extern void mantis_evmgr_exit(struct mantis_ca *ca); 74 + 75 + /* HIF */ 76 + extern int mantis_hif_init(struct mantis_ca *ca); 77 + extern void mantis_hif_exit(struct mantis_ca *ca); 78 + extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr); 79 + extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data); 80 + extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr); 81 + extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data); 82 + 83 + #endif /* __MANTIS_LINK_H */
+177
drivers/media/dvb/mantis/mantis_pci.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/moduleparam.h> 23 + #include <linux/kernel.h> 24 + #include <asm/io.h> 25 + #include <asm/pgtable.h> 26 + #include <asm/page.h> 27 + #include <linux/kmod.h> 28 + #include <linux/vmalloc.h> 29 + #include <linux/init.h> 30 + #include <linux/device.h> 31 + #include <linux/pci.h> 32 + 33 + #include <asm/irq.h> 34 + #include <linux/signal.h> 35 + #include <linux/sched.h> 36 + #include <linux/interrupt.h> 37 + 38 + #include "dmxdev.h" 39 + #include "dvbdev.h" 40 + #include "dvb_demux.h" 41 + #include "dvb_frontend.h" 42 + #include "dvb_net.h" 43 + 44 + #include <asm/irq.h> 45 + #include <linux/signal.h> 46 + #include <linux/sched.h> 47 + #include <linux/interrupt.h> 48 + 49 + #include "mantis_common.h" 50 + #include "mantis_reg.h" 51 + #include "mantis_pci.h" 52 + 53 + #define DRIVER_NAME "Mantis Core" 54 + 55 + int __devinit mantis_pci_init(struct mantis_pci *mantis) 56 + { 57 + u8 revision, latency; 58 + struct mantis_hwconfig *config = mantis->hwconfig; 59 + struct pci_dev *pdev = mantis->pdev; 60 + int err, ret = 0; 61 + 62 + dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", 63 + config->model_name, 64 + config->dev_type, 65 + mantis->pdev->bus->number, 66 + PCI_SLOT(mantis->pdev->devfn), 67 + PCI_FUNC(mantis->pdev->devfn)); 68 + 69 + err = pci_enable_device(pdev); 70 + if (err != 0) { 71 + ret = -ENODEV; 72 + dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err); 73 + goto fail0; 74 + } 75 + 76 + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 77 + if (err != 0) { 78 + dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err); 79 + ret = -ENOMEM; 80 + goto fail1; 81 + } 82 + 83 + pci_set_master(pdev); 84 + 85 + if (!request_mem_region(pci_resource_start(pdev, 0), 86 + pci_resource_len(pdev, 0), 87 + DRIVER_NAME)) { 88 + 89 + dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !"); 90 + ret = -ENODEV; 91 + goto fail1; 92 + } 93 + 94 + mantis->mmio = ioremap(pci_resource_start(pdev, 0), 95 + pci_resource_len(pdev, 0)); 96 + 97 + if (!mantis->mmio) { 98 + dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !"); 99 + ret = -ENODEV; 100 + goto fail2; 101 + } 102 + 103 + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); 104 + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 105 + mantis->latency = latency; 106 + mantis->revision = revision; 107 + 108 + dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", 109 + mantis->revision, 110 + mantis->pdev->subsystem_vendor, 111 + mantis->pdev->subsystem_device); 112 + 113 + dprintk(MANTIS_ERROR, 0, 114 + "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", 115 + mantis->pdev->irq, 116 + mantis->latency, 117 + mantis->mantis_addr, 118 + mantis->mmio); 119 + 120 + err = request_irq(pdev->irq, 121 + config->irq_handler, 122 + IRQF_SHARED, 123 + DRIVER_NAME, 124 + mantis); 125 + 126 + if (err != 0) { 127 + 128 + dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err); 129 + ret = -ENODEV; 130 + goto fail3; 131 + } 132 + 133 + pci_set_drvdata(pdev, mantis); 134 + return ret; 135 + 136 + /* Error conditions */ 137 + fail3: 138 + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret); 139 + if (mantis->mmio) 140 + iounmap(mantis->mmio); 141 + 142 + fail2: 143 + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret); 144 + release_mem_region(pci_resource_start(pdev, 0), 145 + pci_resource_len(pdev, 0)); 146 + 147 + fail1: 148 + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret); 149 + pci_disable_device(pdev); 150 + 151 + fail0: 152 + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); 153 + pci_set_drvdata(pdev, NULL); 154 + return ret; 155 + } 156 + EXPORT_SYMBOL_GPL(mantis_pci_init); 157 + 158 + void mantis_pci_exit(struct mantis_pci *mantis) 159 + { 160 + struct pci_dev *pdev = mantis->pdev; 161 + 162 + dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio); 163 + free_irq(pdev->irq, mantis); 164 + if (mantis->mmio) { 165 + iounmap(mantis->mmio); 166 + release_mem_region(pci_resource_start(pdev, 0), 167 + pci_resource_len(pdev, 0)); 168 + } 169 + 170 + pci_disable_device(pdev); 171 + pci_set_drvdata(pdev, NULL); 172 + } 173 + EXPORT_SYMBOL_GPL(mantis_pci_exit); 174 + 175 + MODULE_DESCRIPTION("Mantis PCI DTV bridge driver"); 176 + MODULE_AUTHOR("Manu Abraham"); 177 + MODULE_LICENSE("GPL");
+27
drivers/media/dvb/mantis/mantis_pci.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_PCI_H 22 + #define __MANTIS_PCI_H 23 + 24 + extern int mantis_pci_init(struct mantis_pci *mantis); 25 + extern void mantis_pci_exit(struct mantis_pci *mantis); 26 + 27 + #endif /* __MANTIS_PCI_H */
+120
drivers/media/dvb/mantis/mantis_pcmcia.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + 23 + #include <linux/signal.h> 24 + #include <linux/sched.h> 25 + #include <linux/interrupt.h> 26 + 27 + #include "dmxdev.h" 28 + #include "dvbdev.h" 29 + #include "dvb_demux.h" 30 + #include "dvb_frontend.h" 31 + #include "dvb_net.h" 32 + 33 + #include "mantis_common.h" 34 + #include "mantis_link.h" /* temporary due to physical layer stuff */ 35 + #include "mantis_reg.h" 36 + 37 + /* 38 + * If Slot state is already PLUG_IN event and we are called 39 + * again, definitely it is jitter alone 40 + */ 41 + void mantis_event_cam_plugin(struct mantis_ca *ca) 42 + { 43 + struct mantis_pci *mantis = ca->ca_priv; 44 + 45 + u32 gpif_irqcfg; 46 + 47 + if (ca->slot_state == MODULE_XTRACTED) { 48 + dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num); 49 + udelay(50); 50 + mmwrite(0xda000000, MANTIS_CARD_RESET); 51 + gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); 52 + gpif_irqcfg |= MANTIS_MASK_PLUGOUT; 53 + gpif_irqcfg &= ~MANTIS_MASK_PLUGIN; 54 + mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); 55 + udelay(500); 56 + ca->slot_state = MODULE_INSERTED; 57 + } 58 + udelay(100); 59 + } 60 + 61 + /* 62 + * If Slot state is already UN_PLUG event and we are called 63 + * again, definitely it is jitter alone 64 + */ 65 + void mantis_event_cam_unplug(struct mantis_ca *ca) 66 + { 67 + struct mantis_pci *mantis = ca->ca_priv; 68 + 69 + u32 gpif_irqcfg; 70 + 71 + if (ca->slot_state == MODULE_INSERTED) { 72 + dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num); 73 + udelay(50); 74 + mmwrite(0x00da0000, MANTIS_CARD_RESET); 75 + gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); 76 + gpif_irqcfg |= MANTIS_MASK_PLUGIN; 77 + gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT; 78 + mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); 79 + udelay(500); 80 + ca->slot_state = MODULE_XTRACTED; 81 + } 82 + udelay(100); 83 + } 84 + 85 + int mantis_pcmcia_init(struct mantis_ca *ca) 86 + { 87 + struct mantis_pci *mantis = ca->ca_priv; 88 + 89 + u32 gpif_stat, card_stat; 90 + 91 + mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK); 92 + gpif_stat = mmread(MANTIS_GPIF_STATUS); 93 + card_stat = mmread(MANTIS_GPIF_IRQCFG); 94 + 95 + if (gpif_stat & MANTIS_GPIF_DETSTAT) { 96 + dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num); 97 + mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG); 98 + ca->slot_state = MODULE_INSERTED; 99 + dvb_ca_en50221_camchange_irq(&ca->en50221, 100 + 0, 101 + DVB_CA_EN50221_CAMCHANGE_INSERTED); 102 + } else { 103 + dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num); 104 + mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG); 105 + ca->slot_state = MODULE_XTRACTED; 106 + dvb_ca_en50221_camchange_irq(&ca->en50221, 107 + 0, 108 + DVB_CA_EN50221_CAMCHANGE_REMOVED); 109 + } 110 + 111 + return 0; 112 + } 113 + 114 + void mantis_pcmcia_exit(struct mantis_ca *ca) 115 + { 116 + struct mantis_pci *mantis = ca->ca_priv; 117 + 118 + mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS); 119 + mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK); 120 + }
+197
drivers/media/dvb/mantis/mantis_reg.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_REG_H 22 + #define __MANTIS_REG_H 23 + 24 + /* Interrupts */ 25 + #define MANTIS_INT_STAT 0x00 26 + #define MANTIS_INT_MASK 0x04 27 + 28 + #define MANTIS_INT_RISCSTAT (0x0f << 28) 29 + #define MANTIS_INT_RISCEN (0x01 << 27) 30 + #define MANTIS_INT_I2CRACK (0x01 << 26) 31 + 32 + /* #define MANTIS_INT_GPIF (0xff << 12) */ 33 + 34 + #define MANTIS_INT_PCMCIA7 (0x01 << 19) 35 + #define MANTIS_INT_PCMCIA6 (0x01 << 18) 36 + #define MANTIS_INT_PCMCIA5 (0x01 << 17) 37 + #define MANTIS_INT_PCMCIA4 (0x01 << 16) 38 + #define MANTIS_INT_PCMCIA3 (0x01 << 15) 39 + #define MANTIS_INT_PCMCIA2 (0x01 << 14) 40 + #define MANTIS_INT_PCMCIA1 (0x01 << 13) 41 + #define MANTIS_INT_PCMCIA0 (0x01 << 12) 42 + #define MANTIS_INT_IRQ1 (0x01 << 11) 43 + #define MANTIS_INT_IRQ0 (0x01 << 10) 44 + #define MANTIS_INT_OCERR (0x01 << 8) 45 + #define MANTIS_INT_PABORT (0x01 << 7) 46 + #define MANTIS_INT_RIPERR (0x01 << 6) 47 + #define MANTIS_INT_PPERR (0x01 << 5) 48 + #define MANTIS_INT_FTRGT (0x01 << 3) 49 + #define MANTIS_INT_RISCI (0x01 << 1) 50 + #define MANTIS_INT_I2CDONE (0x01 << 0) 51 + 52 + /* DMA */ 53 + #define MANTIS_DMA_CTL 0x08 54 + #define MANTIS_GPIF_RD (0xff << 24) 55 + #define MANTIS_GPIF_WR (0xff << 16) 56 + #define MANTIS_CPU_DO (0x01 << 10) 57 + #define MANTIS_DRV_DO (0x01 << 9) 58 + #define MANTIS_I2C_RD (0x01 << 7) 59 + #define MANTIS_I2C_WR (0x01 << 6) 60 + #define MANTIS_DCAP_MODE (0x01 << 5) 61 + #define MANTIS_FIFO_TP_4 (0x00 << 3) 62 + #define MANTIS_FIFO_TP_8 (0x01 << 3) 63 + #define MANTIS_FIFO_TP_16 (0x02 << 3) 64 + #define MANTIS_FIFO_EN (0x01 << 2) 65 + #define MANTIS_DCAP_EN (0x01 << 1) 66 + #define MANTIS_RISC_EN (0x01 << 0) 67 + 68 + /* DEBUG */ 69 + #define MANTIS_DEBUGREG 0x0c 70 + #define MANTIS_DATINV (0x0e << 7) 71 + #define MANTIS_TOP_DEBUGSEL (0x07 << 4) 72 + #define MANTIS_PCMCIA_DEBUGSEL (0x0f << 0) 73 + 74 + #define MANTIS_RISC_START 0x10 75 + #define MANTIS_RISC_PC 0x14 76 + 77 + /* I2C */ 78 + #define MANTIS_I2CDATA_CTL 0x18 79 + #define MANTIS_I2C_RATE_1 (0x00 << 6) 80 + #define MANTIS_I2C_RATE_2 (0x01 << 6) 81 + #define MANTIS_I2C_RATE_3 (0x02 << 6) 82 + #define MANTIS_I2C_RATE_4 (0x03 << 6) 83 + #define MANTIS_I2C_STOP (0x01 << 5) 84 + #define MANTIS_I2C_PGMODE (0x01 << 3) 85 + 86 + /* DATA */ 87 + #define MANTIS_CMD_DATA_R1 0x20 88 + #define MANTIS_CMD_DATA_3 (0xff << 24) 89 + #define MANTIS_CMD_DATA_2 (0xff << 16) 90 + #define MANTIS_CMD_DATA_1 (0xff << 8) 91 + #define MANTIS_CMD_DATA_0 (0xff << 0) 92 + 93 + #define MANTIS_CMD_DATA_R2 0x24 94 + #define MANTIS_CMD_DATA_7 (0xff << 24) 95 + #define MANTIS_CMD_DATA_6 (0xff << 16) 96 + #define MANTIS_CMD_DATA_5 (0xff << 8) 97 + #define MANTIS_CMD_DATA_4 (0xff << 0) 98 + 99 + #define MANTIS_CONTROL 0x28 100 + #define MANTIS_DET (0x01 << 7) 101 + #define MANTIS_DAT_CF_EN (0x01 << 6) 102 + #define MANTIS_ACS (0x03 << 4) 103 + #define MANTIS_VCCEN (0x01 << 3) 104 + #define MANTIS_BYPASS (0x01 << 2) 105 + #define MANTIS_MRST (0x01 << 1) 106 + #define MANTIS_CRST_INT (0x01 << 0) 107 + 108 + #define MANTIS_GPIF_CFGSLA 0x84 109 + #define MANTIS_GPIF_WAITSMPL (0x07 << 28) 110 + #define MANTIS_GPIF_BYTEADDRSUB (0x01 << 25) 111 + #define MANTIS_GPIF_WAITPOL (0x01 << 24) 112 + #define MANTIS_GPIF_NCDELAY (0x07 << 20) 113 + #define MANTIS_GPIF_RW2CSDELAY (0x07 << 16) 114 + #define MANTIS_GPIF_SLFTIMEDMODE (0x01 << 15) 115 + #define MANTIS_GPIF_SLFTIMEDDELY (0x7f << 8) 116 + #define MANTIS_GPIF_DEVTYPE (0x07 << 4) 117 + #define MANTIS_GPIF_BIGENDIAN (0x01 << 3) 118 + #define MANTIS_GPIF_FETCHCMD (0x03 << 1) 119 + #define MANTIS_GPIF_HWORDDEV (0x01 << 0) 120 + 121 + #define MANTIS_GPIF_WSTOPER 0x90 122 + #define MANTIS_GPIF_WSTOPERWREN3 (0x01 << 31) 123 + #define MANTIS_GPIF_PARBOOTN (0x01 << 29) 124 + #define MANTIS_GPIF_WSTOPERSLID3 (0x1f << 24) 125 + #define MANTIS_GPIF_WSTOPERWREN2 (0x01 << 23) 126 + #define MANTIS_GPIF_WSTOPERSLID2 (0x1f << 16) 127 + #define MANTIS_GPIF_WSTOPERWREN1 (0x01 << 15) 128 + #define MANTIS_GPIF_WSTOPERSLID1 (0x1f << 8) 129 + #define MANTIS_GPIF_WSTOPERWREN0 (0x01 << 7) 130 + #define MANTIS_GPIF_WSTOPERSLID0 (0x1f << 0) 131 + 132 + #define MANTIS_GPIF_CS2RW 0x94 133 + #define MANTIS_GPIF_CS2RWWREN3 (0x01 << 31) 134 + #define MANTIS_GPIF_CS2RWDELY3 (0x3f << 24) 135 + #define MANTIS_GPIF_CS2RWWREN2 (0x01 << 23) 136 + #define MANTIS_GPIF_CS2RWDELY2 (0x3f << 16) 137 + #define MANTIS_GPIF_CS2RWWREN1 (0x01 << 15) 138 + #define MANTIS_GPIF_CS2RWDELY1 (0x3f << 8) 139 + #define MANTIS_GPIF_CS2RWWREN0 (0x01 << 7) 140 + #define MANTIS_GPIF_CS2RWDELY0 (0x3f << 0) 141 + 142 + #define MANTIS_GPIF_IRQCFG 0x98 143 + #define MANTIS_GPIF_IRQPOL (0x01 << 8) 144 + #define MANTIS_MASK_WRACK (0x01 << 7) 145 + #define MANTIS_MASK_BRRDY (0x01 << 6) 146 + #define MANTIS_MASK_OVFLW (0x01 << 5) 147 + #define MANTIS_MASK_OTHERR (0x01 << 4) 148 + #define MANTIS_MASK_WSTO (0x01 << 3) 149 + #define MANTIS_MASK_EXTIRQ (0x01 << 2) 150 + #define MANTIS_MASK_PLUGIN (0x01 << 1) 151 + #define MANTIS_MASK_PLUGOUT (0x01 << 0) 152 + 153 + #define MANTIS_GPIF_STATUS 0x9c 154 + #define MANTIS_SBUF_KILLOP (0x01 << 15) 155 + #define MANTIS_SBUF_OPDONE (0x01 << 14) 156 + #define MANTIS_SBUF_EMPTY (0x01 << 13) 157 + #define MANTIS_GPIF_DETSTAT (0x01 << 9) 158 + #define MANTIS_GPIF_INTSTAT (0x01 << 8) 159 + #define MANTIS_GPIF_WRACK (0x01 << 7) 160 + #define MANTIS_GPIF_BRRDY (0x01 << 6) 161 + #define MANTIS_SBUF_OVFLW (0x01 << 5) 162 + #define MANTIS_GPIF_OTHERR (0x01 << 4) 163 + #define MANTIS_SBUF_WSTO (0x01 << 3) 164 + #define MANTIS_GPIF_EXTIRQ (0x01 << 2) 165 + #define MANTIS_CARD_PLUGIN (0x01 << 1) 166 + #define MANTIS_CARD_PLUGOUT (0x01 << 0) 167 + 168 + #define MANTIS_GPIF_BRADDR 0xa0 169 + #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) 170 + #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) 171 + #define MANTIS_GPIF_BR_ADDR (0xfffffff << 0) 172 + 173 + #define MANTIS_GPIF_BRBYTES 0xa4 174 + #define MANTIS_GPIF_BRCNT (0xfff << 0) 175 + 176 + #define MANTIS_PCMCIA_RESET 0xa8 177 + #define MANTIS_PCMCIA_RSTVAL (0xff << 0) 178 + 179 + #define MANTIS_CARD_RESET 0xac 180 + 181 + #define MANTIS_GPIF_ADDR 0xb0 182 + #define MANTIS_GPIF_HIFRDWRN (0x01 << 31) 183 + #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) 184 + #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) 185 + #define MANTIS_GPIF_HIFADDR (0xfffffff << 0) 186 + 187 + #define MANTIS_GPIF_DOUT 0xb4 188 + #define MANTIS_GPIF_HIFDOUT (0xfffffff << 0) 189 + 190 + #define MANTIS_GPIF_DIN 0xb8 191 + #define MANTIS_GPIF_HIFDIN (0xfffffff << 0) 192 + 193 + #define MANTIS_GPIF_SPARE 0xbc 194 + #define MANTIS_GPIF_LOGICRD (0xffff << 16) 195 + #define MANTIS_GPIF_LOGICRW (0xffff << 0) 196 + 197 + #endif /* __MANTIS_REG_H */
+186
drivers/media/dvb/mantis/mantis_uart.c
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/spinlock.h> 23 + 24 + #include <linux/signal.h> 25 + #include <linux/sched.h> 26 + #include <linux/interrupt.h> 27 + 28 + #include "dmxdev.h" 29 + #include "dvbdev.h" 30 + #include "dvb_demux.h" 31 + #include "dvb_frontend.h" 32 + #include "dvb_net.h" 33 + 34 + #include "mantis_common.h" 35 + #include "mantis_reg.h" 36 + #include "mantis_uart.h" 37 + 38 + struct mantis_uart_params { 39 + enum mantis_baud baud_rate; 40 + enum mantis_parity parity; 41 + }; 42 + 43 + static struct { 44 + char string[7]; 45 + } rates[5] = { 46 + { "9600" }, 47 + { "19200" }, 48 + { "38400" }, 49 + { "57600" }, 50 + { "115200" } 51 + }; 52 + 53 + static struct { 54 + char string[5]; 55 + } parity[3] = { 56 + { "NONE" }, 57 + { "ODD" }, 58 + { "EVEN" } 59 + }; 60 + 61 + #define UART_MAX_BUF 16 62 + 63 + int mantis_uart_read(struct mantis_pci *mantis, u8 *data) 64 + { 65 + struct mantis_hwconfig *config = mantis->hwconfig; 66 + u32 stat = 0, i; 67 + 68 + /* get data */ 69 + for (i = 0; i < (config->bytes + 1); i++) { 70 + 71 + stat = mmread(MANTIS_UART_STAT); 72 + 73 + if (stat & MANTIS_UART_RXFIFO_FULL) { 74 + dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); 75 + } 76 + data[i] = mmread(MANTIS_UART_RXD) & 0x3f; 77 + 78 + dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f); 79 + 80 + if (data[i] & (1 << 7)) { 81 + dprintk(MANTIS_ERROR, 1, "UART framing error"); 82 + return -EINVAL; 83 + } 84 + if (data[i] & (1 << 6)) { 85 + dprintk(MANTIS_ERROR, 1, "UART parity error"); 86 + return -EINVAL; 87 + } 88 + } 89 + 90 + return 0; 91 + } 92 + 93 + static void mantis_uart_work(struct work_struct *work) 94 + { 95 + struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); 96 + struct mantis_hwconfig *config = mantis->hwconfig; 97 + u8 buf[16]; 98 + int i; 99 + 100 + mantis_uart_read(mantis, buf); 101 + 102 + for (i = 0; i < (config->bytes + 1); i++) 103 + dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); 104 + 105 + dprintk(MANTIS_DEBUG, 0, "\n"); 106 + } 107 + 108 + static int mantis_uart_setup(struct mantis_pci *mantis, 109 + struct mantis_uart_params *params) 110 + { 111 + u32 reg; 112 + 113 + mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL); 114 + 115 + reg = mmread(MANTIS_UART_BAUD); 116 + 117 + switch (params->baud_rate) { 118 + case MANTIS_BAUD_9600: 119 + reg |= 0xd8; 120 + break; 121 + case MANTIS_BAUD_19200: 122 + reg |= 0x6c; 123 + break; 124 + case MANTIS_BAUD_38400: 125 + reg |= 0x36; 126 + break; 127 + case MANTIS_BAUD_57600: 128 + reg |= 0x23; 129 + break; 130 + case MANTIS_BAUD_115200: 131 + reg |= 0x11; 132 + break; 133 + default: 134 + return -EINVAL; 135 + } 136 + 137 + mmwrite(reg, MANTIS_UART_BAUD); 138 + 139 + return 0; 140 + } 141 + 142 + int mantis_uart_init(struct mantis_pci *mantis) 143 + { 144 + struct mantis_hwconfig *config = mantis->hwconfig; 145 + struct mantis_uart_params params; 146 + 147 + /* default parity: */ 148 + params.baud_rate = config->baud_rate; 149 + params.parity = config->parity; 150 + dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s", 151 + rates[params.baud_rate].string, 152 + parity[params.parity].string); 153 + 154 + init_waitqueue_head(&mantis->uart_wq); 155 + spin_lock_init(&mantis->uart_lock); 156 + 157 + INIT_WORK(&mantis->uart_work, mantis_uart_work); 158 + 159 + /* disable interrupt */ 160 + mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); 161 + 162 + mantis_uart_setup(mantis, &params); 163 + 164 + /* default 1 byte */ 165 + mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD); 166 + 167 + /* flush buffer */ 168 + mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); 169 + 170 + /* enable interrupt */ 171 + mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK); 172 + mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); 173 + 174 + schedule_work(&mantis->uart_work); 175 + dprintk(MANTIS_DEBUG, 1, "UART succesfully initialized"); 176 + 177 + return 0; 178 + } 179 + EXPORT_SYMBOL_GPL(mantis_uart_init); 180 + 181 + void mantis_uart_exit(struct mantis_pci *mantis) 182 + { 183 + /* disable interrupt */ 184 + mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); 185 + } 186 + EXPORT_SYMBOL_GPL(mantis_uart_exit);
+58
drivers/media/dvb/mantis/mantis_uart.h
··· 1 + /* 2 + Mantis PCI bridge driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_UART_H 22 + #define __MANTIS_UART_H 23 + 24 + #define MANTIS_UART_CTL 0xe0 25 + #define MANTIS_UART_RXINT (1 << 4) 26 + #define MANTIS_UART_RXFLUSH (1 << 2) 27 + 28 + #define MANTIS_UART_RXD 0xe8 29 + #define MANTIS_UART_BAUD 0xec 30 + 31 + #define MANTIS_UART_STAT 0xf0 32 + #define MANTIS_UART_RXFIFO_DATA (1 << 7) 33 + #define MANTIS_UART_RXFIFO_EMPTY (1 << 6) 34 + #define MANTIS_UART_RXFIFO_FULL (1 << 3) 35 + #define MANTIS_UART_FRAME_ERR (1 << 2) 36 + #define MANTIS_UART_PARITY_ERR (1 << 1) 37 + #define MANTIS_UART_RXTHRESH_INT (1 << 0) 38 + 39 + enum mantis_baud { 40 + MANTIS_BAUD_9600 = 0, 41 + MANTIS_BAUD_19200, 42 + MANTIS_BAUD_38400, 43 + MANTIS_BAUD_57600, 44 + MANTIS_BAUD_115200 45 + }; 46 + 47 + enum mantis_parity { 48 + MANTIS_PARITY_NONE = 0, 49 + MANTIS_PARITY_EVEN, 50 + MANTIS_PARITY_ODD, 51 + }; 52 + 53 + struct mantis_pci; 54 + 55 + extern int mantis_uart_init(struct mantis_pci *mantis); 56 + extern void mantis_uart_exit(struct mantis_pci *mantis); 57 + 58 + #endif /* __MANTIS_UART_H */
+212
drivers/media/dvb/mantis/mantis_vp1033.c
··· 1 + /* 2 + Mantis VP-1033 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "stv0299.h" 32 + #include "mantis_common.h" 33 + #include "mantis_ioc.h" 34 + #include "mantis_dvb.h" 35 + #include "mantis_vp1033.h" 36 + #include "mantis_reg.h" 37 + 38 + u8 lgtdqcs001f_inittab[] = { 39 + 0x01, 0x15, 40 + 0x02, 0x00, 41 + 0x03, 0x00, 42 + 0x04, 0x2a, 43 + 0x05, 0x85, 44 + 0x06, 0x02, 45 + 0x07, 0x00, 46 + 0x08, 0x00, 47 + 0x0c, 0x01, 48 + 0x0d, 0x81, 49 + 0x0e, 0x44, 50 + 0x0f, 0x94, 51 + 0x10, 0x3c, 52 + 0x11, 0x84, 53 + 0x12, 0xb9, 54 + 0x13, 0xb5, 55 + 0x14, 0x4f, 56 + 0x15, 0xc9, 57 + 0x16, 0x80, 58 + 0x17, 0x36, 59 + 0x18, 0xfb, 60 + 0x19, 0xcf, 61 + 0x1a, 0xbc, 62 + 0x1c, 0x2b, 63 + 0x1d, 0x27, 64 + 0x1e, 0x00, 65 + 0x1f, 0x0b, 66 + 0x20, 0xa1, 67 + 0x21, 0x60, 68 + 0x22, 0x00, 69 + 0x23, 0x00, 70 + 0x28, 0x00, 71 + 0x29, 0x28, 72 + 0x2a, 0x14, 73 + 0x2b, 0x0f, 74 + 0x2c, 0x09, 75 + 0x2d, 0x05, 76 + 0x31, 0x1f, 77 + 0x32, 0x19, 78 + 0x33, 0xfc, 79 + 0x34, 0x13, 80 + 0xff, 0xff, 81 + }; 82 + 83 + #define MANTIS_MODEL_NAME "VP-1033" 84 + #define MANTIS_DEV_TYPE "DVB-S/DSS" 85 + 86 + int lgtdqcs001f_tuner_set(struct dvb_frontend *fe, 87 + struct dvb_frontend_parameters *params) 88 + { 89 + struct mantis_pci *mantis = fe->dvb->priv; 90 + struct i2c_adapter *adapter = &mantis->adapter; 91 + 92 + u8 buf[4]; 93 + u32 div; 94 + 95 + 96 + struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)}; 97 + 98 + div = params->frequency / 250; 99 + 100 + buf[0] = (div >> 8) & 0x7f; 101 + buf[1] = div & 0xff; 102 + buf[2] = 0x83; 103 + buf[3] = 0xc0; 104 + 105 + if (params->frequency < 1531000) 106 + buf[3] |= 0x04; 107 + else 108 + buf[3] &= ~0x04; 109 + if (i2c_transfer(adapter, &msg, 1) < 0) { 110 + dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed"); 111 + return -EIO; 112 + } 113 + msleep_interruptible(100); 114 + 115 + return 0; 116 + } 117 + 118 + int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe, 119 + u32 srate, u32 ratio) 120 + { 121 + u8 aclk = 0; 122 + u8 bclk = 0; 123 + 124 + if (srate < 1500000) { 125 + aclk = 0xb7; 126 + bclk = 0x47; 127 + } else if (srate < 3000000) { 128 + aclk = 0xb7; 129 + bclk = 0x4b; 130 + } else if (srate < 7000000) { 131 + aclk = 0xb7; 132 + bclk = 0x4f; 133 + } else if (srate < 14000000) { 134 + aclk = 0xb7; 135 + bclk = 0x53; 136 + } else if (srate < 30000000) { 137 + aclk = 0xb6; 138 + bclk = 0x53; 139 + } else if (srate < 45000000) { 140 + aclk = 0xb4; 141 + bclk = 0x51; 142 + } 143 + stv0299_writereg(fe, 0x13, aclk); 144 + stv0299_writereg(fe, 0x14, bclk); 145 + 146 + stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); 147 + stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); 148 + stv0299_writereg(fe, 0x21, ratio & 0xf0); 149 + 150 + return 0; 151 + } 152 + 153 + struct stv0299_config lgtdqcs001f_config = { 154 + .demod_address = 0x68, 155 + .inittab = lgtdqcs001f_inittab, 156 + .mclk = 88000000UL, 157 + .invert = 0, 158 + .skip_reinit = 0, 159 + .volt13_op0_op1 = STV0299_VOLT13_OP0, 160 + .min_delay_ms = 100, 161 + .set_symbol_rate = lgtdqcs001f_set_symbol_rate, 162 + }; 163 + 164 + static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 165 + { 166 + struct i2c_adapter *adapter = &mantis->adapter; 167 + 168 + int err = 0; 169 + 170 + err = mantis_frontend_power(mantis, POWER_ON); 171 + if (err == 0) { 172 + mantis_frontend_soft_reset(mantis); 173 + msleep(250); 174 + 175 + dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)"); 176 + fe = stv0299_attach(&lgtdqcs001f_config, adapter); 177 + 178 + if (fe) { 179 + fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set; 180 + dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x", 181 + lgtdqcs001f_config.demod_address); 182 + 183 + dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success"); 184 + } else { 185 + return -1; 186 + } 187 + } else { 188 + dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", 189 + adapter->name, 190 + err); 191 + 192 + return -EIO; 193 + } 194 + mantis->fe = fe; 195 + dprintk(MANTIS_ERROR, 1, "Done!"); 196 + 197 + return 0; 198 + } 199 + 200 + struct mantis_hwconfig vp1033_config = { 201 + .model_name = MANTIS_MODEL_NAME, 202 + .dev_type = MANTIS_DEV_TYPE, 203 + .ts_size = MANTIS_TS_204, 204 + 205 + .baud_rate = MANTIS_BAUD_9600, 206 + .parity = MANTIS_PARITY_NONE, 207 + .bytes = 0, 208 + 209 + .frontend_init = vp1033_frontend_init, 210 + .power = GPIF_A12, 211 + .reset = GPIF_A13, 212 + };
+30
drivers/media/dvb/mantis/mantis_vp1033.h
··· 1 + /* 2 + Mantis VP-1033 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP1033_H 22 + #define __MANTIS_VP1033_H 23 + 24 + #include "mantis_common.h" 25 + 26 + #define MANTIS_VP_1033_DVB_S 0x0016 27 + 28 + extern struct mantis_hwconfig vp1033_config; 29 + 30 + #endif /* __MANTIS_VP1033_H */
+119
drivers/media/dvb/mantis/mantis_vp1034.c
··· 1 + /* 2 + Mantis VP-1034 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "mb86a16.h" 32 + #include "mantis_common.h" 33 + #include "mantis_ioc.h" 34 + #include "mantis_dvb.h" 35 + #include "mantis_vp1034.h" 36 + #include "mantis_reg.h" 37 + 38 + struct mb86a16_config vp1034_mb86a16_config = { 39 + .demod_address = 0x08, 40 + .set_voltage = vp1034_set_voltage, 41 + }; 42 + 43 + #define MANTIS_MODEL_NAME "VP-1034" 44 + #define MANTIS_DEV_TYPE "DVB-S/DSS" 45 + 46 + int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 47 + { 48 + struct mantis_pci *mantis = fe->dvb->priv; 49 + 50 + switch (voltage) { 51 + case SEC_VOLTAGE_13: 52 + dprintk(MANTIS_ERROR, 1, "Polarization=[13V]"); 53 + gpio_set_bits(mantis, 13, 1); 54 + gpio_set_bits(mantis, 14, 0); 55 + break; 56 + case SEC_VOLTAGE_18: 57 + dprintk(MANTIS_ERROR, 1, "Polarization=[18V]"); 58 + gpio_set_bits(mantis, 13, 1); 59 + gpio_set_bits(mantis, 14, 1); 60 + break; 61 + case SEC_VOLTAGE_OFF: 62 + dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN"); 63 + break; 64 + default: 65 + dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage); 66 + return -EINVAL; 67 + } 68 + mmwrite(0x00, MANTIS_GPIF_DOUT); 69 + 70 + return 0; 71 + } 72 + 73 + static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 74 + { 75 + struct i2c_adapter *adapter = &mantis->adapter; 76 + 77 + int err = 0; 78 + 79 + err = mantis_frontend_power(mantis, POWER_ON); 80 + if (err == 0) { 81 + mantis_frontend_soft_reset(mantis); 82 + msleep(250); 83 + 84 + dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); 85 + fe = mb86a16_attach(&vp1034_mb86a16_config, adapter); 86 + if (fe) { 87 + dprintk(MANTIS_ERROR, 1, 88 + "found MB86A16 DVB-S/DSS frontend @0x%02x", 89 + vp1034_mb86a16_config.demod_address); 90 + 91 + } else { 92 + return -1; 93 + } 94 + } else { 95 + dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", 96 + adapter->name, 97 + err); 98 + 99 + return -EIO; 100 + } 101 + mantis->fe = fe; 102 + dprintk(MANTIS_ERROR, 1, "Done!"); 103 + 104 + return 0; 105 + } 106 + 107 + struct mantis_hwconfig vp1034_config = { 108 + .model_name = MANTIS_MODEL_NAME, 109 + .dev_type = MANTIS_DEV_TYPE, 110 + .ts_size = MANTIS_TS_204, 111 + 112 + .baud_rate = MANTIS_BAUD_9600, 113 + .parity = MANTIS_PARITY_NONE, 114 + .bytes = 0, 115 + 116 + .frontend_init = vp1034_frontend_init, 117 + .power = GPIF_A12, 118 + .reset = GPIF_A13, 119 + };
+33
drivers/media/dvb/mantis/mantis_vp1034.h
··· 1 + /* 2 + Mantis VP-1034 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP1034_H 22 + #define __MANTIS_VP1034_H 23 + 24 + #include "dvb_frontend.h" 25 + #include "mantis_common.h" 26 + 27 + 28 + #define MANTIS_VP_1034_DVB_S 0x0014 29 + 30 + extern struct mantis_hwconfig vp1034_config; 31 + extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); 32 + 33 + #endif /* __MANTIS_VP1034_H */
+358
drivers/media/dvb/mantis/mantis_vp1041.c
··· 1 + /* 2 + Mantis VP-1041 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "mantis_common.h" 32 + #include "mantis_ioc.h" 33 + #include "mantis_dvb.h" 34 + #include "mantis_vp1041.h" 35 + #include "stb0899_reg.h" 36 + #include "stb0899_drv.h" 37 + #include "stb0899_cfg.h" 38 + #include "stb6100_cfg.h" 39 + #include "stb6100.h" 40 + #include "lnbp21.h" 41 + 42 + #define MANTIS_MODEL_NAME "VP-1041" 43 + #define MANTIS_DEV_TYPE "DSS/DVB-S/DVB-S2" 44 + 45 + static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { 46 + 47 + /* 0x0000000b, *//* SYSREG */ 48 + { STB0899_DEV_ID , 0x30 }, 49 + { STB0899_DISCNTRL1 , 0x32 }, 50 + { STB0899_DISCNTRL2 , 0x80 }, 51 + { STB0899_DISRX_ST0 , 0x04 }, 52 + { STB0899_DISRX_ST1 , 0x00 }, 53 + { STB0899_DISPARITY , 0x00 }, 54 + { STB0899_DISFIFO , 0x00 }, 55 + { STB0899_DISSTATUS , 0x20 }, 56 + { STB0899_DISF22 , 0x99 }, 57 + { STB0899_DISF22RX , 0xa8 }, 58 + /* SYSREG ? */ 59 + { STB0899_ACRPRESC , 0x11 }, 60 + { STB0899_ACRDIV1 , 0x0a }, 61 + { STB0899_ACRDIV2 , 0x05 }, 62 + { STB0899_DACR1 , 0x00 }, 63 + { STB0899_DACR2 , 0x00 }, 64 + { STB0899_OUTCFG , 0x00 }, 65 + { STB0899_MODECFG , 0x00 }, 66 + { STB0899_IRQSTATUS_3 , 0xfe }, 67 + { STB0899_IRQSTATUS_2 , 0x03 }, 68 + { STB0899_IRQSTATUS_1 , 0x7c }, 69 + { STB0899_IRQSTATUS_0 , 0xf4 }, 70 + { STB0899_IRQMSK_3 , 0xf3 }, 71 + { STB0899_IRQMSK_2 , 0xfc }, 72 + { STB0899_IRQMSK_1 , 0xff }, 73 + { STB0899_IRQMSK_0 , 0xff }, 74 + { STB0899_IRQCFG , 0x00 }, 75 + { STB0899_I2CCFG , 0x88 }, 76 + { STB0899_I2CRPT , 0x58 }, 77 + { STB0899_IOPVALUE5 , 0x00 }, 78 + { STB0899_IOPVALUE4 , 0x33 }, 79 + { STB0899_IOPVALUE3 , 0x6d }, 80 + { STB0899_IOPVALUE2 , 0x90 }, 81 + { STB0899_IOPVALUE1 , 0x60 }, 82 + { STB0899_IOPVALUE0 , 0x00 }, 83 + { STB0899_GPIO00CFG , 0x82 }, 84 + { STB0899_GPIO01CFG , 0x82 }, 85 + { STB0899_GPIO02CFG , 0x82 }, 86 + { STB0899_GPIO03CFG , 0x82 }, 87 + { STB0899_GPIO04CFG , 0x82 }, 88 + { STB0899_GPIO05CFG , 0x82 }, 89 + { STB0899_GPIO06CFG , 0x82 }, 90 + { STB0899_GPIO07CFG , 0x82 }, 91 + { STB0899_GPIO08CFG , 0x82 }, 92 + { STB0899_GPIO09CFG , 0x82 }, 93 + { STB0899_GPIO10CFG , 0x82 }, 94 + { STB0899_GPIO11CFG , 0x82 }, 95 + { STB0899_GPIO12CFG , 0x82 }, 96 + { STB0899_GPIO13CFG , 0x82 }, 97 + { STB0899_GPIO14CFG , 0x82 }, 98 + { STB0899_GPIO15CFG , 0x82 }, 99 + { STB0899_GPIO16CFG , 0x82 }, 100 + { STB0899_GPIO17CFG , 0x82 }, 101 + { STB0899_GPIO18CFG , 0x82 }, 102 + { STB0899_GPIO19CFG , 0x82 }, 103 + { STB0899_GPIO20CFG , 0x82 }, 104 + { STB0899_SDATCFG , 0xb8 }, 105 + { STB0899_SCLTCFG , 0xba }, 106 + { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ 107 + { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ 108 + { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ 109 + { STB0899_DIRCLKCFG , 0x82 }, 110 + { STB0899_CLKOUT27CFG , 0x7e }, 111 + { STB0899_STDBYCFG , 0x82 }, 112 + { STB0899_CS0CFG , 0x82 }, 113 + { STB0899_CS1CFG , 0x82 }, 114 + { STB0899_DISEQCOCFG , 0x20 }, 115 + { STB0899_GPIO32CFG , 0x82 }, 116 + { STB0899_GPIO33CFG , 0x82 }, 117 + { STB0899_GPIO34CFG , 0x82 }, 118 + { STB0899_GPIO35CFG , 0x82 }, 119 + { STB0899_GPIO36CFG , 0x82 }, 120 + { STB0899_GPIO37CFG , 0x82 }, 121 + { STB0899_GPIO38CFG , 0x82 }, 122 + { STB0899_GPIO39CFG , 0x82 }, 123 + { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ 124 + { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ 125 + { STB0899_FILTCTRL , 0x00 }, 126 + { STB0899_SYSCTRL , 0x01 }, 127 + { STB0899_STOPCLK1 , 0x20 }, 128 + { STB0899_STOPCLK2 , 0x00 }, 129 + { STB0899_INTBUFSTATUS , 0x00 }, 130 + { STB0899_INTBUFCTRL , 0x0a }, 131 + { 0xffff , 0xff }, 132 + }; 133 + 134 + static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { 135 + { STB0899_DEMOD , 0x00 }, 136 + { STB0899_RCOMPC , 0xc9 }, 137 + { STB0899_AGC1CN , 0x01 }, 138 + { STB0899_AGC1REF , 0x10 }, 139 + { STB0899_RTC , 0x23 }, 140 + { STB0899_TMGCFG , 0x4e }, 141 + { STB0899_AGC2REF , 0x34 }, 142 + { STB0899_TLSR , 0x84 }, 143 + { STB0899_CFD , 0xf7 }, 144 + { STB0899_ACLC , 0x87 }, 145 + { STB0899_BCLC , 0x94 }, 146 + { STB0899_EQON , 0x41 }, 147 + { STB0899_LDT , 0xf1 }, 148 + { STB0899_LDT2 , 0xe3 }, 149 + { STB0899_EQUALREF , 0xb4 }, 150 + { STB0899_TMGRAMP , 0x10 }, 151 + { STB0899_TMGTHD , 0x30 }, 152 + { STB0899_IDCCOMP , 0xfd }, 153 + { STB0899_QDCCOMP , 0xff }, 154 + { STB0899_POWERI , 0x0c }, 155 + { STB0899_POWERQ , 0x0f }, 156 + { STB0899_RCOMP , 0x6c }, 157 + { STB0899_AGCIQIN , 0x80 }, 158 + { STB0899_AGC2I1 , 0x06 }, 159 + { STB0899_AGC2I2 , 0x00 }, 160 + { STB0899_TLIR , 0x30 }, 161 + { STB0899_RTF , 0x7f }, 162 + { STB0899_DSTATUS , 0x00 }, 163 + { STB0899_LDI , 0xbc }, 164 + { STB0899_CFRM , 0xea }, 165 + { STB0899_CFRL , 0x31 }, 166 + { STB0899_NIRM , 0x2b }, 167 + { STB0899_NIRL , 0x80 }, 168 + { STB0899_ISYMB , 0x1d }, 169 + { STB0899_QSYMB , 0xa6 }, 170 + { STB0899_SFRH , 0x2f }, 171 + { STB0899_SFRM , 0x68 }, 172 + { STB0899_SFRL , 0x40 }, 173 + { STB0899_SFRUPH , 0x2f }, 174 + { STB0899_SFRUPM , 0x68 }, 175 + { STB0899_SFRUPL , 0x40 }, 176 + { STB0899_EQUAI1 , 0x02 }, 177 + { STB0899_EQUAQ1 , 0xff }, 178 + { STB0899_EQUAI2 , 0x04 }, 179 + { STB0899_EQUAQ2 , 0x05 }, 180 + { STB0899_EQUAI3 , 0x02 }, 181 + { STB0899_EQUAQ3 , 0xfd }, 182 + { STB0899_EQUAI4 , 0x03 }, 183 + { STB0899_EQUAQ4 , 0x07 }, 184 + { STB0899_EQUAI5 , 0x08 }, 185 + { STB0899_EQUAQ5 , 0xf5 }, 186 + { STB0899_DSTATUS2 , 0x00 }, 187 + { STB0899_VSTATUS , 0x00 }, 188 + { STB0899_VERROR , 0x86 }, 189 + { STB0899_IQSWAP , 0x2a }, 190 + { STB0899_ECNT1M , 0x00 }, 191 + { STB0899_ECNT1L , 0x00 }, 192 + { STB0899_ECNT2M , 0x00 }, 193 + { STB0899_ECNT2L , 0x00 }, 194 + { STB0899_ECNT3M , 0x0a }, 195 + { STB0899_ECNT3L , 0xad }, 196 + { STB0899_FECAUTO1 , 0x06 }, 197 + { STB0899_FECM , 0x01 }, 198 + { STB0899_VTH12 , 0xb0 }, 199 + { STB0899_VTH23 , 0x7a }, 200 + { STB0899_VTH34 , 0x58 }, 201 + { STB0899_VTH56 , 0x38 }, 202 + { STB0899_VTH67 , 0x34 }, 203 + { STB0899_VTH78 , 0x24 }, 204 + { STB0899_PRVIT , 0xff }, 205 + { STB0899_VITSYNC , 0x19 }, 206 + { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ 207 + { STB0899_TSULC , 0x42 }, 208 + { STB0899_RSLLC , 0x41 }, 209 + { STB0899_TSLPL , 0x12 }, 210 + { STB0899_TSCFGH , 0x0c }, 211 + { STB0899_TSCFGM , 0x00 }, 212 + { STB0899_TSCFGL , 0x00 }, 213 + { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ 214 + { STB0899_RSSYNCDEL , 0x00 }, 215 + { STB0899_TSINHDELH , 0x02 }, 216 + { STB0899_TSINHDELM , 0x00 }, 217 + { STB0899_TSINHDELL , 0x00 }, 218 + { STB0899_TSLLSTKM , 0x1b }, 219 + { STB0899_TSLLSTKL , 0xb3 }, 220 + { STB0899_TSULSTKM , 0x00 }, 221 + { STB0899_TSULSTKL , 0x00 }, 222 + { STB0899_PCKLENUL , 0xbc }, 223 + { STB0899_PCKLENLL , 0xcc }, 224 + { STB0899_RSPCKLEN , 0xbd }, 225 + { STB0899_TSSTATUS , 0x90 }, 226 + { STB0899_ERRCTRL1 , 0xb6 }, 227 + { STB0899_ERRCTRL2 , 0x95 }, 228 + { STB0899_ERRCTRL3 , 0x8d }, 229 + { STB0899_DMONMSK1 , 0x27 }, 230 + { STB0899_DMONMSK0 , 0x03 }, 231 + { STB0899_DEMAPVIT , 0x5c }, 232 + { STB0899_PLPARM , 0x19 }, 233 + { STB0899_PDELCTRL , 0x48 }, 234 + { STB0899_PDELCTRL2 , 0x00 }, 235 + { STB0899_BBHCTRL1 , 0x00 }, 236 + { STB0899_BBHCTRL2 , 0x00 }, 237 + { STB0899_HYSTTHRESH , 0x77 }, 238 + { STB0899_MATCSTM , 0x00 }, 239 + { STB0899_MATCSTL , 0x00 }, 240 + { STB0899_UPLCSTM , 0x00 }, 241 + { STB0899_UPLCSTL , 0x00 }, 242 + { STB0899_DFLCSTM , 0x00 }, 243 + { STB0899_DFLCSTL , 0x00 }, 244 + { STB0899_SYNCCST , 0x00 }, 245 + { STB0899_SYNCDCSTM , 0x00 }, 246 + { STB0899_SYNCDCSTL , 0x00 }, 247 + { STB0899_ISI_ENTRY , 0x00 }, 248 + { STB0899_ISI_BIT_EN , 0x00 }, 249 + { STB0899_MATSTRM , 0xf0 }, 250 + { STB0899_MATSTRL , 0x02 }, 251 + { STB0899_UPLSTRM , 0x45 }, 252 + { STB0899_UPLSTRL , 0x60 }, 253 + { STB0899_DFLSTRM , 0xe3 }, 254 + { STB0899_DFLSTRL , 0x00 }, 255 + { STB0899_SYNCSTR , 0x47 }, 256 + { STB0899_SYNCDSTRM , 0x05 }, 257 + { STB0899_SYNCDSTRL , 0x18 }, 258 + { STB0899_CFGPDELSTATUS1 , 0x19 }, 259 + { STB0899_CFGPDELSTATUS2 , 0x2b }, 260 + { STB0899_BBFERRORM , 0x00 }, 261 + { STB0899_BBFERRORL , 0x01 }, 262 + { STB0899_UPKTERRORM , 0x00 }, 263 + { STB0899_UPKTERRORL , 0x00 }, 264 + { 0xffff , 0xff }, 265 + }; 266 + 267 + struct stb0899_config vp1041_stb0899_config = { 268 + .init_dev = vp1041_stb0899_s1_init_1, 269 + .init_s2_demod = stb0899_s2_init_2, 270 + .init_s1_demod = vp1041_stb0899_s1_init_3, 271 + .init_s2_fec = stb0899_s2_init_4, 272 + .init_tst = stb0899_s1_init_5, 273 + 274 + .demod_address = 0x68, /* 0xd0 >> 1 */ 275 + 276 + .xtal_freq = 27000000, 277 + .inversion = IQ_SWAP_ON, /* 1 */ 278 + 279 + .lo_clk = 76500000, 280 + .hi_clk = 99000000, 281 + 282 + .esno_ave = STB0899_DVBS2_ESNO_AVE, 283 + .esno_quant = STB0899_DVBS2_ESNO_QUANT, 284 + .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, 285 + .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, 286 + .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, 287 + .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, 288 + .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, 289 + .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, 290 + .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, 291 + 292 + .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, 293 + .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, 294 + .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, 295 + .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, 296 + 297 + .tuner_get_frequency = stb6100_get_frequency, 298 + .tuner_set_frequency = stb6100_set_frequency, 299 + .tuner_set_bandwidth = stb6100_set_bandwidth, 300 + .tuner_get_bandwidth = stb6100_get_bandwidth, 301 + .tuner_set_rfsiggain = NULL, 302 + }; 303 + 304 + struct stb6100_config vp1041_stb6100_config = { 305 + .tuner_address = 0x60, 306 + .refclock = 27000000, 307 + }; 308 + 309 + static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 310 + { 311 + struct i2c_adapter *adapter = &mantis->adapter; 312 + 313 + int err = 0; 314 + 315 + err = mantis_frontend_power(mantis, POWER_ON); 316 + if (err == 0) { 317 + mantis_frontend_soft_reset(mantis); 318 + msleep(250); 319 + mantis->fe = stb0899_attach(&vp1041_stb0899_config, adapter); 320 + if (mantis->fe) { 321 + dprintk(MANTIS_ERROR, 1, 322 + "found STB0899 DVB-S/DVB-S2 frontend @0x%02x", 323 + vp1041_stb0899_config.demod_address); 324 + 325 + if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, adapter)) { 326 + if (!lnbp21_attach(mantis->fe, adapter, 0, 0)) 327 + dprintk(MANTIS_ERROR, 1, "No LNBP21 found!"); 328 + } 329 + } else { 330 + return -EREMOTEIO; 331 + } 332 + } else { 333 + dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", 334 + adapter->name, 335 + err); 336 + 337 + return -EIO; 338 + } 339 + 340 + 341 + dprintk(MANTIS_ERROR, 1, "Done!"); 342 + 343 + return 0; 344 + } 345 + 346 + struct mantis_hwconfig vp1041_config = { 347 + .model_name = MANTIS_MODEL_NAME, 348 + .dev_type = MANTIS_DEV_TYPE, 349 + .ts_size = MANTIS_TS_188, 350 + 351 + .baud_rate = MANTIS_BAUD_9600, 352 + .parity = MANTIS_PARITY_NONE, 353 + .bytes = 0, 354 + 355 + .frontend_init = vp1041_frontend_init, 356 + .power = GPIF_A12, 357 + .reset = GPIF_A13, 358 + };
+33
drivers/media/dvb/mantis/mantis_vp1041.h
··· 1 + /* 2 + Mantis VP-1041 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP1041_H 22 + #define __MANTIS_VP1041_H 23 + 24 + #include "mantis_common.h" 25 + 26 + #define MANTIS_VP_1041_DVB_S2 0x0031 27 + #define SKYSTAR_HD2_10 0x0001 28 + #define SKYSTAR_HD2_20 0x0003 29 + #define CINERGY_S2_PCI_HD 0x1179 30 + 31 + extern struct mantis_hwconfig vp1041_config; 32 + 33 + #endif /* __MANTIS_VP1041_H */
+187
drivers/media/dvb/mantis/mantis_vp2033.c
··· 1 + /* 2 + Mantis VP-2033 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "tda1002x.h" 32 + #include "mantis_common.h" 33 + #include "mantis_ioc.h" 34 + #include "mantis_dvb.h" 35 + #include "mantis_vp2033.h" 36 + 37 + #define MANTIS_MODEL_NAME "VP-2033" 38 + #define MANTIS_DEV_TYPE "DVB-C" 39 + 40 + struct tda1002x_config vp2033_tda1002x_cu1216_config = { 41 + .demod_address = 0x18 >> 1, 42 + .invert = 1, 43 + }; 44 + 45 + struct tda10023_config vp2033_tda10023_cu1216_config = { 46 + .demod_address = 0x18 >> 1, 47 + .invert = 1, 48 + }; 49 + 50 + static u8 read_pwm(struct mantis_pci *mantis) 51 + { 52 + struct i2c_adapter *adapter = &mantis->adapter; 53 + 54 + u8 b = 0xff; 55 + u8 pwm; 56 + struct i2c_msg msg[] = { 57 + {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, 58 + {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} 59 + }; 60 + 61 + if ((i2c_transfer(adapter, msg, 2) != 2) 62 + || (pwm == 0xff)) 63 + pwm = 0x48; 64 + 65 + return pwm; 66 + } 67 + 68 + static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 69 + { 70 + struct mantis_pci *mantis = fe->dvb->priv; 71 + struct i2c_adapter *adapter = &mantis->adapter; 72 + 73 + u8 buf[6]; 74 + struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; 75 + int i; 76 + 77 + #define CU1216_IF 36125000 78 + #define TUNER_MUL 62500 79 + 80 + u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; 81 + 82 + buf[0] = (div >> 8) & 0x7f; 83 + buf[1] = div & 0xff; 84 + buf[2] = 0xce; 85 + buf[3] = (params->frequency < 150000000 ? 0x01 : 86 + params->frequency < 445000000 ? 0x02 : 0x04); 87 + buf[4] = 0xde; 88 + buf[5] = 0x20; 89 + 90 + if (fe->ops.i2c_gate_ctrl) 91 + fe->ops.i2c_gate_ctrl(fe, 1); 92 + 93 + if (i2c_transfer(adapter, &msg, 1) != 1) 94 + return -EIO; 95 + 96 + /* wait for the pll lock */ 97 + msg.flags = I2C_M_RD; 98 + msg.len = 1; 99 + for (i = 0; i < 20; i++) { 100 + if (fe->ops.i2c_gate_ctrl) 101 + fe->ops.i2c_gate_ctrl(fe, 1); 102 + 103 + if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) 104 + break; 105 + 106 + msleep(10); 107 + } 108 + 109 + /* switch the charge pump to the lower current */ 110 + msg.flags = 0; 111 + msg.len = 2; 112 + msg.buf = &buf[2]; 113 + buf[2] &= ~0x40; 114 + if (fe->ops.i2c_gate_ctrl) 115 + fe->ops.i2c_gate_ctrl(fe, 1); 116 + 117 + if (i2c_transfer(adapter, &msg, 1) != 1) 118 + return -EIO; 119 + 120 + return 0; 121 + } 122 + 123 + static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 124 + { 125 + struct i2c_adapter *adapter = &mantis->adapter; 126 + 127 + int err = 0; 128 + 129 + err = mantis_frontend_power(mantis, POWER_ON); 130 + if (err == 0) { 131 + mantis_frontend_soft_reset(mantis); 132 + msleep(250); 133 + 134 + dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); 135 + fe = tda10021_attach(&vp2033_tda1002x_cu1216_config, 136 + adapter, 137 + read_pwm(mantis)); 138 + 139 + if (fe) { 140 + dprintk(MANTIS_ERROR, 1, 141 + "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", 142 + vp2033_tda1002x_cu1216_config.demod_address); 143 + } else { 144 + fe = tda10023_attach(&vp2033_tda10023_cu1216_config, 145 + adapter, 146 + read_pwm(mantis)); 147 + 148 + if (fe) { 149 + dprintk(MANTIS_ERROR, 1, 150 + "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", 151 + vp2033_tda1002x_cu1216_config.demod_address); 152 + } 153 + } 154 + 155 + if (fe) { 156 + fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; 157 + dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); 158 + } else { 159 + return -1; 160 + } 161 + } else { 162 + dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", 163 + adapter->name, 164 + err); 165 + 166 + return -EIO; 167 + } 168 + 169 + mantis->fe = fe; 170 + dprintk(MANTIS_DEBUG, 1, "Done!"); 171 + 172 + return 0; 173 + } 174 + 175 + struct mantis_hwconfig vp2033_config = { 176 + .model_name = MANTIS_MODEL_NAME, 177 + .dev_type = MANTIS_DEV_TYPE, 178 + .ts_size = MANTIS_TS_204, 179 + 180 + .baud_rate = MANTIS_BAUD_9600, 181 + .parity = MANTIS_PARITY_NONE, 182 + .bytes = 0, 183 + 184 + .frontend_init = vp2033_frontend_init, 185 + .power = GPIF_A12, 186 + .reset = GPIF_A13, 187 + };
+30
drivers/media/dvb/mantis/mantis_vp2033.h
··· 1 + /* 2 + Mantis VP-2033 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP2033_H 22 + #define __MANTIS_VP2033_H 23 + 24 + #include "mantis_common.h" 25 + 26 + #define MANTIS_VP_2033_DVB_C 0x0008 27 + 28 + extern struct mantis_hwconfig vp2033_config; 29 + 30 + #endif /* __MANTIS_VP2033_H */
+186
drivers/media/dvb/mantis/mantis_vp2040.c
··· 1 + /* 2 + Mantis VP-2040 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "tda1002x.h" 32 + #include "mantis_common.h" 33 + #include "mantis_ioc.h" 34 + #include "mantis_dvb.h" 35 + #include "mantis_vp2040.h" 36 + 37 + #define MANTIS_MODEL_NAME "VP-2040" 38 + #define MANTIS_DEV_TYPE "DVB-C" 39 + 40 + struct tda1002x_config vp2040_tda1002x_cu1216_config = { 41 + .demod_address = 0x18 >> 1, 42 + .invert = 1, 43 + }; 44 + 45 + struct tda10023_config vp2040_tda10023_cu1216_config = { 46 + .demod_address = 0x18 >> 1, 47 + .invert = 1, 48 + }; 49 + 50 + static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 51 + { 52 + struct mantis_pci *mantis = fe->dvb->priv; 53 + struct i2c_adapter *adapter = &mantis->adapter; 54 + 55 + u8 buf[6]; 56 + struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; 57 + int i; 58 + 59 + #define CU1216_IF 36125000 60 + #define TUNER_MUL 62500 61 + 62 + u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; 63 + 64 + buf[0] = (div >> 8) & 0x7f; 65 + buf[1] = div & 0xff; 66 + buf[2] = 0xce; 67 + buf[3] = (params->frequency < 150000000 ? 0x01 : 68 + params->frequency < 445000000 ? 0x02 : 0x04); 69 + buf[4] = 0xde; 70 + buf[5] = 0x20; 71 + 72 + if (fe->ops.i2c_gate_ctrl) 73 + fe->ops.i2c_gate_ctrl(fe, 1); 74 + 75 + if (i2c_transfer(adapter, &msg, 1) != 1) 76 + return -EIO; 77 + 78 + /* wait for the pll lock */ 79 + msg.flags = I2C_M_RD; 80 + msg.len = 1; 81 + for (i = 0; i < 20; i++) { 82 + if (fe->ops.i2c_gate_ctrl) 83 + fe->ops.i2c_gate_ctrl(fe, 1); 84 + 85 + if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) 86 + break; 87 + 88 + msleep(10); 89 + } 90 + 91 + /* switch the charge pump to the lower current */ 92 + msg.flags = 0; 93 + msg.len = 2; 94 + msg.buf = &buf[2]; 95 + buf[2] &= ~0x40; 96 + if (fe->ops.i2c_gate_ctrl) 97 + fe->ops.i2c_gate_ctrl(fe, 1); 98 + 99 + if (i2c_transfer(adapter, &msg, 1) != 1) 100 + return -EIO; 101 + 102 + return 0; 103 + } 104 + 105 + static u8 read_pwm(struct mantis_pci *mantis) 106 + { 107 + struct i2c_adapter *adapter = &mantis->adapter; 108 + 109 + u8 b = 0xff; 110 + u8 pwm; 111 + struct i2c_msg msg[] = { 112 + {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, 113 + {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} 114 + }; 115 + 116 + if ((i2c_transfer(adapter, msg, 2) != 2) 117 + || (pwm == 0xff)) 118 + pwm = 0x48; 119 + 120 + return pwm; 121 + } 122 + 123 + static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 124 + { 125 + struct i2c_adapter *adapter = &mantis->adapter; 126 + 127 + int err = 0; 128 + 129 + err = mantis_frontend_power(mantis, POWER_ON); 130 + if (err == 0) { 131 + mantis_frontend_soft_reset(mantis); 132 + msleep(250); 133 + 134 + dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); 135 + fe = tda10021_attach(&vp2040_tda1002x_cu1216_config, 136 + adapter, 137 + read_pwm(mantis)); 138 + 139 + if (fe) { 140 + dprintk(MANTIS_ERROR, 1, 141 + "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", 142 + vp2040_tda1002x_cu1216_config.demod_address); 143 + } else { 144 + fe = tda10023_attach(&vp2040_tda10023_cu1216_config, 145 + adapter, 146 + read_pwm(mantis)); 147 + 148 + if (fe) { 149 + dprintk(MANTIS_ERROR, 1, 150 + "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", 151 + vp2040_tda1002x_cu1216_config.demod_address); 152 + } 153 + } 154 + 155 + if (fe) { 156 + fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; 157 + dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); 158 + } else { 159 + return -1; 160 + } 161 + } else { 162 + dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", 163 + adapter->name, 164 + err); 165 + 166 + return -EIO; 167 + } 168 + mantis->fe = fe; 169 + dprintk(MANTIS_DEBUG, 1, "Done!"); 170 + 171 + return 0; 172 + } 173 + 174 + struct mantis_hwconfig vp2040_config = { 175 + .model_name = MANTIS_MODEL_NAME, 176 + .dev_type = MANTIS_DEV_TYPE, 177 + .ts_size = MANTIS_TS_204, 178 + 179 + .baud_rate = MANTIS_BAUD_9600, 180 + .parity = MANTIS_PARITY_NONE, 181 + .bytes = 0, 182 + 183 + .frontend_init = vp2040_frontend_init, 184 + .power = GPIF_A12, 185 + .reset = GPIF_A13, 186 + };
+32
drivers/media/dvb/mantis/mantis_vp2040.h
··· 1 + /* 2 + Mantis VP-2040 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP2040_H 22 + #define __MANTIS_VP2040_H 23 + 24 + #include "mantis_common.h" 25 + 26 + #define MANTIS_VP_2040_DVB_C 0x0043 27 + #define CINERGY_C 0x1178 28 + #define CABLESTAR_HD2 0x0002 29 + 30 + extern struct mantis_hwconfig vp2040_config; 31 + 32 + #endif /* __MANTIS_VP2040_H */
+38
drivers/media/dvb/mantis/mantis_vp3028.c
··· 1 + /* 2 + Mantis VP-3028 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include "mantis_common.h" 22 + #include "mantis_vp3028.h" 23 + 24 + struct zl10353_config mantis_vp3028_config = { 25 + .demod_address = 0x0f, 26 + }; 27 + 28 + #define MANTIS_MODEL_NAME "VP-3028" 29 + #define MANTIS_DEV_TYPE "DVB-T" 30 + 31 + struct mantis_hwconfig vp3028_mantis_config = { 32 + .model_name = MANTIS_MODEL_NAME, 33 + .dev_type = MANTIS_DEV_TYPE, 34 + .ts_size = MANTIS_TS_188, 35 + .baud_rate = MANTIS_BAUD_9600, 36 + .parity = MANTIS_PARITY_NONE, 37 + .bytes = 0, 38 + };
+33
drivers/media/dvb/mantis/mantis_vp3028.h
··· 1 + /* 2 + Mantis VP-3028 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP3028_H 22 + #define __MANTIS_VP3028_H 23 + 24 + #include "dvb_frontend.h" 25 + #include "mantis_common.h" 26 + #include "zl10353.h" 27 + 28 + #define MANTIS_VP_3028_DVB_T 0x0028 29 + 30 + extern struct zl10353_config mantis_vp3028_config; 31 + extern struct mantis_hwconfig vp3028_mantis_config; 32 + 33 + #endif /* __MANTIS_VP3028_H */
+105
drivers/media/dvb/mantis/mantis_vp3030.c
··· 1 + /* 2 + Mantis VP-3030 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/signal.h> 22 + #include <linux/sched.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include "dmxdev.h" 26 + #include "dvbdev.h" 27 + #include "dvb_demux.h" 28 + #include "dvb_frontend.h" 29 + #include "dvb_net.h" 30 + 31 + #include "zl10353.h" 32 + #include "tda665x.h" 33 + #include "mantis_common.h" 34 + #include "mantis_ioc.h" 35 + #include "mantis_dvb.h" 36 + #include "mantis_vp3030.h" 37 + 38 + struct zl10353_config mantis_vp3030_config = { 39 + .demod_address = 0x0f, 40 + }; 41 + 42 + struct tda665x_config env57h12d5_config = { 43 + .name = "ENV57H12D5 (ET-50DT)", 44 + .addr = 0x60, 45 + .frequency_min = 47000000, 46 + .frequency_max = 862000000, 47 + .frequency_offst = 3616667, 48 + .ref_multiplier = 6, /* 1/6 MHz */ 49 + .ref_divider = 100000, /* 1/6 MHz */ 50 + }; 51 + 52 + #define MANTIS_MODEL_NAME "VP-3030" 53 + #define MANTIS_DEV_TYPE "DVB-T" 54 + 55 + 56 + static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) 57 + { 58 + struct i2c_adapter *adapter = &mantis->adapter; 59 + struct mantis_hwconfig *config = mantis->hwconfig; 60 + int err = 0; 61 + 62 + gpio_set_bits(mantis, config->reset, 0); 63 + msleep(100); 64 + err = mantis_frontend_power(mantis, POWER_ON); 65 + msleep(100); 66 + gpio_set_bits(mantis, config->reset, 1); 67 + 68 + if (err == 0) { 69 + msleep(250); 70 + dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); 71 + fe = zl10353_attach(&mantis_vp3030_config, adapter); 72 + 73 + if (!fe) 74 + return -1; 75 + 76 + tda665x_attach(fe, &env57h12d5_config, adapter); 77 + } else { 78 + dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", 79 + adapter->name, 80 + err); 81 + 82 + return -EIO; 83 + 84 + } 85 + mantis->fe = fe; 86 + dprintk(MANTIS_ERROR, 1, "Done!"); 87 + 88 + return 0; 89 + } 90 + 91 + struct mantis_hwconfig vp3030_config = { 92 + .model_name = MANTIS_MODEL_NAME, 93 + .dev_type = MANTIS_DEV_TYPE, 94 + .ts_size = MANTIS_TS_188, 95 + 96 + .baud_rate = MANTIS_BAUD_9600, 97 + .parity = MANTIS_PARITY_NONE, 98 + .bytes = 0, 99 + 100 + .frontend_init = vp3030_frontend_init, 101 + .power = GPIF_A12, 102 + .reset = GPIF_A13, 103 + 104 + .i2c_mode = MANTIS_BYTE_MODE 105 + };
+30
drivers/media/dvb/mantis/mantis_vp3030.h
··· 1 + /* 2 + Mantis VP-3030 driver 3 + 4 + Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef __MANTIS_VP3030_H 22 + #define __MANTIS_VP3030_H 23 + 24 + #include "mantis_common.h" 25 + 26 + #define MANTIS_VP_3030_DVB_T 0x0024 27 + 28 + extern struct mantis_hwconfig vp3030_config; 29 + 30 + #endif /* __MANTIS_VP3030_H */