0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0020
0021 #include "budget.h"
0022 #include "stv0299.h"
0023 #include "stb0899_drv.h"
0024 #include "stb0899_reg.h"
0025 #include "stb0899_cfg.h"
0026 #include "tda8261.h"
0027 #include "tda8261_cfg.h"
0028 #include "tda1002x.h"
0029 #include "tda1004x.h"
0030 #include "tua6100.h"
0031 #include "dvb-pll.h"
0032 #include <media/drv-intf/saa7146_vv.h>
0033 #include <linux/module.h>
0034 #include <linux/errno.h>
0035 #include <linux/slab.h>
0036 #include <linux/interrupt.h>
0037 #include <linux/input.h>
0038 #include <linux/spinlock.h>
0039
0040 #include <media/dvb_ca_en50221.h>
0041
0042 #define DEBICICAM 0x02420000
0043
0044 #define SLOTSTATUS_NONE 1
0045 #define SLOTSTATUS_PRESENT 2
0046 #define SLOTSTATUS_RESET 4
0047 #define SLOTSTATUS_READY 8
0048 #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
0049
0050 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
0051
0052 struct budget_av {
0053 struct budget budget;
0054 struct video_device vd;
0055 int cur_input;
0056 int has_saa7113;
0057 struct tasklet_struct ciintf_irq_tasklet;
0058 int slot_status;
0059 struct dvb_ca_en50221 ca;
0060 u8 reinitialise_demod:1;
0061 };
0062
0063 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
0078 {
0079 u8 mm1[] = { 0x00 };
0080 u8 mm2[] = { 0x00 };
0081 struct i2c_msg msgs[2];
0082
0083 msgs[0].flags = 0;
0084 msgs[1].flags = I2C_M_RD;
0085 msgs[0].addr = msgs[1].addr = id / 2;
0086 mm1[0] = reg;
0087 msgs[0].len = 1;
0088 msgs[1].len = 1;
0089 msgs[0].buf = mm1;
0090 msgs[1].buf = mm2;
0091
0092 i2c_transfer(i2c, msgs, 2);
0093
0094 return mm2[0];
0095 }
0096
0097 static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
0098 {
0099 u8 mm1[] = { reg };
0100 struct i2c_msg msgs[2] = {
0101 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
0102 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
0103 };
0104
0105 if (i2c_transfer(i2c, msgs, 2) != 2)
0106 return -EIO;
0107
0108 return 0;
0109 }
0110
0111 static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
0112 {
0113 u8 msg[2] = { reg, val };
0114 struct i2c_msg msgs;
0115
0116 msgs.flags = 0;
0117 msgs.addr = id / 2;
0118 msgs.len = 2;
0119 msgs.buf = msg;
0120 return i2c_transfer(i2c, &msgs, 1);
0121 }
0122
0123 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
0124 {
0125 struct budget_av *budget_av = (struct budget_av *) ca->data;
0126 int result;
0127
0128 if (slot != 0)
0129 return -EINVAL;
0130
0131 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
0132 udelay(1);
0133
0134 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
0135 if (result == -ETIMEDOUT) {
0136 ciintf_slot_shutdown(ca, slot);
0137 pr_info("cam ejected 1\n");
0138 }
0139 return result;
0140 }
0141
0142 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
0143 {
0144 struct budget_av *budget_av = (struct budget_av *) ca->data;
0145 int result;
0146
0147 if (slot != 0)
0148 return -EINVAL;
0149
0150 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
0151 udelay(1);
0152
0153 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
0154 if (result == -ETIMEDOUT) {
0155 ciintf_slot_shutdown(ca, slot);
0156 pr_info("cam ejected 2\n");
0157 }
0158 return result;
0159 }
0160
0161 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
0162 {
0163 struct budget_av *budget_av = (struct budget_av *) ca->data;
0164 int result;
0165
0166 if (slot != 0)
0167 return -EINVAL;
0168
0169 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
0170 udelay(1);
0171
0172 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
0173 if (result == -ETIMEDOUT) {
0174 ciintf_slot_shutdown(ca, slot);
0175 pr_info("cam ejected 3\n");
0176 return -ETIMEDOUT;
0177 }
0178 return result;
0179 }
0180
0181 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
0182 {
0183 struct budget_av *budget_av = (struct budget_av *) ca->data;
0184 int result;
0185
0186 if (slot != 0)
0187 return -EINVAL;
0188
0189 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
0190 udelay(1);
0191
0192 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
0193 if (result == -ETIMEDOUT) {
0194 ciintf_slot_shutdown(ca, slot);
0195 pr_info("cam ejected 5\n");
0196 }
0197 return result;
0198 }
0199
0200 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
0201 {
0202 struct budget_av *budget_av = (struct budget_av *) ca->data;
0203 struct saa7146_dev *saa = budget_av->budget.dev;
0204
0205 if (slot != 0)
0206 return -EINVAL;
0207
0208 dprintk(1, "ciintf_slot_reset\n");
0209 budget_av->slot_status = SLOTSTATUS_RESET;
0210
0211 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI);
0212
0213 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
0214 msleep(2);
0215 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
0216 msleep(20);
0217
0218 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
0219 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
0220 msleep(20);
0221
0222
0223 if (budget_av->reinitialise_demod)
0224 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
0225
0226 return 0;
0227 }
0228
0229 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
0230 {
0231 struct budget_av *budget_av = (struct budget_av *) ca->data;
0232 struct saa7146_dev *saa = budget_av->budget.dev;
0233
0234 if (slot != 0)
0235 return -EINVAL;
0236
0237 dprintk(1, "ciintf_slot_shutdown\n");
0238
0239 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
0240 budget_av->slot_status = SLOTSTATUS_NONE;
0241
0242 return 0;
0243 }
0244
0245 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
0246 {
0247 struct budget_av *budget_av = (struct budget_av *) ca->data;
0248 struct saa7146_dev *saa = budget_av->budget.dev;
0249
0250 if (slot != 0)
0251 return -EINVAL;
0252
0253 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
0254
0255 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
0256
0257 return 0;
0258 }
0259
0260 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
0261 {
0262 struct budget_av *budget_av = (struct budget_av *) ca->data;
0263 struct saa7146_dev *saa = budget_av->budget.dev;
0264 int result;
0265
0266 if (slot != 0)
0267 return -EINVAL;
0268
0269
0270
0271 if (budget_av->slot_status == SLOTSTATUS_NONE) {
0272 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
0273 udelay(1);
0274 if (saa7146_read(saa, PSR) & MASK_06) {
0275 if (budget_av->slot_status == SLOTSTATUS_NONE) {
0276 budget_av->slot_status = SLOTSTATUS_PRESENT;
0277 pr_info("cam inserted A\n");
0278 }
0279 }
0280 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
0281 }
0282
0283
0284
0285
0286
0287
0288
0289 if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
0290 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
0291 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
0292 if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
0293 budget_av->slot_status = SLOTSTATUS_PRESENT;
0294 pr_info("cam inserted B\n");
0295 } else if (result < 0) {
0296 if (budget_av->slot_status != SLOTSTATUS_NONE) {
0297 ciintf_slot_shutdown(ca, slot);
0298 pr_info("cam ejected 5\n");
0299 return 0;
0300 }
0301 }
0302 }
0303
0304
0305 if (budget_av->slot_status == SLOTSTATUS_RESET) {
0306 result = ciintf_read_attribute_mem(ca, slot, 0);
0307 if (result == 0x1d) {
0308 budget_av->slot_status = SLOTSTATUS_READY;
0309 }
0310 }
0311
0312
0313 if (budget_av->slot_status != SLOTSTATUS_NONE) {
0314 if (budget_av->slot_status & SLOTSTATUS_READY) {
0315 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
0316 }
0317 return DVB_CA_EN50221_POLL_CAM_PRESENT;
0318 }
0319 return 0;
0320 }
0321
0322 static int ciintf_init(struct budget_av *budget_av)
0323 {
0324 struct saa7146_dev *saa = budget_av->budget.dev;
0325 int result;
0326
0327 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
0328
0329 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
0330 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
0331 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
0332 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
0333
0334
0335 saa7146_write(saa, MC1, MASK_27 | MASK_11);
0336
0337
0338 budget_av->ca.owner = THIS_MODULE;
0339 budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
0340 budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
0341 budget_av->ca.read_cam_control = ciintf_read_cam_control;
0342 budget_av->ca.write_cam_control = ciintf_write_cam_control;
0343 budget_av->ca.slot_reset = ciintf_slot_reset;
0344 budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
0345 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
0346 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
0347 budget_av->ca.data = budget_av;
0348 budget_av->budget.ci_present = 1;
0349 budget_av->slot_status = SLOTSTATUS_NONE;
0350
0351 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
0352 &budget_av->ca, 0, 1)) != 0) {
0353 pr_err("ci initialisation failed\n");
0354 goto error;
0355 }
0356
0357 pr_info("ci interface initialised\n");
0358 return 0;
0359
0360 error:
0361 saa7146_write(saa, MC1, MASK_27);
0362 return result;
0363 }
0364
0365 static void ciintf_deinit(struct budget_av *budget_av)
0366 {
0367 struct saa7146_dev *saa = budget_av->budget.dev;
0368
0369 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
0370 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
0371 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
0372 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
0373
0374
0375 dvb_ca_en50221_release(&budget_av->ca);
0376
0377
0378 saa7146_write(saa, MC1, MASK_27);
0379 }
0380
0381
0382 static const u8 saa7113_tab[] = {
0383 0x01, 0x08,
0384 0x02, 0xc0,
0385 0x03, 0x33,
0386 0x04, 0x00,
0387 0x05, 0x00,
0388 0x06, 0xeb,
0389 0x07, 0xe0,
0390 0x08, 0x28,
0391 0x09, 0x00,
0392 0x0a, 0x80,
0393 0x0b, 0x47,
0394 0x0c, 0x40,
0395 0x0d, 0x00,
0396 0x0e, 0x01,
0397 0x0f, 0x44,
0398
0399 0x10, 0x08,
0400 0x11, 0x0c,
0401 0x12, 0x7b,
0402 0x13, 0x00,
0403 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
0404
0405 0x57, 0xff,
0406 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
0407 0x5b, 0x83, 0x5e, 0x00,
0408 0xff
0409 };
0410
0411 static int saa7113_init(struct budget_av *budget_av)
0412 {
0413 struct budget *budget = &budget_av->budget;
0414 struct saa7146_dev *saa = budget->dev;
0415 const u8 *data = saa7113_tab;
0416
0417 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
0418 msleep(200);
0419
0420 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
0421 dprintk(1, "saa7113 not found on KNC card\n");
0422 return -ENODEV;
0423 }
0424
0425 dprintk(1, "saa7113 detected and initializing\n");
0426
0427 while (*data != 0xff) {
0428 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
0429 data += 2;
0430 }
0431
0432 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
0433
0434 return 0;
0435 }
0436
0437 static int saa7113_setinput(struct budget_av *budget_av, int input)
0438 {
0439 struct budget *budget = &budget_av->budget;
0440
0441 if (1 != budget_av->has_saa7113)
0442 return -ENODEV;
0443
0444 if (input == 1) {
0445 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
0446 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
0447 } else if (input == 0) {
0448 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
0449 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
0450 } else
0451 return -EINVAL;
0452
0453 budget_av->cur_input = input;
0454 return 0;
0455 }
0456
0457
0458 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
0459 {
0460 u8 aclk = 0;
0461 u8 bclk = 0;
0462 u8 m1;
0463
0464 aclk = 0xb5;
0465 if (srate < 2000000)
0466 bclk = 0x86;
0467 else if (srate < 5000000)
0468 bclk = 0x89;
0469 else if (srate < 15000000)
0470 bclk = 0x8f;
0471 else if (srate < 45000000)
0472 bclk = 0x95;
0473
0474 m1 = 0x14;
0475 if (srate < 4000000)
0476 m1 = 0x10;
0477
0478 stv0299_writereg(fe, 0x13, aclk);
0479 stv0299_writereg(fe, 0x14, bclk);
0480 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
0481 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
0482 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
0483 stv0299_writereg(fe, 0x0f, 0x80 | m1);
0484
0485 return 0;
0486 }
0487
0488 static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe)
0489 {
0490 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0491 u32 div;
0492 u8 buf[4];
0493 struct budget *budget = (struct budget *) fe->dvb->priv;
0494 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
0495
0496 if ((c->frequency < 950000) || (c->frequency > 2150000))
0497 return -EINVAL;
0498
0499 div = (c->frequency + (125 - 1)) / 125;
0500 buf[0] = (div >> 8) & 0x7f;
0501 buf[1] = div & 0xff;
0502 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
0503 buf[3] = 0x20;
0504
0505 if (c->symbol_rate < 4000000)
0506 buf[3] |= 1;
0507
0508 if (c->frequency < 1250000)
0509 buf[3] |= 0;
0510 else if (c->frequency < 1550000)
0511 buf[3] |= 0x40;
0512 else if (c->frequency < 2050000)
0513 buf[3] |= 0x80;
0514 else if (c->frequency < 2150000)
0515 buf[3] |= 0xC0;
0516
0517 if (fe->ops.i2c_gate_ctrl)
0518 fe->ops.i2c_gate_ctrl(fe, 1);
0519 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
0520 return -EIO;
0521 return 0;
0522 }
0523
0524 static u8 typhoon_cinergy1200s_inittab[] = {
0525 0x01, 0x15,
0526 0x02, 0x30,
0527 0x03, 0x00,
0528 0x04, 0x7d,
0529 0x05, 0x35,
0530 0x06, 0x40,
0531 0x07, 0x00,
0532 0x08, 0x40,
0533 0x09, 0x00,
0534 0x0c, 0x51,
0535 0x0d, 0x82,
0536 0x0e, 0x23,
0537 0x10, 0x3f,
0538 0x11, 0x84,
0539 0x12, 0xb9,
0540 0x15, 0xc9,
0541 0x16, 0x00,
0542 0x17, 0x00,
0543 0x18, 0x00,
0544 0x19, 0x00,
0545 0x1a, 0x00,
0546 0x1f, 0x50,
0547 0x20, 0x00,
0548 0x21, 0x00,
0549 0x22, 0x00,
0550 0x23, 0x00,
0551 0x28, 0x00,
0552 0x29, 0x1e,
0553 0x2a, 0x14,
0554 0x2b, 0x0f,
0555 0x2c, 0x09,
0556 0x2d, 0x05,
0557 0x2e, 0x01,
0558 0x31, 0x1f,
0559 0x32, 0x19,
0560 0x33, 0xfc,
0561 0x34, 0x93,
0562 0x0f, 0x92,
0563 0xff, 0xff
0564 };
0565
0566 static const struct stv0299_config typhoon_config = {
0567 .demod_address = 0x68,
0568 .inittab = typhoon_cinergy1200s_inittab,
0569 .mclk = 88000000UL,
0570 .invert = 0,
0571 .skip_reinit = 0,
0572 .lock_output = STV0299_LOCKOUTPUT_1,
0573 .volt13_op0_op1 = STV0299_VOLT13_OP0,
0574 .min_delay_ms = 100,
0575 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
0576 };
0577
0578
0579 static const struct stv0299_config cinergy_1200s_config = {
0580 .demod_address = 0x68,
0581 .inittab = typhoon_cinergy1200s_inittab,
0582 .mclk = 88000000UL,
0583 .invert = 0,
0584 .skip_reinit = 0,
0585 .lock_output = STV0299_LOCKOUTPUT_0,
0586 .volt13_op0_op1 = STV0299_VOLT13_OP0,
0587 .min_delay_ms = 100,
0588 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
0589 };
0590
0591 static const struct stv0299_config cinergy_1200s_1894_0010_config = {
0592 .demod_address = 0x68,
0593 .inittab = typhoon_cinergy1200s_inittab,
0594 .mclk = 88000000UL,
0595 .invert = 1,
0596 .skip_reinit = 0,
0597 .lock_output = STV0299_LOCKOUTPUT_1,
0598 .volt13_op0_op1 = STV0299_VOLT13_OP0,
0599 .min_delay_ms = 100,
0600 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
0601 };
0602
0603 static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe)
0604 {
0605 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0606 struct budget *budget = (struct budget *) fe->dvb->priv;
0607 u8 buf[6];
0608 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
0609 int i;
0610
0611 #define CU1216_IF 36125000
0612 #define TUNER_MUL 62500
0613
0614 u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
0615
0616 buf[0] = (div >> 8) & 0x7f;
0617 buf[1] = div & 0xff;
0618 buf[2] = 0xce;
0619 buf[3] = (c->frequency < 150000000 ? 0x01 :
0620 c->frequency < 445000000 ? 0x02 : 0x04);
0621 buf[4] = 0xde;
0622 buf[5] = 0x20;
0623
0624 if (fe->ops.i2c_gate_ctrl)
0625 fe->ops.i2c_gate_ctrl(fe, 1);
0626 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
0627 return -EIO;
0628
0629
0630 msg.flags = I2C_M_RD;
0631 msg.len = 1;
0632 for (i = 0; i < 20; i++) {
0633 if (fe->ops.i2c_gate_ctrl)
0634 fe->ops.i2c_gate_ctrl(fe, 1);
0635 if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
0636 break;
0637 msleep(10);
0638 }
0639
0640
0641 msg.flags = 0;
0642 msg.len = 2;
0643 msg.buf = &buf[2];
0644 buf[2] &= ~0x40;
0645 if (fe->ops.i2c_gate_ctrl)
0646 fe->ops.i2c_gate_ctrl(fe, 1);
0647 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
0648 return -EIO;
0649
0650 return 0;
0651 }
0652
0653 static struct tda1002x_config philips_cu1216_config = {
0654 .demod_address = 0x0c,
0655 .invert = 1,
0656 };
0657
0658 static struct tda1002x_config philips_cu1216_config_altaddress = {
0659 .demod_address = 0x0d,
0660 .invert = 0,
0661 };
0662
0663 static struct tda10023_config philips_cu1216_tda10023_config = {
0664 .demod_address = 0x0c,
0665 .invert = 1,
0666 };
0667
0668 static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
0669 {
0670 struct budget *budget = (struct budget *) fe->dvb->priv;
0671 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
0672 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
0673
0674
0675 if (fe->ops.i2c_gate_ctrl)
0676 fe->ops.i2c_gate_ctrl(fe, 1);
0677 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
0678 return -EIO;
0679 msleep(1);
0680
0681 return 0;
0682 }
0683
0684 static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe)
0685 {
0686 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0687 struct budget *budget = (struct budget *) fe->dvb->priv;
0688 u8 tuner_buf[4];
0689 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
0690 sizeof(tuner_buf) };
0691 int tuner_frequency = 0;
0692 u8 band, cp, filter;
0693
0694
0695 tuner_frequency = c->frequency + 36166000;
0696 if (tuner_frequency < 87000000)
0697 return -EINVAL;
0698 else if (tuner_frequency < 130000000)
0699 cp = 3;
0700 else if (tuner_frequency < 160000000)
0701 cp = 5;
0702 else if (tuner_frequency < 200000000)
0703 cp = 6;
0704 else if (tuner_frequency < 290000000)
0705 cp = 3;
0706 else if (tuner_frequency < 420000000)
0707 cp = 5;
0708 else if (tuner_frequency < 480000000)
0709 cp = 6;
0710 else if (tuner_frequency < 620000000)
0711 cp = 3;
0712 else if (tuner_frequency < 830000000)
0713 cp = 5;
0714 else if (tuner_frequency < 895000000)
0715 cp = 7;
0716 else
0717 return -EINVAL;
0718
0719
0720 if (c->frequency < 49000000)
0721 return -EINVAL;
0722 else if (c->frequency < 161000000)
0723 band = 1;
0724 else if (c->frequency < 444000000)
0725 band = 2;
0726 else if (c->frequency < 861000000)
0727 band = 4;
0728 else
0729 return -EINVAL;
0730
0731
0732 switch (c->bandwidth_hz) {
0733 case 6000000:
0734 filter = 0;
0735 break;
0736
0737 case 7000000:
0738 filter = 0;
0739 break;
0740
0741 case 8000000:
0742 filter = 1;
0743 break;
0744
0745 default:
0746 return -EINVAL;
0747 }
0748
0749
0750
0751 tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000;
0752
0753
0754 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
0755 tuner_buf[1] = tuner_frequency & 0xff;
0756 tuner_buf[2] = 0xca;
0757 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
0758
0759 if (fe->ops.i2c_gate_ctrl)
0760 fe->ops.i2c_gate_ctrl(fe, 1);
0761 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
0762 return -EIO;
0763
0764 msleep(1);
0765 return 0;
0766 }
0767
0768 static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
0769 const struct firmware **fw, char *name)
0770 {
0771 struct budget *budget = (struct budget *) fe->dvb->priv;
0772
0773 return request_firmware(fw, name, &budget->dev->pci->dev);
0774 }
0775
0776 static struct tda1004x_config philips_tu1216_config = {
0777
0778 .demod_address = 0x8,
0779 .invert = 1,
0780 .invert_oclk = 1,
0781 .xtal_freq = TDA10046_XTAL_4M,
0782 .agc_config = TDA10046_AGC_DEFAULT,
0783 .if_freq = TDA10046_FREQ_3617,
0784 .request_firmware = philips_tu1216_request_firmware,
0785 };
0786
0787 static u8 philips_sd1878_inittab[] = {
0788 0x01, 0x15,
0789 0x02, 0x30,
0790 0x03, 0x00,
0791 0x04, 0x7d,
0792 0x05, 0x35,
0793 0x06, 0x40,
0794 0x07, 0x00,
0795 0x08, 0x43,
0796 0x09, 0x02,
0797 0x0C, 0x51,
0798 0x0D, 0x82,
0799 0x0E, 0x23,
0800 0x10, 0x3f,
0801 0x11, 0x84,
0802 0x12, 0xb9,
0803 0x15, 0xc9,
0804 0x16, 0x19,
0805 0x17, 0x8c,
0806 0x18, 0x59,
0807 0x19, 0xf8,
0808 0x1a, 0xfe,
0809 0x1c, 0x7f,
0810 0x1d, 0x00,
0811 0x1e, 0x00,
0812 0x1f, 0x50,
0813 0x20, 0x00,
0814 0x21, 0x00,
0815 0x22, 0x00,
0816 0x23, 0x00,
0817 0x28, 0x00,
0818 0x29, 0x28,
0819 0x2a, 0x14,
0820 0x2b, 0x0f,
0821 0x2c, 0x09,
0822 0x2d, 0x09,
0823 0x31, 0x1f,
0824 0x32, 0x19,
0825 0x33, 0xfc,
0826 0x34, 0x93,
0827 0xff, 0xff
0828 };
0829
0830 static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
0831 u32 srate, u32 ratio)
0832 {
0833 u8 aclk = 0;
0834 u8 bclk = 0;
0835 u8 m1;
0836
0837 aclk = 0xb5;
0838 if (srate < 2000000)
0839 bclk = 0x86;
0840 else if (srate < 5000000)
0841 bclk = 0x89;
0842 else if (srate < 15000000)
0843 bclk = 0x8f;
0844 else if (srate < 45000000)
0845 bclk = 0x95;
0846
0847 m1 = 0x14;
0848 if (srate < 4000000)
0849 m1 = 0x10;
0850
0851 stv0299_writereg(fe, 0x0e, 0x23);
0852 stv0299_writereg(fe, 0x0f, 0x94);
0853 stv0299_writereg(fe, 0x10, 0x39);
0854 stv0299_writereg(fe, 0x13, aclk);
0855 stv0299_writereg(fe, 0x14, bclk);
0856 stv0299_writereg(fe, 0x15, 0xc9);
0857 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
0858 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
0859 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
0860 stv0299_writereg(fe, 0x0f, 0x80 | m1);
0861
0862 return 0;
0863 }
0864
0865 static const struct stv0299_config philips_sd1878_config = {
0866 .demod_address = 0x68,
0867 .inittab = philips_sd1878_inittab,
0868 .mclk = 88000000UL,
0869 .invert = 0,
0870 .skip_reinit = 0,
0871 .lock_output = STV0299_LOCKOUTPUT_1,
0872 .volt13_op0_op1 = STV0299_VOLT13_OP0,
0873 .min_delay_ms = 100,
0874 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
0875 };
0876
0877
0878 static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
0879
0880 { STB0899_DEV_ID , 0x81 },
0881 { STB0899_DISCNTRL1 , 0x32 },
0882 { STB0899_DISCNTRL2 , 0x80 },
0883 { STB0899_DISRX_ST0 , 0x04 },
0884 { STB0899_DISRX_ST1 , 0x00 },
0885 { STB0899_DISPARITY , 0x00 },
0886 { STB0899_DISSTATUS , 0x20 },
0887 { STB0899_DISF22 , 0x8c },
0888 { STB0899_DISF22RX , 0x9a },
0889 { STB0899_SYSREG , 0x0b },
0890 { STB0899_ACRPRESC , 0x11 },
0891 { STB0899_ACRDIV1 , 0x0a },
0892 { STB0899_ACRDIV2 , 0x05 },
0893 { STB0899_DACR1 , 0x00 },
0894 { STB0899_DACR2 , 0x00 },
0895 { STB0899_OUTCFG , 0x00 },
0896 { STB0899_MODECFG , 0x00 },
0897 { STB0899_IRQSTATUS_3 , 0x30 },
0898 { STB0899_IRQSTATUS_2 , 0x00 },
0899 { STB0899_IRQSTATUS_1 , 0x00 },
0900 { STB0899_IRQSTATUS_0 , 0x00 },
0901 { STB0899_IRQMSK_3 , 0xf3 },
0902 { STB0899_IRQMSK_2 , 0xfc },
0903 { STB0899_IRQMSK_1 , 0xff },
0904 { STB0899_IRQMSK_0 , 0xff },
0905 { STB0899_IRQCFG , 0x00 },
0906 { STB0899_I2CCFG , 0x88 },
0907 { STB0899_I2CRPT , 0x58 },
0908 { STB0899_IOPVALUE5 , 0x00 },
0909 { STB0899_IOPVALUE4 , 0x20 },
0910 { STB0899_IOPVALUE3 , 0xc9 },
0911 { STB0899_IOPVALUE2 , 0x90 },
0912 { STB0899_IOPVALUE1 , 0x40 },
0913 { STB0899_IOPVALUE0 , 0x00 },
0914 { STB0899_GPIO00CFG , 0x82 },
0915 { STB0899_GPIO01CFG , 0x82 },
0916 { STB0899_GPIO02CFG , 0x82 },
0917 { STB0899_GPIO03CFG , 0x82 },
0918 { STB0899_GPIO04CFG , 0x82 },
0919 { STB0899_GPIO05CFG , 0x82 },
0920 { STB0899_GPIO06CFG , 0x82 },
0921 { STB0899_GPIO07CFG , 0x82 },
0922 { STB0899_GPIO08CFG , 0x82 },
0923 { STB0899_GPIO09CFG , 0x82 },
0924 { STB0899_GPIO10CFG , 0x82 },
0925 { STB0899_GPIO11CFG , 0x82 },
0926 { STB0899_GPIO12CFG , 0x82 },
0927 { STB0899_GPIO13CFG , 0x82 },
0928 { STB0899_GPIO14CFG , 0x82 },
0929 { STB0899_GPIO15CFG , 0x82 },
0930 { STB0899_GPIO16CFG , 0x82 },
0931 { STB0899_GPIO17CFG , 0x82 },
0932 { STB0899_GPIO18CFG , 0x82 },
0933 { STB0899_GPIO19CFG , 0x82 },
0934 { STB0899_GPIO20CFG , 0x82 },
0935 { STB0899_SDATCFG , 0xb8 },
0936 { STB0899_SCLTCFG , 0xba },
0937 { STB0899_AGCRFCFG , 0x08 },
0938 { STB0899_GPIO22 , 0x82 },
0939 { STB0899_GPIO21 , 0x91 },
0940 { STB0899_DIRCLKCFG , 0x82 },
0941 { STB0899_CLKOUT27CFG , 0x7e },
0942 { STB0899_STDBYCFG , 0x82 },
0943 { STB0899_CS0CFG , 0x82 },
0944 { STB0899_CS1CFG , 0x82 },
0945 { STB0899_DISEQCOCFG , 0x20 },
0946 { STB0899_GPIO32CFG , 0x82 },
0947 { STB0899_GPIO33CFG , 0x82 },
0948 { STB0899_GPIO34CFG , 0x82 },
0949 { STB0899_GPIO35CFG , 0x82 },
0950 { STB0899_GPIO36CFG , 0x82 },
0951 { STB0899_GPIO37CFG , 0x82 },
0952 { STB0899_GPIO38CFG , 0x82 },
0953 { STB0899_GPIO39CFG , 0x82 },
0954 { STB0899_NCOARSE , 0x15 },
0955 { STB0899_SYNTCTRL , 0x02 },
0956 { STB0899_FILTCTRL , 0x00 },
0957 { STB0899_SYSCTRL , 0x00 },
0958 { STB0899_STOPCLK1 , 0x20 },
0959 { STB0899_STOPCLK2 , 0x00 },
0960 { STB0899_INTBUFSTATUS , 0x00 },
0961 { STB0899_INTBUFCTRL , 0x0a },
0962 { 0xffff , 0xff },
0963 };
0964
0965 static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
0966 { STB0899_DEMOD , 0x00 },
0967 { STB0899_RCOMPC , 0xc9 },
0968 { STB0899_AGC1CN , 0x41 },
0969 { STB0899_AGC1REF , 0x08 },
0970 { STB0899_RTC , 0x7a },
0971 { STB0899_TMGCFG , 0x4e },
0972 { STB0899_AGC2REF , 0x33 },
0973 { STB0899_TLSR , 0x84 },
0974 { STB0899_CFD , 0xee },
0975 { STB0899_ACLC , 0x87 },
0976 { STB0899_BCLC , 0x94 },
0977 { STB0899_EQON , 0x41 },
0978 { STB0899_LDT , 0xdd },
0979 { STB0899_LDT2 , 0xc9 },
0980 { STB0899_EQUALREF , 0xb4 },
0981 { STB0899_TMGRAMP , 0x10 },
0982 { STB0899_TMGTHD , 0x30 },
0983 { STB0899_IDCCOMP , 0xfb },
0984 { STB0899_QDCCOMP , 0x03 },
0985 { STB0899_POWERI , 0x3b },
0986 { STB0899_POWERQ , 0x3d },
0987 { STB0899_RCOMP , 0x81 },
0988 { STB0899_AGCIQIN , 0x80 },
0989 { STB0899_AGC2I1 , 0x04 },
0990 { STB0899_AGC2I2 , 0xf5 },
0991 { STB0899_TLIR , 0x25 },
0992 { STB0899_RTF , 0x80 },
0993 { STB0899_DSTATUS , 0x00 },
0994 { STB0899_LDI , 0xca },
0995 { STB0899_CFRM , 0xf1 },
0996 { STB0899_CFRL , 0xf3 },
0997 { STB0899_NIRM , 0x2a },
0998 { STB0899_NIRL , 0x05 },
0999 { STB0899_ISYMB , 0x17 },
1000 { STB0899_QSYMB , 0xfa },
1001 { STB0899_SFRH , 0x2f },
1002 { STB0899_SFRM , 0x68 },
1003 { STB0899_SFRL , 0x40 },
1004 { STB0899_SFRUPH , 0x2f },
1005 { STB0899_SFRUPM , 0x68 },
1006 { STB0899_SFRUPL , 0x40 },
1007 { STB0899_EQUAI1 , 0xfd },
1008 { STB0899_EQUAQ1 , 0x04 },
1009 { STB0899_EQUAI2 , 0x0f },
1010 { STB0899_EQUAQ2 , 0xff },
1011 { STB0899_EQUAI3 , 0xdf },
1012 { STB0899_EQUAQ3 , 0xfa },
1013 { STB0899_EQUAI4 , 0x37 },
1014 { STB0899_EQUAQ4 , 0x0d },
1015 { STB0899_EQUAI5 , 0xbd },
1016 { STB0899_EQUAQ5 , 0xf7 },
1017 { STB0899_DSTATUS2 , 0x00 },
1018 { STB0899_VSTATUS , 0x00 },
1019 { STB0899_VERROR , 0xff },
1020 { STB0899_IQSWAP , 0x2a },
1021 { STB0899_ECNT1M , 0x00 },
1022 { STB0899_ECNT1L , 0x00 },
1023 { STB0899_ECNT2M , 0x00 },
1024 { STB0899_ECNT2L , 0x00 },
1025 { STB0899_ECNT3M , 0x00 },
1026 { STB0899_ECNT3L , 0x00 },
1027 { STB0899_FECAUTO1 , 0x06 },
1028 { STB0899_FECM , 0x01 },
1029 { STB0899_VTH12 , 0xf0 },
1030 { STB0899_VTH23 , 0xa0 },
1031 { STB0899_VTH34 , 0x78 },
1032 { STB0899_VTH56 , 0x4e },
1033 { STB0899_VTH67 , 0x48 },
1034 { STB0899_VTH78 , 0x38 },
1035 { STB0899_PRVIT , 0xff },
1036 { STB0899_VITSYNC , 0x19 },
1037 { STB0899_RSULC , 0xb1 },
1038 { STB0899_TSULC , 0x42 },
1039 { STB0899_RSLLC , 0x40 },
1040 { STB0899_TSLPL , 0x12 },
1041 { STB0899_TSCFGH , 0x0c },
1042 { STB0899_TSCFGM , 0x00 },
1043 { STB0899_TSCFGL , 0x0c },
1044 { STB0899_TSOUT , 0x4d },
1045 { STB0899_RSSYNCDEL , 0x00 },
1046 { STB0899_TSINHDELH , 0x02 },
1047 { STB0899_TSINHDELM , 0x00 },
1048 { STB0899_TSINHDELL , 0x00 },
1049 { STB0899_TSLLSTKM , 0x00 },
1050 { STB0899_TSLLSTKL , 0x00 },
1051 { STB0899_TSULSTKM , 0x00 },
1052 { STB0899_TSULSTKL , 0xab },
1053 { STB0899_PCKLENUL , 0x00 },
1054 { STB0899_PCKLENLL , 0xcc },
1055 { STB0899_RSPCKLEN , 0xcc },
1056 { STB0899_TSSTATUS , 0x80 },
1057 { STB0899_ERRCTRL1 , 0xb6 },
1058 { STB0899_ERRCTRL2 , 0x96 },
1059 { STB0899_ERRCTRL3 , 0x89 },
1060 { STB0899_DMONMSK1 , 0x27 },
1061 { STB0899_DMONMSK0 , 0x03 },
1062 { STB0899_DEMAPVIT , 0x5c },
1063 { STB0899_PLPARM , 0x1f },
1064 { STB0899_PDELCTRL , 0x48 },
1065 { STB0899_PDELCTRL2 , 0x00 },
1066 { STB0899_BBHCTRL1 , 0x00 },
1067 { STB0899_BBHCTRL2 , 0x00 },
1068 { STB0899_HYSTTHRESH , 0x77 },
1069 { STB0899_MATCSTM , 0x00 },
1070 { STB0899_MATCSTL , 0x00 },
1071 { STB0899_UPLCSTM , 0x00 },
1072 { STB0899_UPLCSTL , 0x00 },
1073 { STB0899_DFLCSTM , 0x00 },
1074 { STB0899_DFLCSTL , 0x00 },
1075 { STB0899_SYNCCST , 0x00 },
1076 { STB0899_SYNCDCSTM , 0x00 },
1077 { STB0899_SYNCDCSTL , 0x00 },
1078 { STB0899_ISI_ENTRY , 0x00 },
1079 { STB0899_ISI_BIT_EN , 0x00 },
1080 { STB0899_MATSTRM , 0x00 },
1081 { STB0899_MATSTRL , 0x00 },
1082 { STB0899_UPLSTRM , 0x00 },
1083 { STB0899_UPLSTRL , 0x00 },
1084 { STB0899_DFLSTRM , 0x00 },
1085 { STB0899_DFLSTRL , 0x00 },
1086 { STB0899_SYNCSTR , 0x00 },
1087 { STB0899_SYNCDSTRM , 0x00 },
1088 { STB0899_SYNCDSTRL , 0x00 },
1089 { STB0899_CFGPDELSTATUS1 , 0x10 },
1090 { STB0899_CFGPDELSTATUS2 , 0x00 },
1091 { STB0899_BBFERRORM , 0x00 },
1092 { STB0899_BBFERRORL , 0x00 },
1093 { STB0899_UPKTERRORM , 0x00 },
1094 { STB0899_UPKTERRORL , 0x00 },
1095 { 0xffff , 0xff },
1096 };
1097
1098
1099 static struct stb0899_config knc1_dvbs2_config = {
1100 .init_dev = knc1_stb0899_s1_init_1,
1101 .init_s2_demod = stb0899_s2_init_2,
1102 .init_s1_demod = knc1_stb0899_s1_init_3,
1103 .init_s2_fec = stb0899_s2_init_4,
1104 .init_tst = stb0899_s1_init_5,
1105
1106 .postproc = NULL,
1107
1108 .demod_address = 0x68,
1109
1110 .block_sync_mode = STB0899_SYNC_FORCED,
1111
1112
1113 .xtal_freq = 27000000,
1114 .inversion = IQ_SWAP_OFF,
1115
1116 .lo_clk = 76500000,
1117 .hi_clk = 90000000,
1118
1119 .esno_ave = STB0899_DVBS2_ESNO_AVE,
1120 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
1121 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
1122 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
1123 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
1124 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1125 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1126 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1127 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1128
1129 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
1130 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1131 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
1132 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
1133
1134 .tuner_get_frequency = tda8261_get_frequency,
1135 .tuner_set_frequency = tda8261_set_frequency,
1136 .tuner_set_bandwidth = NULL,
1137 .tuner_get_bandwidth = tda8261_get_bandwidth,
1138 .tuner_set_rfsiggain = NULL
1139 };
1140
1141
1142
1143
1144
1145 static const struct tda8261_config sd1878c_config = {
1146
1147 .addr = 0x60,
1148 .step_size = TDA8261_STEP_1000
1149 };
1150
1151 static u8 read_pwm(struct budget_av *budget_av)
1152 {
1153 u8 b = 0xff;
1154 u8 pwm;
1155 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1156 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1157 };
1158
1159 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1160 || (pwm == 0xff))
1161 pwm = 0x48;
1162
1163 return pwm;
1164 }
1165
1166 #define SUBID_DVBS_KNC1 0x0010
1167 #define SUBID_DVBS_KNC1_PLUS 0x0011
1168 #define SUBID_DVBS_TYPHOON 0x4f56
1169 #define SUBID_DVBS_CINERGY1200 0x1154
1170 #define SUBID_DVBS_CYNERGY1200N 0x1155
1171 #define SUBID_DVBS_TV_STAR 0x0014
1172 #define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
1173 #define SUBID_DVBS_TV_STAR_CI 0x0016
1174 #define SUBID_DVBS2_KNC1 0x0018
1175 #define SUBID_DVBS2_KNC1_OEM 0x0019
1176 #define SUBID_DVBS_EASYWATCH_1 0x001a
1177 #define SUBID_DVBS_EASYWATCH_2 0x001b
1178 #define SUBID_DVBS2_EASYWATCH 0x001d
1179 #define SUBID_DVBS_EASYWATCH 0x001e
1180
1181 #define SUBID_DVBC_EASYWATCH 0x002a
1182 #define SUBID_DVBC_EASYWATCH_MK3 0x002c
1183 #define SUBID_DVBC_KNC1 0x0020
1184 #define SUBID_DVBC_KNC1_PLUS 0x0021
1185 #define SUBID_DVBC_KNC1_MK3 0x0022
1186 #define SUBID_DVBC_KNC1_TDA10024 0x0028
1187 #define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
1188 #define SUBID_DVBC_CINERGY1200 0x1156
1189 #define SUBID_DVBC_CINERGY1200_MK3 0x1176
1190
1191 #define SUBID_DVBT_EASYWATCH 0x003a
1192 #define SUBID_DVBT_KNC1_PLUS 0x0031
1193 #define SUBID_DVBT_KNC1 0x0030
1194 #define SUBID_DVBT_CINERGY1200 0x1157
1195
1196 static void frontend_init(struct budget_av *budget_av)
1197 {
1198 struct saa7146_dev * saa = budget_av->budget.dev;
1199 struct dvb_frontend * fe = NULL;
1200
1201
1202 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1203
1204
1205 msleep(100);
1206
1207
1208 switch (saa->pci->subsystem_device) {
1209 case SUBID_DVBS_KNC1_PLUS:
1210 case SUBID_DVBC_KNC1_PLUS:
1211 case SUBID_DVBT_KNC1_PLUS:
1212 case SUBID_DVBC_EASYWATCH:
1213 case SUBID_DVBC_KNC1_PLUS_MK3:
1214 case SUBID_DVBS2_KNC1:
1215 case SUBID_DVBS2_KNC1_OEM:
1216 case SUBID_DVBS2_EASYWATCH:
1217 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1218 break;
1219 }
1220
1221 switch (saa->pci->subsystem_device) {
1222
1223 case SUBID_DVBS_KNC1:
1224
1225
1226
1227
1228 budget_av->reinitialise_demod = 1;
1229 fallthrough;
1230 case SUBID_DVBS_KNC1_PLUS:
1231 case SUBID_DVBS_EASYWATCH_1:
1232 if (saa->pci->subsystem_vendor == 0x1894) {
1233 fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
1234 &budget_av->budget.i2c_adap);
1235 if (fe) {
1236 dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
1237 }
1238 } else {
1239 fe = dvb_attach(stv0299_attach, &typhoon_config,
1240 &budget_av->budget.i2c_adap);
1241 if (fe) {
1242 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1243 }
1244 }
1245 break;
1246
1247 case SUBID_DVBS_TV_STAR:
1248 case SUBID_DVBS_TV_STAR_PLUS_X4:
1249 case SUBID_DVBS_TV_STAR_CI:
1250 case SUBID_DVBS_CYNERGY1200N:
1251 case SUBID_DVBS_EASYWATCH:
1252 case SUBID_DVBS_EASYWATCH_2:
1253 fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
1254 &budget_av->budget.i2c_adap);
1255 if (fe) {
1256 dvb_attach(dvb_pll_attach, fe, 0x60,
1257 &budget_av->budget.i2c_adap,
1258 DVB_PLL_PHILIPS_SD1878_TDA8261);
1259 }
1260 break;
1261
1262 case SUBID_DVBS_TYPHOON:
1263 fe = dvb_attach(stv0299_attach, &typhoon_config,
1264 &budget_av->budget.i2c_adap);
1265 if (fe) {
1266 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1267 }
1268 break;
1269 case SUBID_DVBS2_KNC1:
1270 case SUBID_DVBS2_KNC1_OEM:
1271 case SUBID_DVBS2_EASYWATCH:
1272 budget_av->reinitialise_demod = 1;
1273 if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1274 dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
1275
1276 break;
1277 case SUBID_DVBS_CINERGY1200:
1278 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1279 &budget_av->budget.i2c_adap);
1280 if (fe) {
1281 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1282 }
1283 break;
1284
1285 case SUBID_DVBC_KNC1:
1286 case SUBID_DVBC_KNC1_PLUS:
1287 case SUBID_DVBC_CINERGY1200:
1288 case SUBID_DVBC_EASYWATCH:
1289 budget_av->reinitialise_demod = 1;
1290 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1291 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1292 &budget_av->budget.i2c_adap,
1293 read_pwm(budget_av));
1294 if (fe == NULL)
1295 fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1296 &budget_av->budget.i2c_adap,
1297 read_pwm(budget_av));
1298 if (fe) {
1299 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1300 }
1301 break;
1302
1303 case SUBID_DVBC_EASYWATCH_MK3:
1304 case SUBID_DVBC_CINERGY1200_MK3:
1305 case SUBID_DVBC_KNC1_MK3:
1306 case SUBID_DVBC_KNC1_TDA10024:
1307 case SUBID_DVBC_KNC1_PLUS_MK3:
1308 budget_av->reinitialise_demod = 1;
1309 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1310 fe = dvb_attach(tda10023_attach,
1311 &philips_cu1216_tda10023_config,
1312 &budget_av->budget.i2c_adap,
1313 read_pwm(budget_av));
1314 if (fe) {
1315 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1316 }
1317 break;
1318
1319 case SUBID_DVBT_EASYWATCH:
1320 case SUBID_DVBT_KNC1:
1321 case SUBID_DVBT_KNC1_PLUS:
1322 case SUBID_DVBT_CINERGY1200:
1323 budget_av->reinitialise_demod = 1;
1324 fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1325 &budget_av->budget.i2c_adap);
1326 if (fe) {
1327 fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1328 fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1329 }
1330 break;
1331 }
1332
1333 if (fe == NULL) {
1334 pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1335 saa->pci->vendor,
1336 saa->pci->device,
1337 saa->pci->subsystem_vendor,
1338 saa->pci->subsystem_device);
1339 return;
1340 }
1341
1342 budget_av->budget.dvb_frontend = fe;
1343
1344 if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1345 budget_av->budget.dvb_frontend)) {
1346 pr_err("Frontend registration failed!\n");
1347 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1348 budget_av->budget.dvb_frontend = NULL;
1349 }
1350 }
1351
1352
1353 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1354 {
1355 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1356
1357 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1358
1359 if (*isr & MASK_10)
1360 ttpci_budget_irq10_handler(dev, isr);
1361 }
1362
1363 static int budget_av_detach(struct saa7146_dev *dev)
1364 {
1365 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1366 int err;
1367
1368 dprintk(2, "dev: %p\n", dev);
1369
1370 if (1 == budget_av->has_saa7113) {
1371 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1372
1373 msleep(200);
1374
1375 saa7146_unregister_device(&budget_av->vd, dev);
1376
1377 saa7146_vv_release(dev);
1378 }
1379
1380 if (budget_av->budget.ci_present)
1381 ciintf_deinit(budget_av);
1382
1383 if (budget_av->budget.dvb_frontend != NULL) {
1384 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1385 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1386 }
1387 err = ttpci_budget_deinit(&budget_av->budget);
1388
1389 kfree(budget_av);
1390
1391 return err;
1392 }
1393
1394 #define KNC1_INPUTS 2
1395 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1396 { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
1397 V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1398 { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
1399 V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1400 };
1401
1402 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1403 {
1404 dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index);
1405 if (i->index >= KNC1_INPUTS)
1406 return -EINVAL;
1407 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1408 return 0;
1409 }
1410
1411 static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1412 {
1413 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1414 struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1415
1416 *i = budget_av->cur_input;
1417
1418 dprintk(1, "VIDIOC_G_INPUT %d\n", *i);
1419 return 0;
1420 }
1421
1422 static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
1423 {
1424 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1425 struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1426
1427 dprintk(1, "VIDIOC_S_INPUT %d\n", input);
1428 return saa7113_setinput(budget_av, input);
1429 }
1430
1431 static struct saa7146_ext_vv vv_data;
1432
1433 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1434 {
1435 struct budget_av *budget_av;
1436 u8 *mac;
1437 int err;
1438
1439 dprintk(2, "dev: %p\n", dev);
1440
1441 if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1442 return -ENOMEM;
1443
1444 budget_av->has_saa7113 = 0;
1445 budget_av->budget.ci_present = 0;
1446
1447 dev->ext_priv = budget_av;
1448
1449 err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1450 adapter_nr);
1451 if (err) {
1452 kfree(budget_av);
1453 return err;
1454 }
1455
1456
1457 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1458 saa7146_write(dev, DD1_INIT, 0x07000600);
1459 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1460
1461 if (saa7113_init(budget_av) == 0) {
1462 budget_av->has_saa7113 = 1;
1463 err = saa7146_vv_init(dev, &vv_data);
1464 if (err != 0) {
1465
1466 ERR("cannot init vv subsystem\n");
1467 return err;
1468 }
1469 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
1470 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
1471 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
1472
1473 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) {
1474
1475 ERR("cannot register capture v4l2 device\n");
1476 saa7146_vv_release(dev);
1477 return err;
1478 }
1479
1480
1481 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1482 SAA7146_HPS_SYNC_PORT_A);
1483
1484 saa7113_setinput(budget_av, 0);
1485 }
1486
1487
1488 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1489
1490 mac = budget_av->budget.dvb_adapter.proposed_mac;
1491 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1492 pr_err("KNC1-%d: Could not read MAC from KNC1 card\n",
1493 budget_av->budget.dvb_adapter.num);
1494 eth_zero_addr(mac);
1495 } else {
1496 pr_info("KNC1-%d: MAC addr = %pM\n",
1497 budget_av->budget.dvb_adapter.num, mac);
1498 }
1499
1500 budget_av->budget.dvb_adapter.priv = budget_av;
1501 frontend_init(budget_av);
1502 ciintf_init(budget_av);
1503
1504 ttpci_budget_init_hooks(&budget_av->budget);
1505
1506 return 0;
1507 }
1508
1509 static struct saa7146_standard standard[] = {
1510 {.name = "PAL",.id = V4L2_STD_PAL,
1511 .v_offset = 0x17,.v_field = 288,
1512 .h_offset = 0x14,.h_pixels = 680,
1513 .v_max_out = 576,.h_max_out = 768 },
1514
1515 {.name = "NTSC",.id = V4L2_STD_NTSC,
1516 .v_offset = 0x16,.v_field = 240,
1517 .h_offset = 0x06,.h_pixels = 708,
1518 .v_max_out = 480,.h_max_out = 640, },
1519 };
1520
1521 static struct saa7146_ext_vv vv_data = {
1522 .inputs = 2,
1523 .capabilities = 0,
1524 .flags = 0,
1525 .stds = &standard[0],
1526 .num_stds = ARRAY_SIZE(standard),
1527 };
1528
1529 static struct saa7146_extension budget_extension;
1530
1531 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1532 MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
1533 MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
1534 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1535 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1536 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1537 MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1538 MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1539 MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
1540 MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
1541 MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
1542 MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
1543 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1544 MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
1545 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1546 MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1547 MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024);
1548 MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
1549 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1550 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1551 MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1552 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1553 MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1554 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1555
1556 static const struct pci_device_id pci_tbl[] = {
1557 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1558 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1559 MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1560 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1561 MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1562 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1563 MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
1564 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1565 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1566 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
1567 MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
1568 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1569 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1570 MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
1571 MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
1572 MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
1573 MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
1574 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1575 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1576 MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1577 MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028),
1578 MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1579 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1580 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1581 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1582 MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1583 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1584 MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1585 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1586 {
1587 .vendor = 0,
1588 }
1589 };
1590
1591 MODULE_DEVICE_TABLE(pci, pci_tbl);
1592
1593 static struct saa7146_extension budget_extension = {
1594 .name = "budget_av",
1595 .flags = SAA7146_USE_I2C_IRQ,
1596
1597 .pci_tbl = pci_tbl,
1598
1599 .module = THIS_MODULE,
1600 .attach = budget_av_attach,
1601 .detach = budget_av_detach,
1602
1603 .irq_mask = MASK_10,
1604 .irq_func = budget_av_irq,
1605 };
1606
1607 static int __init budget_av_init(void)
1608 {
1609 return saa7146_register_extension(&budget_extension);
1610 }
1611
1612 static void __exit budget_av_exit(void)
1613 {
1614 saa7146_unregister_extension(&budget_extension);
1615 }
1616
1617 module_init(budget_av_init);
1618 module_exit(budget_av_exit);
1619
1620 MODULE_LICENSE("GPL");
1621 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1622 MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");