diff options
author | Andrew de Quincy <devnull@localhost> | 2004-10-28 17:37:07 +0000 |
---|---|---|
committer | Andrew de Quincy <devnull@localhost> | 2004-10-28 17:37:07 +0000 |
commit | 25da23146538519f0f644671c49868bfb560740a (patch) | |
tree | 7987970be2d5e86492325711d234ff59319f2685 /linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |
parent | dcc0614123e60b1b01ed67850ebd22a517d8c086 (diff) | |
download | mediapointer-dvb-s2-25da23146538519f0f644671c49868bfb560740a.tar.gz mediapointer-dvb-s2-25da23146538519f0f644671c49868bfb560740a.tar.bz2 |
Imported FE_REFACTORING to HEAD
Diffstat (limited to 'linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c')
-rw-r--r-- | linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 228 |
1 files changed, 180 insertions, 48 deletions
diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 3ce423b55..338eeb507 100644 --- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -24,11 +24,14 @@ #include "dmxdev.h" #include "dvb_demux.h" #include "dvb_net.h" +#include "cx22700.h" +#include "tda1004x.h" #include <linux/dvb/frontend.h> #include <linux/dvb/dmx.h> #include <linux/pci.h> + /* TTUSB_HWSECTIONS: the DSP supports filtering in hardware, however, since the "muxstream" @@ -132,6 +135,8 @@ struct ttusb { #if 0 devfs_handle_t stc_devfs_handle; #endif + + struct dvb_frontend* fe; }; /* ugly workaround ... don't know why it's neccessary to read */ @@ -461,9 +466,10 @@ static int ttusb_init_controller(struct ttusb *ttusb) } #ifdef TTUSB_DISEQC -static int ttusb_send_diseqc(struct ttusb *ttusb, - const struct dvb_diseqc_master_cmd *cmd) +static int ttusb_send_diseqc(struct dvb_frontend* fe, + const struct dvb_diseqc_master_cmd *cmd) { + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 b[12] = { 0xaa, ++ttusb->c, 0x18 }; int err; @@ -501,41 +507,24 @@ static int ttusb_update_lnb(struct ttusb *ttusb) return err; } -static int ttusb_set_voltage(struct ttusb *ttusb, fe_sec_voltage_t voltage) +static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; + ttusb->voltage = voltage; return ttusb_update_lnb(ttusb); } #ifdef TTUSB_TONE -static int ttusb_set_tone(struct ttusb *ttusb, fe_sec_tone_mode_t tone) +static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; + ttusb->tone = tone; return ttusb_update_lnb(ttusb); } #endif -static int ttusb_lnb_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) -{ - struct ttusb *ttusb = fe->before_after_data; - - switch (cmd) { - case FE_SET_VOLTAGE: - return ttusb_set_voltage(ttusb, (fe_sec_voltage_t) arg); -#ifdef TTUSB_TONE - case FE_SET_TONE: - return ttusb_set_tone(ttusb, (fe_sec_tone_mode_t) arg); -#endif -#ifdef TTUSB_DISEQC - case FE_DISEQC_SEND_MASTER_CMD: - return ttusb_send_diseqc(ttusb, - (struct dvb_diseqc_master_cmd *) - arg); -#endif - default: - return -EOPNOTSUPP; - }; -} #if 0 static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq) @@ -1076,33 +1065,178 @@ u32 functionality(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } -static struct i2c_algorithm ttusb_dec_algo = { - .name = "ttusb dec i2c algorithm", - .id = I2C_ALGO_BIT, - .master_xfer = master_xfer, - .functionality = functionality, -}; -static int client_register(struct i2c_client *client) + +static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { - struct ttusb *ttusb = (struct ttusb*)i2c_get_adapdata(client->adapter); + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; + u8 data[4]; + struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) }; + u32 div; + + div = (params->frequency + 36166667) / 166667; - if (client->driver->command) - return client->driver->command(client, FE_REGISTER, ttusb->adapter); + data[0] = (div >> 8) & 0x7f; + data[1] = div & 0xff; + data[2] = ((div >> 10) & 0x60) | 0x85; + data[3] = params->frequency < 592000000 ? 0x40 : 0x80; + if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } -static int client_unregister(struct i2c_client *client) +struct cx22700_config alps_tdmb7_config = { + .demod_address = 0x43, + .pll_set = alps_tdmb7_pll_set, +}; + + + + + +static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) { - struct ttusb *ttusb = (struct ttusb*)i2c_get_adapdata(client->adapter); + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; + static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; + static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; + struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; + + // setup PLL configuration + if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; + msleep(1); + + // disable the mc44BC374c (do not check for errors) + tuner_msg.addr = 0x65; + tuner_msg.buf = disable_mc44BC374c; + tuner_msg.len = sizeof(disable_mc44BC374c); + if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { + i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); + } - if (client->driver->command) - return client->driver->command(client, FE_UNREGISTER, ttusb->adapter); + return 0; +} +static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +{ + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; + u8 tuner_buf[4]; + struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) }; + int tuner_frequency = 0; + u8 band, cp, filter; + + // determine charge pump + tuner_frequency = params->frequency + 36130000; + if (tuner_frequency < 87000000) return -EINVAL; + else if (tuner_frequency < 130000000) cp = 3; + else if (tuner_frequency < 160000000) cp = 5; + else if (tuner_frequency < 200000000) cp = 6; + else if (tuner_frequency < 290000000) cp = 3; + else if (tuner_frequency < 420000000) cp = 5; + else if (tuner_frequency < 480000000) cp = 6; + else if (tuner_frequency < 620000000) cp = 3; + else if (tuner_frequency < 830000000) cp = 5; + else if (tuner_frequency < 895000000) cp = 7; + else return -EINVAL; + + // determine band + if (params->frequency < 49000000) return -EINVAL; + else if (params->frequency < 159000000) band = 1; + else if (params->frequency < 444000000) band = 2; + else if (params->frequency < 861000000) band = 4; + else return -EINVAL; + + // setup PLL filter + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + tda1004x_write_byte(fe, 0x0C, 0); + filter = 0; + break; + + case BANDWIDTH_7_MHZ: + tda1004x_write_byte(fe, 0x0C, 0); + filter = 0; + break; + + case BANDWIDTH_8_MHZ: + tda1004x_write_byte(fe, 0x0C, 0xFF); + filter = 1; + break; + + default: + return -EINVAL; + } + + // calculate divisor + // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) + tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000; + + // setup tuner buffer + tuner_buf[0] = tuner_frequency >> 8; + tuner_buf[1] = tuner_frequency & 0xff; + tuner_buf[2] = 0xca; + tuner_buf[3] = (cp << 5) | (filter << 3) | band; + + if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; + + msleep(1); return 0; } +static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) +{ + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; + + return request_firmware(fw, name, &ttusb->dev->dev); +} + +struct tda1004x_config philips_tdm1316l_config = { + + .demod_address = 0x8, + .invert = 1, + .pll_init = philips_tdm1316l_pll_init, + .pll_set = philips_tdm1316l_pll_set, + .request_firmware = philips_tdm1316l_request_firmware, +}; + + + +static void frontend_init(struct ttusb* ttusb) +{ + switch(ttusb->dev->descriptor.idProduct) { + case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) + // try the ALPS TDMB7 first + ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); + if (ttusb->fe != NULL) break; + + // Philips td1316 + ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); + if (ttusb->fe != NULL) break; + break; + } + + if (ttusb->fe == NULL) { + printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n", + ttusb->dev->descriptor.idVendor, + ttusb->dev->descriptor.idProduct); + } else { + if (dvb_register_frontend(ttusb->adapter, ttusb->fe)) { + printk("dvb-ttusb-budget: Frontend registration failed!\n"); + if (ttusb->fe->ops->release) + ttusb->fe->ops->release(ttusb->fe); + ttusb->fe = NULL; + } + } +} + + + +static struct i2c_algorithm ttusb_dec_algo = { + .name = "ttusb dec i2c algorithm", + .id = I2C_ALGO_BIT, + .master_xfer = master_xfer, + .functionality = functionality, +}; + static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev; @@ -1140,6 +1274,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i up(&ttusb->sem); dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); + ttusb->adapter->priv = ttusb; /* i2c */ memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter)); @@ -1155,18 +1290,13 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ttusb->i2c_adap.algo = &ttusb_dec_algo; ttusb->i2c_adap.algo_data = NULL; ttusb->i2c_adap.id = I2C_ALGO_BIT; - ttusb->i2c_adap.client_register = client_register; - ttusb->i2c_adap.client_unregister = client_unregister; - + result = i2c_add_adapter(&ttusb->i2c_adap); if (result) { dvb_unregister_adapter (ttusb->adapter); return result; } - dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL, - ttusb); - memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux)); ttusb->dvb_demux.dmx.capabilities = @@ -1220,6 +1350,8 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i #endif usb_set_intfdata(intf, (void *) ttusb); + frontend_init(ttusb); + return 0; } @@ -1237,7 +1369,7 @@ static void ttusb_disconnect(struct usb_interface *intf) dvb_net_release(&ttusb->dvbnet); dvb_dmxdev_release(&ttusb->dmxdev); dvb_dmx_release(&ttusb->dvb_demux); - + if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe); i2c_del_adapter(&ttusb->i2c_adap); dvb_unregister_adapter(ttusb->adapter); @@ -1249,8 +1381,8 @@ static void ttusb_disconnect(struct usb_interface *intf) } static struct usb_device_id ttusb_table[] = { - {USB_DEVICE(0xb48, 0x1003)}, - {USB_DEVICE(0xb48, 0x1004)}, /* to be confirmed ???? */ +/* {USB_DEVICE(0xb48, 0x1003)},UNDEFINED HARDWARE - mail linuxtv.org list */ +/* {USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/ /* to be confirmed ???? */ {USB_DEVICE(0xb48, 0x1005)}, {} }; |