summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
diff options
context:
space:
mode:
authorAndrew de Quincy <devnull@localhost>2004-10-28 17:37:07 +0000
committerAndrew de Quincy <devnull@localhost>2004-10-28 17:37:07 +0000
commit25da23146538519f0f644671c49868bfb560740a (patch)
tree7987970be2d5e86492325711d234ff59319f2685 /linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
parentdcc0614123e60b1b01ed67850ebd22a517d8c086 (diff)
downloadmediapointer-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.c228
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)},
{}
};