From aa8de0afdd1a794bcd8f80c83ca7710c0050894a Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 15 Apr 2009 19:45:10 -0400 Subject: cx18: Simplify the work handler for outgoing mailbox commands From: Andy Walls Simplify the way outgoing work handler gets scheduled to send empty buffers back to the firmware for use. Also reduced the memory required for scheduling this outgoing work, by using a single, per stream work object. Priority: normal Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-dvb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/video/cx18/cx18-dvb.c') diff --git a/linux/drivers/media/video/cx18/cx18-dvb.c b/linux/drivers/media/video/cx18/cx18-dvb.c index 3b86f57cd..e7285a109 100644 --- a/linux/drivers/media/video/cx18/cx18-dvb.c +++ b/linux/drivers/media/video/cx18/cx18-dvb.c @@ -23,6 +23,7 @@ #include "cx18-version.h" #include "cx18-dvb.h" #include "cx18-io.h" +#include "cx18-queue.h" #include "cx18-streams.h" #include "cx18-cards.h" #include "s5h1409.h" -- cgit v1.2.3 From 4b038fe7fa0a646fedf0e49aa2bfba38c814e3ad Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Tue, 9 Jun 2009 19:47:21 -0400 Subject: cx18: Add DVB-T support for the Leadtek WinFast DVR3100 H From: Andy Walls This adds support for DVB-T on the Leadtek DVR3100 H and should also get analog TV capture from the tuner working properly as well. DVB-T 6 MHz and 8 MHz have been tested and verified to work by Terry Wu of Leadtek. DVB-T 7 MHz has also been verified working with a change developed by Terry to the tuner-xc2028.c driver. Special thanks go to Terry Wu of Leadtek who provided the needed information and testing to get digital TV working for the Leadtek DVR3100 H. Reported-by: Terry Wu Priority: normal Tested-by: Terry Wu Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-dvb.c | 53 +++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/video/cx18/cx18-dvb.c') diff --git a/linux/drivers/media/video/cx18/cx18-dvb.c b/linux/drivers/media/video/cx18/cx18-dvb.c index e7285a109..6ea3fe623 100644 --- a/linux/drivers/media/video/cx18/cx18-dvb.c +++ b/linux/drivers/media/video/cx18/cx18-dvb.c @@ -26,12 +26,17 @@ #include "cx18-queue.h" #include "cx18-streams.h" #include "cx18-cards.h" +#include "cx18-gpio.h" #include "s5h1409.h" #include "mxl5005s.h" +#include "zl10353.h" +#include "tuner-xc2028.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 +#define CX18_CLOCK_ENABLE2 0xc71024 +#define CX18_DMUX_CLK_MASK 0x0080 static struct mxl5005s_config hauppauge_hvr1600_tuner = { .i2c_address = 0xC6 >> 1, @@ -58,7 +63,15 @@ static struct s5h1409_config hauppauge_hvr1600_config = { .inversion = S5H1409_INVERSION_OFF, .status_mode = S5H1409_DEMODLOCKING, .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK +}; +/* Information/confirmation of proper config values provided by Terry Wu */ +static struct zl10353_config leadtek_dvr3100h_demod = { + .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ + .if2 = 45600, /* 4.560 MHz IF from the XC3028 */ + .parallel_ts = 1, /* Not a serial TS */ + .no_tuner = 1, /* XC3028 is not behind the gate */ + .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ }; static int dvb_register(struct cx18_stream *stream); @@ -99,6 +112,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); break; + case CX18_CARD_LEADTEK_DVR3100H: default: /* Assumption - Parallel transport - Signalling * undefined or default. @@ -268,8 +282,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream) } /* All the DVB attach calls go here, this function get's modified - * for each new card. No other function in this file needs - * to change. + * for each new card. cx18_dvb_start_feed() will also need changes. */ static int dvb_register(struct cx18_stream *stream) { @@ -290,6 +303,29 @@ static int dvb_register(struct cx18_stream *stream) ret = 0; } break; + case CX18_CARD_LEADTEK_DVR3100H: + dvb->fe = dvb_attach(zl10353_attach, + &leadtek_dvr3100h_demod, + &cx->i2c_adap[1]); + if (dvb->fe != NULL) { + struct dvb_frontend *fe; + struct xc2028_config cfg = { + .i2c_adap = &cx->i2c_adap[1], + .i2c_addr = 0xc2 >> 1, + .ctrl = NULL, + }; + static struct xc2028_ctrl ctrl = { + .fname = XC2028_DEFAULT_FIRMWARE, + .max_len = 64, + .demod = XC3028_FE_ZARLINK456, + .type = XC2028_AUTO, + }; + + fe = dvb_attach(xc2028_attach, dvb->fe, &cfg); + if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) + fe->ops.tuner_ops.set_config(fe, &ctrl); + } + break; default: /* No Digital Tv Support */ break; @@ -300,6 +336,8 @@ static int dvb_register(struct cx18_stream *stream) return -1; } + dvb->fe->callback = cx18_reset_tuner_gpio; + ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); if (ret < 0) { if (dvb->fe->ops.release) @@ -307,5 +345,16 @@ static int dvb_register(struct cx18_stream *stream) return ret; } + /* + * The firmware seems to enable the TS DMUX clock + * under various circumstances. However, since we know we + * might use it, let's just turn it on ourselves here. + */ + cx18_write_reg_expect(cx, + (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK, + CX18_CLOCK_ENABLE2, + CX18_DMUX_CLK_MASK, + (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK); + return ret; } -- cgit v1.2.3 From 249b5a4539777b7bbc76ce4ce3b7207113098925 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 3 Jul 2009 10:54:40 -0400 Subject: cx18: Add DVB-T support for Yuan MPC-718 cards with an MT352 or ZL10353 From: Andy Walls Add DVB-T support for Yuan MPC-718 cards with an MT352 or ZL10353 demodulator. There are apparently some units with a DiBcom demodulator which could be supported by one of the dib7000 modules - but this is not implemented in the cx18 driver (yet). Due to lack of porgramming details for the MT352 and the mt352 module requiring a "demod_init" function, a "firmware" must be obtained and loaded to get DVB-T working for Yuan MPC-718 cards with an MT352. Priority: normal Tested-by: Steve Firth Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-dvb.c | 160 ++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) (limited to 'linux/drivers/media/video/cx18/cx18-dvb.c') diff --git a/linux/drivers/media/video/cx18/cx18-dvb.c b/linux/drivers/media/video/cx18/cx18-dvb.c index 6ea3fe623..51a0c33b2 100644 --- a/linux/drivers/media/video/cx18/cx18-dvb.c +++ b/linux/drivers/media/video/cx18/cx18-dvb.c @@ -30,6 +30,10 @@ #include "s5h1409.h" #include "mxl5005s.h" #include "zl10353.h" + +#include +#include "mt352.h" +#include "mt352_priv.h" #include "tuner-xc2028.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -38,6 +42,11 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define CX18_CLOCK_ENABLE2 0xc71024 #define CX18_DMUX_CLK_MASK 0x0080 +/* + * CX18_CARD_HVR_1600_ESMT + * CX18_CARD_HVR_1600_SAMSUNG + */ + static struct mxl5005s_config hauppauge_hvr1600_tuner = { .i2c_address = 0xC6 >> 1, .if_freq = IF_FREQ_5380000HZ, @@ -65,6 +74,9 @@ static struct s5h1409_config hauppauge_hvr1600_config = { .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK }; +/* + * CX18_CARD_LEADTEK_DVR3100H + */ /* Information/confirmation of proper config values provided by Terry Wu */ static struct zl10353_config leadtek_dvr3100h_demod = { .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ @@ -74,6 +86,121 @@ static struct zl10353_config leadtek_dvr3100h_demod = { .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ }; +/* + * CX18_CARD_YUAN_MPC718 + */ +/* + * Due to + * + * 1. an absence of information on how to prgram the MT352 + * 2. the Linux mt352 module pushing MT352 initialzation off onto us here + * + * We have to use an init sequence that *you* must extract from the Windows + * driver (yuanrap.sys) and which we load as a firmware. + * + * If someone can provide me with a Zarlink MT352 (Intel CE6352?) Design Manual + * with chip programming details, then I can remove this annoyance. + */ +static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream, + const struct firmware **fw) +{ + struct cx18 *cx = stream->cx; + const char *fn = "dvb-cx18-mpc718-mt352.fw"; + int ret; + + ret = request_firmware(fw, fn, &cx->pci_dev->dev); + if (ret) + CX18_ERR("Unable to open firmware file %s\n", fn); + else { + size_t sz = (*fw)->size; + if (sz < 2 || sz > 64 || (sz % 2) != 0) { + CX18_ERR("Firmware %s has a bad size: %lu bytes\n", + fn, (unsigned long) sz); + ret = -EILSEQ; + release_firmware(*fw); + *fw = NULL; + } + } + + if (ret) { + CX18_ERR("The MPC718 board variant with the MT352 DVB-T" + "demodualtor will not work without it\n"); + CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware " + "mpc718' if you need the firmware\n"); + } + return ret; +} + +static int yuan_mpc718_mt352_init(struct dvb_frontend *fe) +{ + struct cx18_dvb *dvb = container_of(fe->dvb, + struct cx18_dvb, dvb_adapter); + struct cx18_stream *stream = container_of(dvb, struct cx18_stream, dvb); + const struct firmware *fw = NULL; + int ret; + int i; + u8 buf[3]; + + ret = yuan_mpc718_mt352_reqfw(stream, &fw); + if (ret) + return ret; + + /* Loop through all the register-value pairs in the firmware file */ + for (i = 0; i < fw->size; i += 2) { + buf[0] = fw->data[i]; + /* Intercept a few registers we want to set ourselves */ + switch (buf[0]) { + case TRL_NOMINAL_RATE_0: + /* Set our custom OFDM bandwidth in the case below */ + break; + case TRL_NOMINAL_RATE_1: + /* 6 MHz: 64/7 * 6/8 / 20.48 * 2^16 = 0x55b6.db6 */ + /* 7 MHz: 64/7 * 7/8 / 20.48 * 2^16 = 0x6400 */ + /* 8 MHz: 64/7 * 8/8 / 20.48 * 2^16 = 0x7249.249 */ + buf[1] = 0x72; + buf[2] = 0x49; + mt352_write(fe, buf, 3); + break; + case INPUT_FREQ_0: + /* Set our custom IF in the case below */ + break; + case INPUT_FREQ_1: + /* 4.56 MHz IF: (20.48 - 4.56)/20.48 * 2^14 = 0x31c0 */ + buf[1] = 0x31; + buf[2] = 0xc0; + mt352_write(fe, buf, 3); + break; + default: + /* Pass through the register-value pair from the fw */ + buf[1] = fw->data[i+1]; + mt352_write(fe, buf, 2); + break; + } + } + + buf[0] = (u8) TUNER_GO; + buf[1] = 0x01; /* Go */ + mt352_write(fe, buf, 2); + release_firmware(fw); + return 0; +} + +static struct mt352_config yuan_mpc718_mt352_demod = { + .demod_address = 0x1e >> 1, + .adc_clock = 20480, /* 20.480 MHz */ + .if2 = 4560, /* 4.560 MHz */ + .no_tuner = 1, /* XC3028 is not behind the gate */ + .demod_init = yuan_mpc718_mt352_init, +}; + +static struct zl10353_config yuan_mpc718_zl10353_demod = { + .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ + .if2 = 45600, /* 4.560 MHz IF from the XC3028 */ + .parallel_ts = 1, /* Not a serial TS */ + .no_tuner = 1, /* XC3028 is not behind the gate */ + .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ +}; + static int dvb_register(struct cx18_stream *stream); /* Kernel DVB framework calls this when the feed needs to start. @@ -113,6 +240,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) break; case CX18_CARD_LEADTEK_DVR3100H: + case CX18_CARD_YUAN_MPC718: default: /* Assumption - Parallel transport - Signalling * undefined or default. @@ -326,6 +454,38 @@ static int dvb_register(struct cx18_stream *stream) fe->ops.tuner_ops.set_config(fe, &ctrl); } break; + case CX18_CARD_YUAN_MPC718: + /* + * TODO + * Apparently, these cards also could instead have a + * DiBcom demod supported by one of the db7000 drivers + */ + dvb->fe = dvb_attach(mt352_attach, + &yuan_mpc718_mt352_demod, + &cx->i2c_adap[1]); + if (dvb->fe == NULL) + dvb->fe = dvb_attach(zl10353_attach, + &yuan_mpc718_zl10353_demod, + &cx->i2c_adap[1]); + if (dvb->fe != NULL) { + struct dvb_frontend *fe; + struct xc2028_config cfg = { + .i2c_adap = &cx->i2c_adap[1], + .i2c_addr = 0xc2 >> 1, + .ctrl = NULL, + }; + static struct xc2028_ctrl ctrl = { + .fname = XC2028_DEFAULT_FIRMWARE, + .max_len = 64, + .demod = XC3028_FE_ZARLINK456, + .type = XC2028_AUTO, + }; + + fe = dvb_attach(xc2028_attach, dvb->fe, &cfg); + if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) + fe->ops.tuner_ops.set_config(fe, &ctrl); + } + break; default: /* No Digital Tv Support */ break; -- cgit v1.2.3