diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-13 12:09:52 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-13 12:09:52 -0200 |
commit | c04e90e2d38493e6c092095cc2441365dd3973af (patch) | |
tree | 10f7dd48868de244e34380fc45ecac99601d9027 /linux | |
parent | 2cea09a7e6ff7e5202803e6a6c2279ed254d7dff (diff) | |
parent | a0184c08027dba2f30a12bcd1ca1ca1da7fc7963 (diff) | |
download | mediapointer-dvb-s2-c04e90e2d38493e6c092095cc2441365dd3973af.tar.gz mediapointer-dvb-s2-c04e90e2d38493e6c092095cc2441365dd3973af.tar.bz2 |
merge: http://linuxtv.org/hg/~stoth/s2
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Priority: normal
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux')
-rw-r--r-- | linux/Documentation/video4linux/CARDLIST.cx88 | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 98 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/Kconfig | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dw2102.c | 123 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/cx24116.c | 177 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/eds1547.h | 133 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/stb6000.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/stv0288.c | 20 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/stv0288.h | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-cards.c | 27 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-dvb.c | 9 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88.h | 1 | ||||
-rw-r--r-- | linux/include/linux/dvb/frontend.h | 21 |
13 files changed, 530 insertions, 87 deletions
diff --git a/linux/Documentation/video4linux/CARDLIST.cx88 b/linux/Documentation/video4linux/CARDLIST.cx88 index 50d0b1c55..a5227e308 100644 --- a/linux/Documentation/video4linux/CARDLIST.cx88 +++ b/linux/Documentation/video4linux/CARDLIST.cx88 @@ -73,3 +73,4 @@ 72 -> TBS 8920 DVB-S/S2 [8920:8888] 73 -> TeVii S420 DVB-S [d420:9022] 74 -> Prolink Pixelview Global Extreme [1554:4976] + 75 -> PROF 7300 DVB-S/S2 [B033:3033] diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 6f0dc252f..43b31ec2c 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -841,6 +841,11 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_DELIVERY_SYSTEM, .set = 1, }, + [DTV_HIERARCHY] = { + .name = "DTV_HIERARCHY", + .cmd = DTV_HIERARCHY, + .set = 1, + }, #if 0 [DTV_ISDB_SEGMENT_IDX] = { .name = "DTV_ISDB_SEGMENT_IDX", @@ -853,6 +858,26 @@ struct dtv_cmds_h dtv_cmds[] = { .set = 1, }, #endif + [DTV_CODE_RATE_HP] = { + .name = "DTV_CODE_RATE_HP", + .cmd = DTV_CODE_RATE_HP, + .set = 1, + }, + [DTV_CODE_RATE_LP] = { + .name = "DTV_CODE_RATE_LP", + .cmd = DTV_CODE_RATE_LP, + .set = 1, + }, + [DTV_GUARD_INTERVAL] = { + .name = "DTV_GUARD_INTERVAL", + .cmd = DTV_GUARD_INTERVAL, + .set = 1, + }, + [DTV_TRANSMISSION_MODE] = { + .name = "DTV_TRANSMISSION_MODE", + .cmd = DTV_TRANSMISSION_MODE, + .set = 1, + }, /* Get */ [DTV_DISEQC_SLAVE_REPLY] = { .name = "DTV_DISEQC_SLAVE_REPLY", @@ -912,12 +937,43 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_API_VERSION, .set = 0, }, + [DTV_CODE_RATE_HP] = { + .name = "DTV_CODE_RATE_HP", + .cmd = DTV_CODE_RATE_HP, + .set = 0, + }, + [DTV_CODE_RATE_LP] = { + .name = "DTV_CODE_RATE_LP", + .cmd = DTV_CODE_RATE_LP, + .set = 0, + }, + [DTV_GUARD_INTERVAL] = { + .name = "DTV_GUARD_INTERVAL", + .cmd = DTV_GUARD_INTERVAL, + .set = 0, + }, + [DTV_TRANSMISSION_MODE] = { + .name = "DTV_TRANSMISSION_MODE", + .cmd = DTV_TRANSMISSION_MODE, + .set = 0, + }, + [DTV_HIERARCHY] = { + .name = "DTV_HIERARCHY", + .cmd = DTV_HIERARCHY, + .set = 0, + }, }; void dtv_property_dump(struct dtv_property *tvp) { int i; + if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { + printk("%s: tvp.cmd = 0x%08x (undefined/unknown/invalid)\n", + __func__, tvp->cmd); + return; + } + printk("%s() tvp.cmd = 0x%08x (%s)\n" ,__FUNCTION__ ,tvp->cmd @@ -963,6 +1019,8 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame switch (fe->ops.info.type) { case FE_QPSK: + c->modulation = QPSK; /* implied for DVB-S in legacy API */ + c->rolloff = ROLLOFF_35;/* implied for DVB-S */ c->symbol_rate = p->u.qpsk.symbol_rate; c->fec_inner = p->u.qpsk.fec_inner; c->delivery_system = SYS_DVBS; @@ -1073,9 +1131,9 @@ void dtv_property_adv_params_sync(struct dvb_frontend *fe) p->inversion = c->inversion; switch(c->modulation) { - case _8PSK: - case _16APSK: - case NBC_QPSK: + case PSK_8: + case APSK_16: + case QPSK: p->u.qpsk.symbol_rate = c->symbol_rate; p->u.qpsk.fec_inner = c->fec_inner; break; @@ -1219,6 +1277,21 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_API_VERSION: tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR; break; + case DTV_CODE_RATE_HP: + tvp->u.data = fe->dtv_property_cache.code_rate_HP; + break; + case DTV_CODE_RATE_LP: + tvp->u.data = fe->dtv_property_cache.code_rate_LP; + break; + case DTV_GUARD_INTERVAL: + tvp->u.data = fe->dtv_property_cache.guard_interval; + break; + case DTV_TRANSMISSION_MODE: + tvp->u.data = fe->dtv_property_cache.transmission_mode; + break; + case DTV_HIERARCHY: + tvp->u.data = fe->dtv_property_cache.hierarchy; + break; default: r = -1; } @@ -1309,6 +1382,21 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, (void *)fe->dtv_property_cache.sectone); break; + case DTV_CODE_RATE_HP: + fe->dtv_property_cache.code_rate_HP = tvp->u.data; + break; + case DTV_CODE_RATE_LP: + fe->dtv_property_cache.code_rate_LP = tvp->u.data; + break; + case DTV_GUARD_INTERVAL: + fe->dtv_property_cache.guard_interval = tvp->u.data; + break; + case DTV_TRANSMISSION_MODE: + fe->dtv_property_cache.transmission_mode = tvp->u.data; + break; + case DTV_HIERARCHY: + fe->dtv_property_cache.hierarchy = tvp->u.data; + break; default: r = -1; } @@ -1371,7 +1459,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, /* Put an arbitrary limit on the number of messages that can * be sent at once */ - if (tvps->num > DTV_IOCTL_MAX_MSGS) + if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; tvp = (struct dtv_property *) kmalloc(tvps->num * @@ -1406,7 +1494,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, /* Put an arbitrary limit on the number of messages that can * be sent at once */ - if (tvps->num > DTV_IOCTL_MAX_MSGS) + if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; tvp = (struct dtv_property *) kmalloc(tvps->num * diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 57bb470bd..3c13bcfa6 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -253,6 +253,8 @@ config DVB_USB_DW2102 depends on DVB_USB select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE + select DVB_STV0288 if !DVB_FE_CUSTOMISE + select DVB_STB6000 if !DVB_FE_CUSTOMISE select DVB_CX24116 if !DVB_FE_CUSTOMISE select DVB_SI21XX if !DVB_FE_CUSTOMISE help diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.c b/linux/drivers/media/dvb/dvb-usb/dw2102.c index 20ba3f129..ca53df61c 100644 --- a/linux/drivers/media/dvb/dvb-usb/dw2102.c +++ b/linux/drivers/media/dvb/dvb-usb/dw2102.c @@ -14,6 +14,9 @@ #include "si21xx.h" #include "stv0299.h" #include "z0194a.h" +#include "stv0288.h" +#include "stb6000.h" +#include "eds1547.h" #include "cx24116.h" #ifndef USB_PID_DW2102 @@ -199,6 +202,78 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, mutex_unlock(&d->i2c_mutex); return num; } +static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int ret = 0; + + if (!d) + return -ENODEV; + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + switch (num) { + case 2: { + /* read */ + /* first write first register number */ + u8 ibuf [msg[1].len + 2], obuf[3]; + obuf[0] = 0xd0; + obuf[1] = msg[0].len; + obuf[2] = msg[0].buf[0]; + ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, + obuf, msg[0].len + 2, DW210X_WRITE_MSG); + /* second read registers */ + ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0, + ibuf, msg[1].len + 2, DW210X_READ_MSG); + memcpy(msg[1].buf, ibuf + 2, msg[1].len); + + break; + } + case 1: + switch (msg[0].addr) { + case 0x68: { + /* write to register */ + u8 obuf[msg[0].len + 2]; + obuf[0] = 0xd0; + obuf[1] = msg[0].len; + memcpy(obuf + 2, msg[0].buf, msg[0].len); + ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, + obuf, msg[0].len + 2, DW210X_WRITE_MSG); + break; + } + case 0x61: { + /* write to tuner */ + u8 obuf[msg[0].len + 2]; + obuf[0] = 0xc2; + obuf[1] = msg[0].len; + memcpy(obuf + 2, msg[0].buf, msg[0].len); + ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, + obuf, msg[0].len + 2, DW210X_WRITE_MSG); + break; + } + case(DW2102_RC_QUERY): { + u8 ibuf[2]; + ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, + ibuf, 2, DW210X_READ_MSG); + memcpy(msg[0].buf, ibuf , 2); + break; + } + case(DW2102_VOLTAGE_CTRL): { + u8 obuf[2]; + obuf[0] = 0x30; + obuf[1] = msg[0].buf[0]; + ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, + obuf, 2, DW210X_WRITE_MSG); + break; + } + } + + break; + } + + mutex_unlock(&d->i2c_mutex); + return num; +} static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { @@ -297,6 +372,11 @@ static struct i2c_algorithm dw2102_serit_i2c_algo = { .functionality = dw210x_i2c_func, }; +static struct i2c_algorithm dw2102_earda_i2c_algo = { + .master_xfer = dw2102_earda_i2c_transfer, + .functionality = dw210x_i2c_func, +}; + static struct i2c_algorithm dw2104_i2c_algo = { .master_xfer = dw2104_i2c_transfer, .functionality = dw210x_i2c_func, @@ -378,6 +458,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) return 0; } } + if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { + /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ + d->fe = dvb_attach(stv0288_attach, &earda_config, + &d->dev->i2c_adap); + if (d->fe != NULL) { + d->fe->ops.set_voltage = dw210x_set_voltage; + info("Attached stv0288!\n"); + return 0; + } + } + if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) { /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, @@ -398,6 +489,14 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap) +{ + dvb_attach(stb6000_attach, adap->fe, 0x61, + &adap->dev->i2c_adap); + + return 0; +} + static struct dvb_usb_rc_key dw210x_rc_keys[] = { { 0xf8, 0x0a, KEY_Q }, /*power*/ { 0xf8, 0x0c, KEY_M }, /*mute*/ @@ -478,7 +577,7 @@ static int dw2102_load_firmware(struct usb_device *dev, u8 *b, *p; int ret = 0, i; u8 reset; - u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0}; + u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; const struct firmware *fw; const char *filename = "dvb-usb-dw2101.fw"; switch (dev->descriptor.idProduct) { @@ -544,9 +643,25 @@ static int dw2102_load_firmware(struct usb_device *dev, /* check STV0299 frontend */ dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, DW210X_READ_MSG); - if (reset16[0] == 0xa1) + if (reset16[0] == 0xa1) { dw2102_properties.i2c_algo = &dw2102_i2c_algo; - break; + dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach; + break; + } else { + /* check STV0288 frontend */ + reset16[0] = 0xd0; + reset16[1] = 1; + reset16[2] = 0; + dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3, + DW210X_WRITE_MSG); + dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3, + DW210X_READ_MSG); + if (reset16[2] == 0x11) { + dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; + dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach; + break; + } + } case 0x2101: dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, DW210X_READ_MSG); @@ -586,7 +701,7 @@ static struct dvb_usb_device_properties dw2102_properties = { { .frontend_attach = dw2102_frontend_attach, .streaming_ctrl = NULL, - .tuner_attach = dw2102_tuner_attach, + .tuner_attach = NULL, .stream = { .type = USB_BULK, .count = 8, diff --git a/linux/drivers/media/dvb/frontends/cx24116.c b/linux/drivers/media/dvb/frontends/cx24116.c index 163190d54..3c58b9f57 100644 --- a/linux/drivers/media/dvb/frontends/cx24116.c +++ b/linux/drivers/media/dvb/frontends/cx24116.c @@ -57,8 +57,9 @@ static int debug = 0; #define CX24116_REG_RESET (0x20) /* reset status > 0 */ #define CX24116_REG_SIGNAL (0x9e) /* signal low */ #define CX24116_REG_SSTATUS (0x9d) /* signal high / status */ +#define CX24116_REG_QUALITY8 (0xa3) #define CX24116_REG_QSTATUS (0xbc) -#define CX24116_REG_QUALITY (0xd5) +#define CX24116_REG_QUALITY0 (0xd5) #define CX24116_REG_BER0 (0xc9) #define CX24116_REG_BER8 (0xc8) #define CX24116_REG_BER16 (0xc7) @@ -84,7 +85,8 @@ static int debug = 0; #define CX24116_ROLLOFF_035 (0x02) /* pilot bit */ -#define CX24116_PILOT (0x40) +#define CX24116_PILOT_OFF (0x00) +#define CX24116_PILOT_ON (0x40) /* signal status */ #define CX24116_HAS_SIGNAL (0x01) @@ -115,6 +117,9 @@ static int debug = 0; /* DiSEqC tone burst */ static int toneburst = 1; +/* SNR measurements */ +static int esno_snr = 0; + enum cmds { CMD_SET_VCO = 0x10, @@ -148,6 +153,7 @@ struct cx24116_tuning u8 fec_val; u8 fec_mask; u8 inversion_val; + u8 pilot_val; u8 rolloff_val; }; @@ -342,6 +348,7 @@ static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_invers * a scheme are support. Especially, no auto detect when in S2 mode. */ struct cx24116_modfec { + fe_delivery_system_t delivery_system; fe_modulation_t modulation; fe_code_rate_t fec; u8 mask; /* In DVBS mode this is used to autodetect */ @@ -350,32 +357,32 @@ struct cx24116_modfec { /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */ /*mod fec mask val */ - { QPSK, FEC_NONE, 0xfe, 0x30 }, - { QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */ - { QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */ - { QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */ - { QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */ - { QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */ - { QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */ - { QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */ - { QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */ - { QPSK, FEC_AUTO, 0xfe, 0x30 }, + { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 }, + { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */ + { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */ + { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */ + { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */ + { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */ + { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */ + { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */ + { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */ + { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 }, /* NBC-QPSK */ - { NBC_QPSK, FEC_1_2, 0x00, 0x04 }, - { NBC_QPSK, FEC_3_5, 0x00, 0x05 }, - { NBC_QPSK, FEC_2_3, 0x00, 0x06 }, - { NBC_QPSK, FEC_3_4, 0x00, 0x07 }, - { NBC_QPSK, FEC_4_5, 0x00, 0x08 }, - { NBC_QPSK, FEC_5_6, 0x00, 0x09 }, - { NBC_QPSK, FEC_8_9, 0x00, 0x0a }, - { NBC_QPSK, FEC_9_10, 0x00, 0x0b }, + { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 }, + { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 }, + { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 }, + { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 }, + { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 }, + { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 }, + { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a }, + { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b }, /* 8PSK */ - { _8PSK, FEC_3_5, 0x00, 0x0c }, - { _8PSK, FEC_2_3, 0x00, 0x0d }, - { _8PSK, FEC_3_4, 0x00, 0x0e }, - { _8PSK, FEC_5_6, 0x00, 0x0f }, - { _8PSK, FEC_8_9, 0x00, 0x10 }, - { _8PSK, FEC_9_10, 0x00, 0x11 }, + { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c }, + { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d }, + { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e }, + { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f }, + { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 }, + { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 }, /* * `val' can be found in the FECSTATUS register when tuning. * FECSTATUS will give the actual FEC in use if tuning was successful. @@ -700,7 +707,7 @@ static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_str } /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ -static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) +static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr) { struct cx24116_state *state = fe->demodulator_priv; u8 snr_reading; @@ -711,7 +718,7 @@ static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) dprintk("%s()\n", __func__); - snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY); + snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); if(snr_reading >= 0xa0 /* 100% */) *snr = 0xffff; @@ -725,6 +732,32 @@ static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) return 0; } +/* The reelbox patches show the value in the registers represents + * ESNO, from 0->30db (values 0->300). We provide this value by + * default. + */ +static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr) +{ + struct cx24116_state *state = fe->demodulator_priv; + + dprintk("%s()\n", __func__); + + *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 | + cx24116_readreg(state, CX24116_REG_QUALITY0); + + dprintk("%s: raw 0x%04x\n", __func__, *snr); + + return 0; +} + +static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) +{ + if (esno_snr == 1) + return cx24116_read_snr_esno(fe, snr); + else + return cx24116_read_snr_pct(fe, snr); +} + static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) { struct cx24116_state *state = fe->demodulator_priv; @@ -1138,25 +1171,62 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct cx24116_cmd cmd; fe_status_t tunerstat; - int i, status, ret, retune = 1; + int i, status, ret, retune; dprintk("%s()\n",__func__); - state->dnxt.modulation = c->modulation; - state->dnxt.frequency = c->frequency; - switch(c->delivery_system) { case SYS_DVBS: dprintk("%s: DVB-S delivery system selected\n",__func__); - state->dnxt.pilot = PILOT_OFF; + + /* Only QPSK is supported for DVB-S */ + if(c->modulation != QPSK) { + dprintk("%s: unsupported modulation selected (%d)\n", + __func__, c->modulation); + return -EOPNOTSUPP; + } + + /* Pilot doesn't exist in DVB-S, turn bit off */ + state->dnxt.pilot_val = CX24116_PILOT_OFF; + retune = 1; + + /* DVB-S only supports 0.35 */ + if(c->rolloff != ROLLOFF_35) { + dprintk("%s: unsupported rolloff selected (%d)\n", + __func__, c->rolloff); + return -EOPNOTSUPP; + } state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - state->dnxt.rolloff = c->rolloff; break; + case SYS_DVBS2: dprintk("%s: DVB-S2 delivery system selected\n",__func__); - if(c->pilot == PILOT_AUTO) - retune++; - state->dnxt.pilot = c->pilot; + + /* + * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, + * but not hardware auto detection + */ + if(c->modulation != PSK_8 && c->modulation != QPSK) { + dprintk("%s: unsupported modulation selected (%d)\n", + __func__, c->modulation); + return -EOPNOTSUPP; + } + + switch(c->pilot) { + case PILOT_AUTO: /* Not supported but emulated */ + retune = 2; /* Fall-through */ + case PILOT_OFF: + state->dnxt.pilot_val = CX24116_PILOT_OFF; + break; + case PILOT_ON: + state->dnxt.pilot_val = CX24116_PILOT_ON; + break; + default: + dprintk("%s: unsupported pilot mode selected (%d)\n", + __func__, c->pilot); + return -EOPNOTSUPP; + } + switch(c->rolloff) { case ROLLOFF_20: state->dnxt.rolloff_val= CX24116_ROLLOFF_020; @@ -1167,20 +1237,28 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par case ROLLOFF_35: state->dnxt.rolloff_val= CX24116_ROLLOFF_035; break; - case ROLLOFF_AUTO: + case ROLLOFF_AUTO: /* Rolloff must be explicit */ + default: + dprintk("%s: unsupported rolloff selected (%d)\n", + __func__, c->rolloff); return -EOPNOTSUPP; } - state->dnxt.rolloff = c->rolloff; break; + default: dprintk("%s: unsupported delivery system selected (%d)\n", __func__, c->delivery_system); return -EOPNOTSUPP; } + state->dnxt.modulation = c->modulation; + state->dnxt.frequency = c->frequency; + state->dnxt.pilot = c->pilot; + state->dnxt.rolloff = c->rolloff; if ((ret = cx24116_set_inversion(state, c->inversion)) != 0) return ret; + /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0) return ret; @@ -1190,10 +1268,13 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par /* discard the 'current' tuning parameters and prepare to tune */ cx24116_clone_params(fe); - dprintk("%s: retune = %d\n", __func__, retune); - dprintk("%s: rolloff = %d\n", __func__, state->dcur.rolloff); - dprintk("%s: pilot = %d\n", __func__, state->dcur.pilot); + dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation); dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); + dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__, + state->dcur.pilot, state->dcur.pilot_val); + dprintk("%s: retune = %d\n", __func__, retune); + dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__, + state->dcur.rolloff, state->dcur.rolloff_val); dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); @@ -1227,11 +1308,8 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par /* Automatic Inversion */ cmd.args[0x06] = state->dcur.inversion_val; - /* Modulation / FEC & Pilot Off */ - cmd.args[0x07] = state->dcur.fec_val; - - if (state->dcur.pilot == PILOT_ON) - cmd.args[0x07] |= CX24116_PILOT; + /* Modulation / FEC / Pilot */ + cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val; cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8; cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff; @@ -1294,7 +1372,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par /* Toggle pilot bit when in auto-pilot */ if(state->dcur.pilot == PILOT_AUTO) - cmd.args[0x07] ^= CX24116_PILOT; + cmd.args[0x07] ^= CX24116_PILOT_ON; } while(--retune); @@ -1352,6 +1430,9 @@ MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); module_param(toneburst, int, 0644); MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)"); +module_param(esno_snr, int, 0644); +MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)"); + MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/eds1547.h b/linux/drivers/media/dvb/frontends/eds1547.h new file mode 100644 index 000000000..fa79b7c83 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/eds1547.h @@ -0,0 +1,133 @@ +/* eds1547.h Earda EDS-1547 tuner support +* +* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation, version 2. +* +* see Documentation/dvb/README.dvb-usb for more information +*/ + +#ifndef EDS1547 +#define EDS1547 + +static u8 stv0288_earda_inittab[] = { + 0x01, 0x57, + 0x02, 0x20, + 0x03, 0x8e, + 0x04, 0x8e, + 0x05, 0x12, + 0x06, 0x00, + 0x07, 0x00, + 0x09, 0x00, + 0x0a, 0x04, + 0x0b, 0x00, + 0x0c, 0x00, + 0x0d, 0x00, + 0x0e, 0xd4, + 0x0f, 0x30, + 0x11, 0x44, + 0x12, 0x03, + 0x13, 0x48, + 0x14, 0x84, + 0x15, 0x45, + 0x16, 0xb7, + 0x17, 0x9c, + 0x18, 0x00, + 0x19, 0xa6, + 0x1a, 0x88, + 0x1b, 0x8f, + 0x1c, 0xf0, + 0x20, 0x0b, + 0x21, 0x54, + 0x22, 0x00, + 0x23, 0x00, + 0x2b, 0xff, + 0x2c, 0xf7, + 0x30, 0x00, + 0x31, 0x1e, + 0x32, 0x14, + 0x33, 0x0f, + 0x34, 0x09, + 0x35, 0x0c, + 0x36, 0x05, + 0x37, 0x2f, + 0x38, 0x16, + 0x39, 0xbd, + 0x3a, 0x00, + 0x3b, 0x13, + 0x3c, 0x11, + 0x3d, 0x30, + 0x40, 0x63, + 0x41, 0x04, + 0x42, 0x60, + 0x43, 0x00, + 0x44, 0x00, + 0x45, 0x00, + 0x46, 0x00, + 0x47, 0x00, + 0x4a, 0x00, + 0x50, 0x10, + 0x51, 0x36, + 0x52, 0x09, + 0x53, 0x94, + 0x54, 0x62, + 0x55, 0x29, + 0x56, 0x64, + 0x57, 0x2b, + 0x58, 0x54, + 0x59, 0x86, + 0x5a, 0x00, + 0x5b, 0x9b, + 0x5c, 0x08, + 0x5d, 0x7f, + 0x5e, 0x00, + 0x5f, 0xff, + 0x70, 0x00, + 0x71, 0x00, + 0x72, 0x00, + 0x74, 0x00, + 0x75, 0x00, + 0x76, 0x00, + 0x81, 0x00, + 0x82, 0x3f, + 0x83, 0x3f, + 0x84, 0x00, + 0x85, 0x00, + 0x88, 0x00, + 0x89, 0x00, + 0x8a, 0x00, + 0x8b, 0x00, + 0x8c, 0x00, + 0x90, 0x00, + 0x91, 0x00, + 0x92, 0x00, + 0x93, 0x00, + 0x94, 0x1c, + 0x97, 0x00, + 0xa0, 0x48, + 0xa1, 0x00, + 0xb0, 0xb8, + 0xb1, 0x3a, + 0xb2, 0x10, + 0xb3, 0x82, + 0xb4, 0x80, + 0xb5, 0x82, + 0xb6, 0x82, + 0xb7, 0x82, + 0xb8, 0x20, + 0xb9, 0x00, + 0xf0, 0x00, + 0xf1, 0x00, + 0xf2, 0xc0, + 0xff,0xff, +}; + +static struct stv0288_config earda_config = { + .demod_address = 0x68, + .min_delay_ms = 100, + .inittab = stv0288_earda_inittab, +}; + +#endif diff --git a/linux/drivers/media/dvb/frontends/stb6000.c b/linux/drivers/media/dvb/frontends/stb6000.c index a0ece4278..43e583a44 100644 --- a/linux/drivers/media/dvb/frontends/stb6000.c +++ b/linux/drivers/media/dvb/frontends/stb6000.c @@ -202,12 +202,13 @@ struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) { struct stb6000_priv *priv = NULL; + u8 b0[] = { 0 }; u8 b1[] = { 0, 0 }; struct i2c_msg msg[2] = { { .addr = addr, .flags = 0, - .buf = NULL, + .buf = b0, .len = 0 }, { .addr = addr, diff --git a/linux/drivers/media/dvb/frontends/stv0288.c b/linux/drivers/media/dvb/frontends/stv0288.c index 90e72e771..ff1194de3 100644 --- a/linux/drivers/media/dvb/frontends/stv0288.c +++ b/linux/drivers/media/dvb/frontends/stv0288.c @@ -328,16 +328,28 @@ static int stv0288_init(struct dvb_frontend *fe) { struct stv0288_state *state = fe->demodulator_priv; int i; + u8 reg; + u8 val; dprintk("stv0288: init chip\n"); stv0288_writeregI(state, 0x41, 0x04); msleep(50); - for (i = 0; !(stv0288_inittab[i] == 0xff && + /* we have default inittab */ + if (state->config->inittab == NULL) { + for (i = 0; !(stv0288_inittab[i] == 0xff && stv0288_inittab[i + 1] == 0xff); i += 2) - stv0288_writeregI(state, stv0288_inittab[i], - stv0288_inittab[i + 1]); - + stv0288_writeregI(state, stv0288_inittab[i], + stv0288_inittab[i + 1]); + } else { + for (i = 0; ; i += 2) { + reg = state->config->inittab[i]; + val = state->config->inittab[i+1]; + if (reg == 0xff && val == 0xff) + break; + stv0288_writeregI(state, reg, val); + } + } return 0; } diff --git a/linux/drivers/media/dvb/frontends/stv0288.h b/linux/drivers/media/dvb/frontends/stv0288.h index aa0cdd273..f2b53db06 100644 --- a/linux/drivers/media/dvb/frontends/stv0288.h +++ b/linux/drivers/media/dvb/frontends/stv0288.h @@ -34,6 +34,8 @@ struct stv0288_config { /* the demodulator's i2c address */ u8 demod_address; + u8* inittab; + /* minimum delay before retuning */ int min_delay_ms; diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index 60513e48f..a351a2220 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -1855,6 +1855,18 @@ static const struct cx88_board cx88_boards[] = { } }, .mpeg = CX88_MPEG_DVB, }, + [CX88_BOARD_PROF_7300] = { + .name = "PROF 7300 DVB-S/S2", + .tuner_type = UNSET, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .input = {{ + .type = CX88_VMUX_DVB, + .vmux = 0, + } }, + .mpeg = CX88_MPEG_DVB, + }, }; /* ------------------------------------------------------------------ */ @@ -2244,6 +2256,10 @@ static const struct cx88_subid cx88_subids[] = { .subvendor = 0x8920, .subdevice = 0x8888, .card = CX88_BOARD_TBS_8920, + }, { + .subvendor = 0xB033, + .subdevice = 0x3033, + .card = CX88_BOARD_PROF_7300, }, }; @@ -2850,18 +2866,9 @@ static void cx88_card_setup(struct cx88_core *core) } case CX88_BOARD_TEVII_S420: case CX88_BOARD_TEVII_S460: - cx_write(MO_SRST_IO, 0); - msleep(100); - cx_write(MO_SRST_IO, 1); - msleep(100); - break; case CX88_BOARD_OMICOM_SS4_PCI: - cx_write(MO_SRST_IO, 0); - msleep(100); - cx_write(MO_SRST_IO, 1); - msleep(100); - break; case CX88_BOARD_TBS_8920: + case CX88_BOARD_PROF_7300: cx_write(MO_SRST_IO, 0); msleep(100); cx_write(MO_SRST_IO, 1); diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index da1ad2b6b..84f235ba0 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -985,15 +985,8 @@ static int dvb_register(struct cx8802_dev *dev) } break; case CX88_BOARD_OMICOM_SS4_PCI: - dev->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &core->i2c_adap); - if (dev->dvb.frontend != NULL) { - core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; - dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - } - break; case CX88_BOARD_TBS_8920: + case CX88_BOARD_PROF_7300: dev->dvb.frontend = dvb_attach(cx24116_attach, &hauppauge_hvr4000_config, &core->i2c_adap); diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index e42ce0016..778e1f707 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -229,6 +229,7 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_TBS_8920 72 #define CX88_BOARD_TEVII_S420 73 #define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74 +#define CX88_BOARD_PROF_7300 75 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, diff --git a/linux/include/linux/dvb/frontend.h b/linux/include/linux/dvb/frontend.h index d28f21796..72cb8ae55 100644 --- a/linux/include/linux/dvb/frontend.h +++ b/linux/include/linux/dvb/frontend.h @@ -164,9 +164,8 @@ typedef enum fe_modulation { QAM_AUTO, VSB_8, VSB_16, - _8PSK, - _16APSK, - NBC_QPSK, + PSK_8, + APSK_16, DQPSK, } fe_modulation_t; @@ -300,6 +299,14 @@ struct dvb_frontend_event { #define DTV_ISDB_LAYERC_TIME_INTERLEAVING 34 #endif #define DTV_API_VERSION 35 +#define DTV_API_VERSION 35 +#define DTV_CODE_RATE_HP 36 +#define DTV_CODE_RATE_LP 37 +#define DTV_GUARD_INTERVAL 38 +#define DTV_TRANSMISSION_MODE 39 +#define DTV_HIERARCHY 40 + +#define DTV_MAX_COMMAND DTV_HIERARCHY typedef enum fe_pilot { PILOT_ON, @@ -308,9 +315,9 @@ typedef enum fe_pilot { } fe_pilot_t; typedef enum fe_rolloff { + ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */ ROLLOFF_20, ROLLOFF_25, - ROLLOFF_35, ROLLOFF_AUTO, } fe_rolloff_t; @@ -358,14 +365,14 @@ struct dtv_property { int result; } __attribute__ ((packed)); -/* No more than 16 properties during any given ioctl */ +/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */ +#define DTV_IOCTL_MAX_MSGS 64 + struct dtv_properties { __u32 num; struct dtv_property *props; }; -#define DTV_IOCTL_MAX_MSGS 64 - #define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties) #define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties) |