aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Kaiser <linux-dvb AT kaiser-linux.li>2006-04-27 20:45:20 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-25 00:59:46 -0400
commitb8d4c235d50f8512bbc9d67730c24da3309b0307 (patch)
tree9af461a3b198bfd6856ab510044363b34a7d7be4
parent21c2858235a81ce4fa1862432eb0c98d8dbdee1e (diff)
V4L/DVB (3934): Support new dvb-ttusb-budget boards with stv0297
Added config switch to stv0297 to control i2c STOP during write behaviour. Update frontend init in dvb-ttusb-budget. Enable i2c STOP on other users of stv0297. Signed-off-by: Thomas Kaiser <linux-dvb AT kaiser-linux.li> Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/dvb/frontends/stv0297.c49
-rw-r--r--drivers/media/dvb/frontends/stv0297.h3
-rw-r--r--drivers/media/dvb/ttpci/av7110.c1
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c1
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig1
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c175
6 files changed, 212 insertions, 18 deletions
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index c8c3b74f9958..98b95a205fd2 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -68,19 +68,25 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg)
68 int ret; 68 int ret;
69 u8 b0[] = { reg }; 69 u8 b0[] = { reg };
70 u8 b1[] = { 0 }; 70 u8 b1[] = { 0 };
71 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 71 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
72 1}, 72 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
73 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} 73 };
74 };
75 74
76 // this device needs a STOP between the register and data 75 // this device needs a STOP between the register and data
77 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { 76 if (state->config->stop_during_read) {
78 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); 77 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
79 return -1; 78 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
80 } 79 return -1;
81 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { 80 }
82 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); 81 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
83 return -1; 82 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
83 return -1;
84 }
85 } else {
86 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
87 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
88 return -1;
89 }
84 } 90 }
85 91
86 return b1[0]; 92 return b1[0];
@@ -107,13 +113,20 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len
107 }; 113 };
108 114
109 // this device needs a STOP between the register and data 115 // this device needs a STOP between the register and data
110 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { 116 if (state->config->stop_during_read) {
111 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); 117 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
112 return -1; 118 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
113 } 119 return -1;
114 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { 120 }
115 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); 121 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
116 return -1; 122 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
123 return -1;
124 }
125 } else {
126 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
127 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
128 return -1;
129 }
117 } 130 }
118 131
119 return 0; 132 return 0;
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 8ff793c90038..1da5384fb985 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -37,6 +37,9 @@ struct stv0297_config
37 37
38 /* does the "inversion" need inverted? */ 38 /* does the "inversion" need inverted? */
39 u8 invert:1; 39 u8 invert:1;
40
41 /* set to 1 if the device requires an i2c STOP during reading */
42 u8 stop_during_read:1;
40}; 43};
41 44
42extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, 45extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 1a6d7a3bf459..be0a04caf923 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1859,6 +1859,7 @@ static struct stv0297_config nexusca_stv0297_config = {
1859 .demod_address = 0x1C, 1859 .demod_address = 0x1C,
1860 .inittab = nexusca_stv0297_inittab, 1860 .inittab = nexusca_stv0297_inittab,
1861 .invert = 1, 1861 .invert = 1,
1862 .stop_during_read = 1,
1862}; 1863};
1863 1864
1864 1865
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 145e12f9a7f6..eb03b140b05c 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -977,6 +977,7 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = {
977 .demod_address = 0x1c, 977 .demod_address = 0x1c,
978 .inittab = dvbc_philips_tdm1316l_inittab, 978 .inittab = dvbc_philips_tdm1316l_inittab,
979 .invert = 0, 979 .invert = 0,
980 .stop_during_read = 1,
980}; 981};
981 982
982 983
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index d1004e863290..92c7cdcf8981 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -6,6 +6,7 @@ config DVB_TTUSB_BUDGET
6 select DVB_VES1820 6 select DVB_VES1820
7 select DVB_TDA8083 7 select DVB_TDA8083
8 select DVB_STV0299 8 select DVB_STV0299
9 select DVB_STV0297
9 select DVB_LNBP21 10 select DVB_LNBP21
10 help 11 help
11 Support for external USB adapters designed by Technotrend and 12 Support for external USB adapters designed by Technotrend and
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 71581303b0ea..cf264512d36f 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -30,6 +30,7 @@
30#include "tda1004x.h" 30#include "tda1004x.h"
31#include "stv0299.h" 31#include "stv0299.h"
32#include "tda8083.h" 32#include "tda8083.h"
33#include "stv0297.h"
33#include "lnbp21.h" 34#include "lnbp21.h"
34 35
35#include <linux/dvb/frontend.h> 36#include <linux/dvb/frontend.h>
@@ -1380,6 +1381,174 @@ static u8 read_pwm(struct ttusb* ttusb)
1380} 1381}
1381 1382
1382 1383
1384static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1385{
1386 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1387 u8 tuner_buf[5];
1388 struct i2c_msg tuner_msg = {.addr = 0x60,
1389 .flags = 0,
1390 .buf = tuner_buf,
1391 .len = sizeof(tuner_buf) };
1392 int tuner_frequency = 0;
1393 u8 band, cp, filter;
1394
1395 // determine charge pump
1396 tuner_frequency = params->frequency;
1397 if (tuner_frequency < 87000000) {return -EINVAL;}
1398 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1399 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1400 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1401 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1402 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1403 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1404 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1405 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1406 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1407 else {return -EINVAL;}
1408
1409 // assume PLL filter should always be 8MHz for the moment.
1410 filter = 1;
1411
1412 // calculate divisor
1413 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1414 tuner_frequency = ((params->frequency + 36125000) / 62500);
1415
1416 // setup tuner buffer
1417 tuner_buf[0] = tuner_frequency >> 8;
1418 tuner_buf[1] = tuner_frequency & 0xff;
1419 tuner_buf[2] = 0xc8;
1420 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1421 tuner_buf[4] = 0x80;
1422
1423 if (fe->ops->i2c_gate_ctrl)
1424 fe->ops->i2c_gate_ctrl(fe, 1);
1425 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1426 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1427 return -EIO;
1428 }
1429
1430 msleep(50);
1431
1432 if (fe->ops->i2c_gate_ctrl)
1433 fe->ops->i2c_gate_ctrl(fe, 1);
1434 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1435 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1436 return -EIO;
1437 }
1438
1439 msleep(1);
1440
1441 return 0;
1442}
1443
1444static u8 dvbc_philips_tdm1316l_inittab[] = {
1445 0x80, 0x21,
1446 0x80, 0x20,
1447 0x81, 0x01,
1448 0x81, 0x00,
1449 0x00, 0x09,
1450 0x01, 0x69,
1451 0x03, 0x00,
1452 0x04, 0x00,
1453 0x07, 0x00,
1454 0x08, 0x00,
1455 0x20, 0x00,
1456 0x21, 0x40,
1457 0x22, 0x00,
1458 0x23, 0x00,
1459 0x24, 0x40,
1460 0x25, 0x88,
1461 0x30, 0xff,
1462 0x31, 0x00,
1463 0x32, 0xff,
1464 0x33, 0x00,
1465 0x34, 0x50,
1466 0x35, 0x7f,
1467 0x36, 0x00,
1468 0x37, 0x20,
1469 0x38, 0x00,
1470 0x40, 0x1c,
1471 0x41, 0xff,
1472 0x42, 0x29,
1473 0x43, 0x20,
1474 0x44, 0xff,
1475 0x45, 0x00,
1476 0x46, 0x00,
1477 0x49, 0x04,
1478 0x4a, 0xff,
1479 0x4b, 0x7f,
1480 0x52, 0x30,
1481 0x55, 0xae,
1482 0x56, 0x47,
1483 0x57, 0xe1,
1484 0x58, 0x3a,
1485 0x5a, 0x1e,
1486 0x5b, 0x34,
1487 0x60, 0x00,
1488 0x63, 0x00,
1489 0x64, 0x00,
1490 0x65, 0x00,
1491 0x66, 0x00,
1492 0x67, 0x00,
1493 0x68, 0x00,
1494 0x69, 0x00,
1495 0x6a, 0x02,
1496 0x6b, 0x00,
1497 0x70, 0xff,
1498 0x71, 0x00,
1499 0x72, 0x00,
1500 0x73, 0x00,
1501 0x74, 0x0c,
1502 0x80, 0x00,
1503 0x81, 0x00,
1504 0x82, 0x00,
1505 0x83, 0x00,
1506 0x84, 0x04,
1507 0x85, 0x80,
1508 0x86, 0x24,
1509 0x87, 0x78,
1510 0x88, 0x00,
1511 0x89, 0x00,
1512 0x90, 0x01,
1513 0x91, 0x01,
1514 0xa0, 0x00,
1515 0xa1, 0x00,
1516 0xa2, 0x00,
1517 0xb0, 0x91,
1518 0xb1, 0x0b,
1519 0xc0, 0x4b,
1520 0xc1, 0x00,
1521 0xc2, 0x00,
1522 0xd0, 0x00,
1523 0xd1, 0x00,
1524 0xd2, 0x00,
1525 0xd3, 0x00,
1526 0xd4, 0x00,
1527 0xd5, 0x00,
1528 0xde, 0x00,
1529 0xdf, 0x00,
1530 0x61, 0x38,
1531 0x62, 0x0a,
1532 0x53, 0x13,
1533 0x59, 0x08,
1534 0x55, 0x00,
1535 0x56, 0x40,
1536 0x57, 0x08,
1537 0x58, 0x3d,
1538 0x88, 0x10,
1539 0xa0, 0x00,
1540 0xa0, 0x00,
1541 0xa0, 0x00,
1542 0xa0, 0x04,
1543 0xff, 0xff,
1544};
1545
1546static struct stv0297_config dvbc_philips_tdm1316l_config = {
1547 .demod_address = 0x1c,
1548 .inittab = dvbc_philips_tdm1316l_inittab,
1549 .invert = 0,
1550};
1551
1383static void frontend_init(struct ttusb* ttusb) 1552static void frontend_init(struct ttusb* ttusb)
1384{ 1553{
1385 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { 1554 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
@@ -1413,6 +1582,12 @@ static void frontend_init(struct ttusb* ttusb)
1413 ttusb->fe->ops->tuner_ops.set_params = alps_tdbe2_tuner_set_params; 1582 ttusb->fe->ops->tuner_ops.set_params = alps_tdbe2_tuner_set_params;
1414 break; 1583 break;
1415 } 1584 }
1585
1586 ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
1587 if (ttusb->fe != NULL) {
1588 ttusb->fe->ops->tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1589 break;
1590 }
1416 break; 1591 break;
1417 1592
1418 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) 1593 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))