]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/dvb/dvb-usb/dibusb-common.c
V4L/DVB (4453): [PATCH] dibcom mod3000p + mt2060 -- remote control
[linux-2.6-omap-h63xx.git] / drivers / media / dvb / dvb-usb / dibusb-common.c
index 269d899da488336024e70286a8773b48cff65c77..d7e2319ff2023840f82bd8955e81310ca8e20dec 100644 (file)
@@ -128,7 +128,7 @@ 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)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        if (num > 2)
@@ -146,7 +146,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
                                break;
        }
 
-       up(&d->i2c_sem);
+       mutex_unlock(&d->i2c_mutex);
        return i;
 }
 
@@ -168,13 +168,58 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
 }
 EXPORT_SYMBOL(dibusb_read_eeprom_byte);
 
+static struct mt2060_config stk3000p_mt2060_config = {
+       .i2c_address = 0x60,
+};
+
+static int dibusb_tuner_init(struct dvb_frontend *fe)
+{
+       struct dvb_usb_device *d = fe->dvb->priv;
+       struct dibusb_state *st = d->priv;
+
+       if (d->tuner_pass_ctrl && st->mt2060_present) {
+               int ret;
+               d->tuner_pass_ctrl(d->fe, 1, stk3000p_mt2060_config.i2c_address);
+               ret = mt2060_init(&st->mt2060);
+               d->tuner_pass_ctrl(d->fe, 0, 0);
+               return ret;
+       }
+       return dvb_usb_pll_init_i2c(fe);
+}
+
+static int dibusb_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+       struct dvb_usb_device *d = fe->dvb->priv;
+       struct dibusb_state *st = d->priv;
+
+       if (d->tuner_pass_ctrl && st->mt2060_present) {
+               int ret;
+               d->tuner_pass_ctrl(d->fe, 1, stk3000p_mt2060_config.i2c_address);
+               ret = mt2060_set(&st->mt2060,fep);
+               d->tuner_pass_ctrl(d->fe,0,0);
+               return ret;
+       }
+       return dvb_usb_pll_set_i2c(fe,fep);
+}
+
+static const struct dib3000p_agc_config dib3000p_agc_panasonic_env57h1xd5 = {
+       { 0x51, 0x301d, 0x0, 0x1cc7, 0xdc29, 0x570a,
+       0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0xa, 0x951e }
+};
+
+static const struct dib3000p_agc_config dib3000p_agc_microtune_mt2060 = {
+       { 0x196, 0x301d, 0x0, 0x1cc7, 0xffff, 0x5c29,
+       0xa8f6, 0x5eb8, 0x65ff, 0x40ff, 0x8a, 0x1114 }
+};
+
 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 = dvb_usb_pll_set_i2c;
-       demod_cfg.pll_init = dvb_usb_pll_init_i2c;
+       demod_cfg.agc      = &dib3000p_agc_panasonic_env57h1xd5;
+       demod_cfg.pll_set  = dibusb_tuner_set;
+       demod_cfg.pll_init = dibusb_tuner_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) {
@@ -188,8 +233,42 @@ EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
 
 int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
 {
-       d->pll_addr = 0x60;
-       d->pll_desc = &dvb_pll_env57h1xd5;
+       int ret;
+       u8 a,b;
+       u16 if1=1220;
+
+       if (d->tuner_pass_ctrl) {
+               struct dibusb_state *st = d->priv;
+               d->tuner_pass_ctrl(d->fe, 1, stk3000p_mt2060_config.i2c_address);
+               // First IF calibration for Liteon Sticks
+               if (d->udev->descriptor.idVendor == USB_VID_LITEON &&
+                   d->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
+                       dibusb_read_eeprom_byte(d,0x7E,&a);
+                       dibusb_read_eeprom_byte(d,0x7F,&b);
+                       if (a == 0xFF && b == 0xFF) {
+                               if1 = 1220;
+                       } else
+                       if (a == 0x00) {
+                               if1 = 1220+b;
+                       } else
+                       if (a == 0x80) {
+                               if1 = 1220-b;
+                       } else {
+                               warn("LITE-ON DVB-T Tuner : Strange IF1 calibration :%2X %2X\n",(int)a,(int)b);
+                               if1 = 1220;
+                       }
+               }
+               if ((ret = mt2060_attach(&st->mt2060,&stk3000p_mt2060_config, &d->i2c_adap,if1)) != 0) {
+                       /* not found - use panasonic pll parameters */
+                       d->pll_addr = 0x60;
+                       d->pll_desc = &dvb_pll_env57h1xd5;
+               } else {
+                       st->mt2060_present = 1;
+                       /* set the correct agc parameters for the dib3000p */
+                       dib3000mc_set_agc_config(d->fe, &dib3000p_agc_microtune_mt2060);
+               }
+               d->tuner_pass_ctrl(d->fe,0,0);
+       }
        return 0;
 }
 EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
@@ -264,6 +343,67 @@ struct dvb_usb_rc_key dibusb_rc_keys[] = {
        { 0x86, 0x1e, KEY_DOWN },
        { 0x86, 0x1f, KEY_LEFT },
        { 0x86, 0x1b, KEY_RIGHT },
+
+       /* Key codes for the DiBcom MOD3000 remote. */
+       { 0x80, 0x00, KEY_MUTE },
+       { 0x80, 0x01, KEY_TEXT },
+       { 0x80, 0x02, KEY_HOME },
+       { 0x80, 0x03, KEY_POWER },
+
+       { 0x80, 0x04, KEY_RED },
+       { 0x80, 0x05, KEY_GREEN },
+       { 0x80, 0x06, KEY_YELLOW },
+       { 0x80, 0x07, KEY_BLUE },
+
+       { 0x80, 0x08, KEY_DVD },
+       { 0x80, 0x09, KEY_AUDIO },
+       { 0x80, 0x0a, KEY_MEDIA },      /* Pictures */
+       { 0x80, 0x0b, KEY_VIDEO },
+
+       { 0x80, 0x0c, KEY_BACK },
+       { 0x80, 0x0d, KEY_UP },
+       { 0x80, 0x0e, KEY_RADIO },
+       { 0x80, 0x0f, KEY_EPG },
+
+       { 0x80, 0x10, KEY_LEFT },
+       { 0x80, 0x11, KEY_OK },
+       { 0x80, 0x12, KEY_RIGHT },
+       { 0x80, 0x13, KEY_UNKNOWN },    /* SAP */
+
+       { 0x80, 0x14, KEY_TV },
+       { 0x80, 0x15, KEY_DOWN },
+       { 0x80, 0x16, KEY_MENU },       /* DVD Menu */
+       { 0x80, 0x17, KEY_LAST },
+
+       { 0x80, 0x18, KEY_RECORD },
+       { 0x80, 0x19, KEY_STOP },
+       { 0x80, 0x1a, KEY_PAUSE },
+       { 0x80, 0x1b, KEY_PLAY },
+
+       { 0x80, 0x1c, KEY_PREVIOUS },
+       { 0x80, 0x1d, KEY_REWIND },
+       { 0x80, 0x1e, KEY_FASTFORWARD },
+       { 0x80, 0x1f, KEY_NEXT},
+
+       { 0x80, 0x40, KEY_1 },
+       { 0x80, 0x41, KEY_2 },
+       { 0x80, 0x42, KEY_3 },
+       { 0x80, 0x43, KEY_CHANNELUP },
+
+       { 0x80, 0x44, KEY_4 },
+       { 0x80, 0x45, KEY_5 },
+       { 0x80, 0x46, KEY_6 },
+       { 0x80, 0x47, KEY_CHANNELDOWN },
+
+       { 0x80, 0x48, KEY_7 },
+       { 0x80, 0x49, KEY_8 },
+       { 0x80, 0x4a, KEY_9 },
+       { 0x80, 0x4b, KEY_VOLUMEUP },
+
+       { 0x80, 0x4c, KEY_CLEAR },
+       { 0x80, 0x4d, KEY_0 },
+       { 0x80, 0x4e, KEY_ENTER },
+       { 0x80, 0x4f, KEY_VOLUMEDOWN },
 };
 EXPORT_SYMBOL(dibusb_rc_keys);