summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/dvb-usb/dibusb-common.c
diff options
context:
space:
mode:
authorPatrick Boettcher <devnull@localhost>2005-04-17 14:37:15 +0000
committerPatrick Boettcher <devnull@localhost>2005-04-17 14:37:15 +0000
commit4e4da24aa36487071bd874fc63d387258299ceb0 (patch)
treeb048f438139994b1842b269838bc85d2eebf2d63 /linux/drivers/media/dvb/dvb-usb/dibusb-common.c
parentb5833bcf1184221ce9ff84d4787d77ce1cbacafa (diff)
downloadmediapointer-dvb-s2-4e4da24aa36487071bd874fc63d387258299ceb0.tar.gz
mediapointer-dvb-s2-4e4da24aa36487071bd874fc63d387258299ceb0.tar.bz2
- ported all dibusb drivers to fit into the dvb-usb-frameword
- created dvb-pll-entries for the tuner used with the dibusb-drivers - removed all traces of the dibusb driver - adapted the dib3000-frontends to get along with the dvb-pll-changes
Diffstat (limited to 'linux/drivers/media/dvb/dvb-usb/dibusb-common.c')
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dibusb-common.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-common.c b/linux/drivers/media/dvb/dvb-usb/dibusb-common.c
new file mode 100644
index 000000000..fdec9e459
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -0,0 +1,252 @@
+/* Common methods for dibusb-based-receivers.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * 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
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
+
+#define deb_info(args...) dprintk(debug,0x01,args)
+
+/* common stuff used by the different dibusb modules */
+int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ if (d->priv != NULL) {
+ struct dib_fe_xfer_ops *ops = d->priv;
+ if (ops->fifo_ctrl != NULL)
+ if (ops->fifo_ctrl(d->fe,onoff)) {
+ err("error while controlling the fifo of the demod.");
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_streaming_ctrl);
+
+int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+{
+ if (d->priv != NULL) {
+ struct dib_fe_xfer_ops *ops = d->priv;
+ if (d->pid_filtering && ops->pid_ctrl != NULL)
+ ops->pid_ctrl(d->fe,index,pid,onoff);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter);
+
+int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ if (d->priv != NULL) {
+ struct dib_fe_xfer_ops *ops = d->priv;
+ if (ops->pid_parse != NULL)
+ if (ops->pid_parse(d->fe,onoff) < 0)
+ err("could not handle pid_parser");
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
+
+int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 b[3];
+ b[0] = DIBUSB_REQ_SET_IOCTL;
+ b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
+ b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
+ return dvb_usb_generic_write(d,b,3);
+}
+EXPORT_SYMBOL(dibusb_power_ctrl);
+
+int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 b[2];
+ b[0] = DIBUSB_REQ_SET_IOCTL;
+ b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
+
+ dvb_usb_generic_write(d,b,3);
+
+ return dibusb_streaming_ctrl(d,onoff);
+}
+EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
+
+int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ if (onoff) {
+ u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
+ return dvb_usb_generic_write(d,b,3);
+ } else
+ return 0;
+}
+EXPORT_SYMBOL(dibusb2_0_power_ctrl);
+
+int dibusb_rc_init(struct dvb_usb_device *d)
+{
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_rc_init);
+
+int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
+ dvb_usb_generic_rw(d,&cmd,1,key,5);
+/* dvb_usb_nec_rc_key_to_event(d,dtt200u_rc_keys,sizeof(dtt200u_rc_keys)/sizeof(struct dvb_usb_nec_rc_key),
+ key,event,state);*/
+ if (key[0] != 0)
+ deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_rc_query);
+
+static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
+ u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+ u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
+ /* write only ? */
+ int wo = (rbuf == NULL || rlen == 0),
+ len = 2 + wlen + (wo ? 0 : 2);
+
+ sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
+ sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
+
+ memcpy(&sndbuf[2],wbuf,wlen);
+
+ if (!wo) {
+ sndbuf[wlen+2] = (rlen >> 8) & 0xff;
+ sndbuf[wlen+3] = rlen & 0xff;
+ }
+
+ return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen);
+}
+
+/*
+ * I2C master xfer function
+ */
+static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i;
+
+ if (down_interruptible(&d->i2c_sem) < 0)
+ return -EAGAIN;
+
+ if (num > 2)
+ warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+ for (i = 0; i < num; i++) {
+ /* write/read request */
+ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+ if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
+ msg[i+1].buf,msg[i+1].len) < 0)
+ break;
+ i++;
+ } else
+ if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
+ break;
+ }
+
+ up(&d->i2c_sem);
+ return i;
+}
+
+static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm dibusb_i2c_algo = {
+ .name = "DiBcom USB I2C algorithm",
+ .id = I2C_ALGO_BIT,
+ .master_xfer = dibusb_i2c_xfer,
+ .functionality = dibusb_i2c_func,
+};
+EXPORT_SYMBOL(dibusb_i2c_algo);
+
+int dibusb_pll_init_i2c(struct dvb_frontend *fe)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ struct dibusb_state *st = d->priv;
+ if (st && st->ops.tuner_pass_ctrl)
+ st->ops.tuner_pass_ctrl(d->fe,1,st->pll_addr);
+
+// init;
+
+ if (st && st->ops.tuner_pass_ctrl)
+ st->ops.tuner_pass_ctrl(d->fe,0,st->pll_addr);
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_pll_init_i2c);
+
+int dibusb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5])
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ struct dibusb_state *st = d->priv;
+ b[0] = st->pll_addr << 1;
+
+ deb_info("pll addr: %x, freq: %d\n",st->pll_addr,fep->frequency);
+
+ dvb_pll_configure(st->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
+
+ deb_info("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
+
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_pll_set);
+
+int dibusb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ struct dibusb_state *st = d->priv;
+ int ret = 0;
+ u8 b[5];
+ struct i2c_msg msg = { .addr = st->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
+
+ dibusb_pll_set(fe,fep,b);
+
+ if (st && st->ops.tuner_pass_ctrl)
+ st->ops.tuner_pass_ctrl(d->fe,1,st->pll_addr);
+
+ if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+ err("tuner i2c write failed.");
+ ret = -EREMOTEIO;
+ }
+
+ msleep(1);
+
+ if (st && st->ops.tuner_pass_ctrl)
+ st->ops.tuner_pass_ctrl(d->fe,0,st->pll_addr);
+
+ return ret;
+}
+EXPORT_SYMBOL(dibusb_pll_set_i2c);
+
+int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
+{
+ struct dib3000_config demod_cfg;
+ struct dibusb_state *st = d->priv;
+
+ demod_cfg.pll_set = dibusb_pll_set_i2c; /* dibusb_general_pll_set; */
+ demod_cfg.pll_init = dibusb_pll_init_i2c; /* dibusb_general_pll_init; */
+
+ for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
+ if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL)
+ return 0;
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
+
+int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
+{
+ struct dibusb_state *st = d->priv;
+ st->pll_addr = 0x60;
+ st->pll_desc = &dvb_pll_env57h1xd5;
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);