From bc1d3340bb49a953d61c32831705ab1b1d41390d Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sun, 21 Nov 2004 21:40:58 +0000 Subject: added support for the dib3000mc/p frontend driver. Micheal, sorry for being overhasty with the Kconfig from dibusb. --- linux/drivers/media/dvb/dibusb/dvb-dibusb.c | 135 ++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 27 deletions(-) (limited to 'linux/drivers/media/dvb/dibusb/dvb-dibusb.c') diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb.c index 713d66b1d..e7f83d964 100644 --- a/linux/drivers/media/dvb/dibusb/dvb-dibusb.c +++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb.c @@ -7,10 +7,8 @@ * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de) * * based on GPL code from DiBcom, which has - * * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) * - * * Remote control code added by David Matthews (dm@prolingua.co.uk) * * This program is free software; you can redistribute it and/or @@ -269,6 +267,13 @@ static const struct { u8 c0, c1, c2; uint32_t key; } rc_keys [] = { 0x00, 0xff, 0x4c, KEY_PAUSE }, { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */ { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ + /* additional keys TwinHan VisionPlus, the Artec seemingly not have */ + { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */ + { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */ + { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */ + { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */ + { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */ + { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */ /* Key codes for the KWorld/ADSTech/JetWay remote. */ { 0x86, 0x6b, 0x12, KEY_POWER }, { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */ @@ -354,7 +359,7 @@ static int dibusb_read_remote_control(struct usb_dibusb *dib) return 0; } -#define RC_QUERY_INTERVAL (100) /* milliseconds */ +#define RC_QUERY_INTERVAL (10000) /* milliseconds */ /* Remote-control poll function - called every RC_QUERY_INTERVAL ms to see whether the remote control has received anything. */ @@ -373,17 +378,11 @@ static void dibusb_query_rc (void *data) */ #if 0 - /* - * #if 0'ing the following 5 functions as they are not in use _now_, + * #if 0'ing the following functions as they are not in use _now_, * but probably will be sometime. */ -static int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len) -{ - return dibusb_readwrite_usb(dib,buf,len,NULL,0); -} - /* * do not use this, just a workaround for a bug, * which will hopefully never occur :). @@ -394,6 +393,21 @@ static int dibusb_interrupt_read_loop(struct usb_dibusb *dib) return dibusb_write_usb(dib,b,1); } +/* + * ioctl for power control + */ +static int dibusb_hw_sleep(struct usb_dibusb *dib) +{ + u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP }; + return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1); +} + +#endif +static int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len) +{ + return dibusb_readwrite_usb(dib,buf,len,NULL,0); +} + /* * ioctl for the firmware */ @@ -408,23 +422,12 @@ static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen) return dibusb_write_usb(dib,b,2+size); } -/* - * ioctl for power control - */ -static int dibusb_hw_sleep(struct usb_dibusb *dib) -{ - u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP }; - return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1); -} - static int dibusb_hw_wakeup(struct usb_dibusb *dib) { u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP }; return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1); } -#endif - /* * I2C */ @@ -457,15 +460,17 @@ static u32 dibusb_i2c_func(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } -static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); - +static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct + dvb_frontend_parameters* params); + static struct dib3000_config thomson_cable_eu_config = { .demod_address = 0x10, .pll_addr = 194, .pll_set = thomson_cable_eu_pll_set, }; -static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct + dvb_frontend_parameters* params) { struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; u8 buf[4]; @@ -492,7 +497,71 @@ static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct dvb_frontend buf[2] = 0x8e; buf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0; - if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1) return -EIO; + if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1) + return -EIO; + + msleep(1); + return 0; +} + +static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend *fe, struct + dvb_frontend_parameters *params); + +static struct dib3000_config panasonic_cofdm_env57h1xd5 = { + .demod_address = 0x18, + .pll_addr = 192, + .pll_set = panasonic_cofdm_env57h1xd5_pll_set, +}; + +static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend *fe, struct + dvb_frontend_parameters *params) +{ + struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv; + u8 buf[4]; + u32 freq = params->frequency; + u32 tfreq = (freq + 36125000) / 1000000 * 6 + 1; + u8 TA, T210, R210, ctrl1, cp210, p4321; + struct i2c_msg msg = { + .addr = panasonic_cofdm_env57h1xd5.pll_addr, + .flags = 0, + .buf = buf, + .len = sizeof(buf) + }; + + if (freq > 858000000) { + err("frequency cannot be larger than 858 MHz."); + return -EINVAL; + } + + // contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0 + TA = 1; + T210 = 0; + R210 = 0x2; + ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210; + +// ******** CHARGE PUMP CONFIG vs RF FREQUENCIES ***************** + if (freq < 470000000) + cp210 = 2; // VHF Low and High band ch E12 to E4 to E12 + else if (freq < 526000000) + cp210 = 4; // UHF band Ch E21 to E27 + else // if (freq < 862000000) + cp210 = 5; // UHF band ch E28 to E69 + +//********************* BW select ******************************* + if (freq < 153000000) + p4321 = 1; // BW selected for VHF low + else if (freq < 470000000) + p4321 = 2; // BW selected for VHF high E5 to E12 + else // if (freq < 862000000) + p4321 = 4; // BW selection for UHF E21 to E69 + + buf[0] = (tfreq >> 8) & 0xff; + buf[1] = (tfreq >> 0) & 0xff; + buf[2] = 0xff & ctrl1; + buf[3] = (cp210 << 5) | (p4321); + + if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1) + return -EIO; msleep(1); return 0; @@ -507,8 +576,16 @@ static struct i2c_algorithm dibusb_algo = { static void frontend_init(struct usb_dibusb* dib) { - dib->fe = dib3000mb_attach(&thomson_cable_eu_config, &dib->i2c_adap,&dib->xfer_ops); - + switch (dib->dibdev->parm->type) { + case DIBUSB1_1: + case DIBUSB1_1_AN2235: + dib->fe = dib3000mb_attach(&thomson_cable_eu_config,&dib->i2c_adap,&dib->xfer_ops); + break; + case DIBUSB2_0: + dib->fe = dib3000mc_attach(&panasonic_cofdm_env57h1xd5,&dib->i2c_adap, &dib->xfer_ops); + break; + } + if (dib->fe == NULL) { printk("dvb-dibusb: A frontend driver was not found for device %04x/%04x\n", dib->udev->descriptor.idVendor, @@ -670,9 +747,11 @@ static int dibusb_init(struct usb_dibusb *dib) deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize); /* allocate the actual buffer for the URBs */ if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) { + deb_info("not enough memory.\n"); dibusb_exit(dib); return -ENOMEM; } + deb_info("allocation complete\n"); memset(dib->buffer,0,bufsize); /* allocate and submit the URBs */ @@ -719,6 +798,8 @@ static int dibusb_init(struct usb_dibusb *dib) dib->rc_input_event = KEY_MAX; INIT_WORK(&dib->rc_query_work, dibusb_query_rc, dib); + + dibusb_hw_wakeup(dib); if ((ret = dibusb_dvb_init(dib))) { dibusb_exit(dib); -- cgit v1.2.3