Here is a patch against linux-2.6.22.1
----- Original ----
Sender: Patrick Boettcher <patrick.boettcher@xxxxxxx>
Receiver: Shuhao Chang <shuhao_chang@xxxxxxxxx>
CC: linux-dvb@xxxxxxxxxxx
Date: Mon, Oct 22 15:39:12 +0800
Subject: Re: is dib7070m supported?
Hello,
As you have received a development board from DiBcom you most likely have
a contact at DiBcom. Try to ask them to have a driver (for windows at
least).
The DiB7070M can be used in Linux with v4l-dvb but not without some work.
Have a look at dib0700_devices.c to find how the DiB7070P is implemented.
Patrick.
--
Mail: patrick.boettcher@xxxxxxx
WWW: http://www.wi-bw.tfh-wildau.de/~pboettch/
On Wed, 17 Oct 2007, Shuhao Chang wrote:
> We got NIM7070MD(2 dib7070m + dib0700c usb bridge) board.
> My linux box didn't recognize it.
> is dib7070m supported?
>
> I found there is a dib7070p-based driver patch(01373a5c97ced83d4cb520f7e56c80454a198bfb) at linux git reposity.
> Does it works with dib7070m?
>
>
>
>
>
> ____________________________________________________________________________________
> ??????,?????? - ???? Yahoo!??????http://tw.info.yahoo.com/seal/index.html
Sender: Patrick Boettcher <patrick.boettcher@xxxxxxx>
Receiver: Shuhao Chang <shuhao_chang@xxxxxxxxx>
CC: linux-dvb@xxxxxxxxxxx
Date: Mon, Oct 22 15:39:12 +0800
Subject: Re: is dib7070m supported?
Hello,
As you have received a development board from DiBcom you most likely have
a contact at DiBcom. Try to ask them to have a driver (for windows at
least).
The DiB7070M can be used in Linux with v4l-dvb but not without some work.
Have a look at dib0700_devices.c to find how the DiB7070P is implemented.
Patrick.
--
Mail: patrick.boettcher@xxxxxxx
WWW: http://www.wi-bw.tfh-wildau.de/~pboettch/
On Wed, 17 Oct 2007, Shuhao Chang wrote:
> We got NIM7070MD(2 dib7070m + dib0700c usb bridge) board.
> My linux box didn't recognize it.
> is dib7070m supported?
>
> I found there is a dib7070p-based driver patch(01373a5c97ced83d4cb520f7e56c80454a198bfb) at linux git reposity.
> Does it works with dib7070m?
>
>
>
>
>
> ____________________________________________________________________________________
> ??????,?????? - ???? Yahoo!??????http://tw.info.yahoo.com/seal/index.html
____________________________________________________________________________________
怎樣減少垃圾信?只要看到垃圾信,立即按下「這是垃圾信」按鈕,垃圾信剋星幫助你清除你信箱垃圾。
diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/dvb-usb/Kconfig linux-2.6.22.1.nim7070md/drivers/media/dvb/dvb-usb/Kconfig *** linux-2.6.22.1.vallina/drivers/media/dvb/dvb-usb/Kconfig Wed Oct 31 15:53:48 2007 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/dvb-usb/Kconfig Wed Nov 14 13:36:51 2007 *************** config DVB_USB_DIB0700 *** 74,79 **** --- 74,80 ---- select DVB_DIB7000M select DVB_DIB3000MC select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE + select DVB_TUNER_DIB0070 help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The USB bridge is also present in devices having the DiB7700 DVB-T-USB diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-2.6.22.1.nim7070md/drivers/media/dvb/dvb-usb/dib0700_devices.c *** linux-2.6.22.1.vallina/drivers/media/dvb/dvb-usb/dib0700_devices.c Wed Oct 31 15:53:48 2007 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/dvb-usb/dib0700_devices.c Wed Nov 14 12:05:05 2007 *************** *** 12,23 **** --- 12,28 ---- #include "dib7000m.h" #include "dib7000p.h" #include "mt2060.h" + #include "dib0070.h" static int force_lna_activation; module_param(force_lna_activation, int, 0644); MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), " "if applicable for the device (default: 0=automatic/off)."); + struct dib0700_adapter_state { + int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); + }; + /* Hauppauge Nova-T 500 * has a LNA on GPIO0 which is enabled by setting 1 */ static struct mt2060_config bristol_mt2060_config[2] = { *************** static int stk7700p_frontend_attach(stru *** 244,250 **** adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); st->is_dib7000pc = 1; } else ! adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); return adap->fe == NULL ? -ENODEV : 0; } --- 249,255 ---- adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); st->is_dib7000pc = 1; } else ! adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config, NULL, OUTMODE_MPEG2_FIFO); return adap->fe == NULL ? -ENODEV : 0; } *************** static int stk7700p_tuner_attach(struct *** 267,285 **** st->mt2060_if1[0]) == NULL ? -ENODEV : 0; } struct usb_device_id dib0700_usb_id_table[] = { ! { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) }, ! { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) }, { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) }, { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) }, { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) }, ! { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); --- 272,449 ---- st->mt2060_if1[0]) == NULL ? -ENODEV : 0; } + /* NIM7070MD */ + static struct dibx000_agc_config dib7070_agc_config = { + BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, + * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ + (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup + + 600, // inv_gain + 10, // time_stabiliz + + 0, // alpha_level + 118, // thlock + + 0, // wbd_inv + 3530, // wbd_ref + 1, // wbd_sel + 5, // wbd_alpha + + 65535, // agc1_max + 0, // agc1_min + + 65535, // agc2_max + 0, // agc2_min + + 0, // agc1_pt1 + 40, // agc1_pt2 + 183, // agc1_pt3 + 206, // agc1_slope1 + 255, // agc1_slope2 + 72, // agc2_pt1 + 152, // agc2_pt2 + 88, // agc2_slope1 + 90, // agc2_slope2 + + 17, // alpha_mant + 27, // alpha_exp + 23, // beta_mant + 51, // beta_exp + + 0, // perform_agc_softsplit + }; + + static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { + 60000, 15000, // internal, sampling + 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass + 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo + (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k + (0 << 25) | 0, // ifreq = 0.000000 MHz + 20452225 // timf + }; + + static struct dib7000m_config nim7070md_dib7000m_config[2] = { + { + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 1, + .agc = &dib7070_agc_config, + .bw = &dib7070_bw_config_12_mhz, + + .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, + .mobile_mode = 1 + }, { + .output_mpeg2_in_188_bytes = 0, + + .agc_config_count = 1, + .agc = &dib7070_agc_config, + .bw = &dib7070_bw_config_12_mhz, + + .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, + .mobile_mode = 1 + } + }; + + static int nim7070md_frontend_attach(struct dvb_usb_adapter *adap) + { + struct dvb_frontend *fe; + + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + dib7000m_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, nim7070md_dib7000m_config); + + fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 0x82, &nim7070md_dib7000m_config[1], NULL, OUTMODE_DIVERSITY); + if (fe == NULL) { + return -ENODEV; + } + adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 0x80, &nim7070md_dib7000m_config[0], fe, OUTMODE_MPEG2_FIFO); + return adap->fe == NULL ? -ENODEV : 0; + } + + static int dib7070m_tuner_reset(struct dvb_frontend *fe, int onoff) + { + int ret; + + do { + ret = dib7000m_set_gpio(fe, 8, 0, !onoff); + } while ((fe = dib7000m_get_next_frontend(fe)) != NULL); + return ret; + } + + static int dib7070m_tuner_sleep(struct dvb_frontend *fe, int onoff) + { + int ret; + + do { + ret = dib7000m_set_gpio(fe, 9, 0, onoff); + } while ((fe = dib7000m_get_next_frontend(fe)) != NULL); + return ret; + } + + static struct dib0070_config nim7070md_dib0070_config[2] = { + { + .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, + .reset = dib7070m_tuner_reset, + .sleep = dib7070m_tuner_sleep, + .clock_khz = 12000, + .clock_pad_drive = 4 + }, { + .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, + .reset = dib7070m_tuner_reset, + .sleep = dib7070m_tuner_sleep, + .clock_khz = 12000 + } + }; + + static int nim7070md_tuner_attach(struct dvb_usb_adapter *adap) + { + struct dvb_frontend *fe = adap->fe; + struct i2c_adapter *tun_i2c; + int i = 0; + + do { + tun_i2c = dib7000m_get_i2c_master(fe, DIBX000_I2C_INTERFACE_TUNER, 1); + dvb_attach(dib0070_attach, fe, tun_i2c, &nim7070md_dib0070_config[i++]); + } while ((fe = dib7000m_get_next_frontend(fe)) != NULL); + + return 0; + } + struct usb_device_id dib0700_usb_id_table[] = { ! /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) }, ! /* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) }, { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) }, { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) }, { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) }, ! /* 10 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) }, ! { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7070MD) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); *************** struct dvb_usb_device_properties dib0700 *** 372,377 **** --- 536,562 ---- { NULL }, }, } + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + + .num_adapters = 1, + .adapter = { + { + .frontend_attach = nim7070md_frontend_attach, + .tuner_attach = nim7070md_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = sizeof(struct dib0700_adapter_state) + } + }, + + .num_device_descs = 1, + .devices = { + { "DiBcom NIM7070MD reference design", + { &dib0700_usb_id_table[11], NULL }, + { NULL }, + } + } } }; diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-2.6.22.1.nim7070md/drivers/media/dvb/dvb-usb/dvb-usb-ids.h *** linux-2.6.22.1.vallina/drivers/media/dvb/dvb-usb/dvb-usb-ids.h Wed Oct 31 15:53:48 2007 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/dvb-usb/dvb-usb-ids.h Wed Oct 31 10:28:11 2007 *************** *** 61,66 **** --- 61,67 ---- #define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 #define USB_PID_DIBCOM_STK7700P 0x1e14 #define USB_PID_DIBCOM_STK7700P_PC 0x1e78 + #define USB_PID_DIBCOM_NIM7070MD 0x1ec6 #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 #define USB_PID_DPOSH_M9206_COLD 0x9206 #define USB_PID_DPOSH_M9206_WARM 0xa090 diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/frontends/Kconfig linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/Kconfig *** linux-2.6.22.1.vallina/drivers/media/dvb/frontends/Kconfig Wed Oct 31 15:53:48 2007 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/Kconfig Wed Nov 14 13:39:10 2007 *************** config DVB_TUNER_MT2060 *** 322,327 **** --- 322,336 ---- help A driver for the silicon IF tuner MT2060 from Microtune. + config DVB_TUNER_DIB0070 + tristate "DiBcom DiB0070 silicon base-band tuner" + depends on I2C + default m if DVB_FE_CUSTOMISE + help + A driver for the silicon baseband tuner DiB0070 from DiBcom. + This device is only used inside a SiP called togther with a + demodulator for now. + comment "Miscellaneous devices" depends on DVB_CORE diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/frontends/Makefile linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/Makefile *** linux-2.6.22.1.vallina/drivers/media/dvb/frontends/Makefile Wed Oct 31 15:53:48 2007 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/Makefile Wed Nov 14 13:41:35 2007 *************** obj-$(CONFIG_DVB_TDA10086) += tda10086.o *** 40,44 **** --- 40,45 ---- obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TDA827X) += tda827x.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o + obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o obj-$(CONFIG_DVB_TUA6100) += tua6100.o diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib0070.c linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib0070.c *** linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib0070.c Thu Jan 1 08:00:00 1970 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib0070.c Wed Oct 31 15:52:01 2007 *************** *** 0 **** --- 1,580 ---- + /* + * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. + * + * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) + * + * 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. + */ + #include <linux/kernel.h> + #include <linux/i2c.h> + + #include "dvb_frontend.h" + + #include "dib0070.h" + #include "dibx000_common.h" + + static int debug; + module_param(debug, int, 0644); + MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); + + #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0) + + #define DIB0070_P1D 0x00 + #define DIB0070_P1F 0x01 + #define DIB0070_P1G 0x03 + #define DIB0070S_P1A 0x02 + + struct dib0070_state { + struct i2c_adapter *i2c; + struct dvb_frontend *fe; + const struct dib0070_config *cfg; + u16 wbd_ff_offset; + u8 revision; + }; + + static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) + { + u8 b[2]; + struct i2c_msg msg[2] = { + { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, + { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, + }; + if (i2c_transfer(state->i2c, msg, 2) != 2) { + printk(KERN_WARNING "DiB0070 I2C read failed\n"); + return 0; + } + return (b[0] << 8) | b[1]; + } + + static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) + { + u8 b[3] = { reg, val >> 8, val & 0xff }; + struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "DiB0070 I2C write failed\n"); + return -EREMOTEIO; + } + return 0; + } + + #define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0) + + static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) + { + struct dib0070_state *st = fe->tuner_priv; + u16 tmp = 0; + tmp = dib0070_read_reg(st, 0x02) & 0x3fff; + + switch(BW_INDEX_TO_KHZ(ch->u.ofdm.bandwidth)) { + case 8000: + tmp |= (0 << 14); + break; + case 7000: + tmp |= (1 << 14); + break; + case 6000: + tmp |= (2 << 14); + break; + case 5000: + default: + tmp |= (3 << 14); + break; + } + dib0070_write_reg(st, 0x02, tmp); + return 0; + } + + static void dib0070_captrim(struct dib0070_state *st, u16 LO4) + { + int8_t captrim, fcaptrim, step_sign, step; + u16 adc, adc_diff = 3000; + + + + dib0070_write_reg(st, 0x0f, 0xed10); + dib0070_write_reg(st, 0x17, 0x0034); + + dib0070_write_reg(st, 0x18, 0x0032); + msleep(2); + + step = captrim = fcaptrim = 64; + + do { + step /= 2; + dib0070_write_reg(st, 0x14, LO4 | captrim); + msleep(1); + adc = dib0070_read_reg(st, 0x19); + + dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024); + + if (adc >= 400) { + adc -= 400; + step_sign = -1; + } else { + adc = 400 - adc; + step_sign = 1; + } + + if (adc < adc_diff) { + dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff); + adc_diff = adc; + fcaptrim = captrim; + + + + } + captrim += (step_sign * step); + } while (step >= 1); + + dib0070_write_reg(st, 0x14, LO4 | fcaptrim); + dib0070_write_reg(st, 0x18, 0x07ff); + } + + #define LPF 100 // define for the loop filter 100kHz by default 16-07-06 + #define LO4_SET_VCO_HFDIV(l, v, h) l |= ((v) << 11) | ((h) << 7) + #define LO4_SET_SD(l, s) l |= ((s) << 14) | ((s) << 12) + #define LO4_SET_CTRIM(l, c) l |= (c) << 10 + static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) + { + struct dib0070_state *st = fe->tuner_priv; + u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf); + + u8 band = BAND_OF_FREQUENCY(freq), c; + + /*******************VCO***********************************/ + u16 lo4 = 0; + + u8 REFDIV, PRESC = 2; + u32 FBDiv, Rest, FREF, VCOF_kHz; + u16 Num, Den; + /*******************FrontEnd******************************/ + u16 value = 0; + + dprintk( "Tuning for Band: %hd (%d kHz)", band, freq); + + + dib0070_write_reg(st, 0x17, 0x30); + + dib0070_set_bandwidth(fe, ch); /* c is used as HF */ + switch (st->revision) { + case DIB0070S_P1A: + switch (band) { + case BAND_LBAND: + LO4_SET_VCO_HFDIV(lo4, 1, 1); + c = 2; + break; + case BAND_SBAND: + LO4_SET_VCO_HFDIV(lo4, 0, 0); + LO4_SET_CTRIM(lo4, 1);; + c = 1; + break; + case BAND_UHF: + default: + if (freq < 570000) { + LO4_SET_VCO_HFDIV(lo4, 1, 3); + PRESC = 6; c = 6; + } else if (freq < 680000) { + LO4_SET_VCO_HFDIV(lo4, 0, 2); + c = 4; + } else { + LO4_SET_VCO_HFDIV(lo4, 1, 2); + c = 4; + } + break; + } break; + + case DIB0070_P1G: + case DIB0070_P1F: + default: + switch (band) { + case BAND_FM: + LO4_SET_VCO_HFDIV(lo4, 0, 7); + c = 24; + break; + case BAND_LBAND: + LO4_SET_VCO_HFDIV(lo4, 1, 0); + c = 2; + break; + case BAND_VHF: + if (freq < 180000) { + LO4_SET_VCO_HFDIV(lo4, 0, 3); + c = 16; + } else if (freq < 190000) { + LO4_SET_VCO_HFDIV(lo4, 1, 3); + c = 16; + } else { + LO4_SET_VCO_HFDIV(lo4, 0, 6); + c = 12; + } + break; + + case BAND_UHF: + default: + if (freq < 570000) { + LO4_SET_VCO_HFDIV(lo4, 1, 5); + c = 6; + } else if (freq < 700000) { + LO4_SET_VCO_HFDIV(lo4, 0, 1); + c = 4; + } else { + LO4_SET_VCO_HFDIV(lo4, 1, 1); + c = 4; + } + break; + } + break; + } + + dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf); + dprintk( "VCO = %hd", (lo4 >> 11) & 0x3); + + + VCOF_kHz = (c * freq) * 2; + dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq); + + switch (band) { + case BAND_VHF: + REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000); + break; + case BAND_FM: + REFDIV = (u8) ((st->cfg->clock_khz) / 1000); + break; + default: + REFDIV = (u8) ( st->cfg->clock_khz / 10000); + break; + } + FREF = st->cfg->clock_khz / REFDIV; + + dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF); + + + + switch (st->revision) { + case DIB0070S_P1A: + FBDiv = (VCOF_kHz / PRESC / FREF); + Rest = (VCOF_kHz / PRESC) - FBDiv * FREF; + break; + + case DIB0070_P1G: + case DIB0070_P1F: + default: + FBDiv = (freq / (FREF / 2)); + Rest = 2 * freq - FBDiv * FREF; + break; + } + + + if (Rest < LPF) Rest = 0; + else if (Rest < 2 * LPF) Rest = 2 * LPF; + else if (Rest > (FREF - LPF)) { Rest = 0 ; FBDiv += 1; } + else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF; + Rest = (Rest * 6528) / (FREF / 10); + dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest); + + Num = 0; + Den = 1; + + if (Rest > 0) { + LO4_SET_SD(lo4, 1); + Den = 255; + Num = (u16)Rest; + } + dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1); + + + + dib0070_write_reg(st, 0x11, (u16)FBDiv); + + + dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV); + + + dib0070_write_reg(st, 0x13, Num); + + + value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001; + + switch (band) { + case BAND_UHF: value |= 0x4000 | 0x0800; break; + case BAND_LBAND: value |= 0x2000 | 0x0400; break; + default: value |= 0x8000 | 0x1000; break; + } + dib0070_write_reg(st, 0x20, value); + + dib0070_captrim(st, lo4); + if (st->revision == DIB0070S_P1A) { + if (band == BAND_SBAND) + dib0070_write_reg(st, 0x15, 0x16e2); + else + dib0070_write_reg(st, 0x15, 0x56e5); + } + + + + switch (band) { + case BAND_UHF: value = 0x7c82; break; + case BAND_LBAND: value = 0x7c84; break; + default: value = 0x7c81; break; + } + dib0070_write_reg(st, 0x0f, value); + dib0070_write_reg(st, 0x06, 0x3fff); + + /* Front End */ + /* c == TUNE, value = SWITCH */ + c = 0; + value = 0; + switch (band) { + case BAND_FM: + c = 0; value = 1; + break; + + case BAND_VHF: + if (freq <= 180000) c = 0; + else if (freq <= 188200) c = 1; + else if (freq <= 196400) c = 2; + else c = 3; + value = 1; + break; + + case BAND_LBAND: + if (freq <= 1500000) c = 0; + else if (freq <= 1600000) c = 1; + else c = 3; + break; + + case BAND_SBAND: + c = 7; + dib0070_write_reg(st, 0x1d,0xFFFF); + break; + + case BAND_UHF: + default: + if (st->cfg->flip_chip) { + if (freq <= 550000) c = 0; + else if (freq <= 590000) c = 1; + else if (freq <= 666000) c = 3; + else c = 5; + } else { + if (freq <= 550000) c = 2; + else if (freq <= 650000) c = 3; + else if (freq <= 750000) c = 5; + else if (freq <= 850000) c = 6; + else c = 7; + } + value = 2; + break; + } + + /* default: LNA_MATCH=7, BIAS=3 */ + dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0)); + dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127)); + dib0070_write_reg(st, 0x0d, 0x0d80); + + + dib0070_write_reg(st, 0x18, 0x07ff); + dib0070_write_reg(st, 0x17, 0x0033); + + return 0; + } + + static int dib0070_wakeup(struct dvb_frontend *fe) + { + struct dib0070_state *st = fe->tuner_priv; + if (st->cfg->sleep) + st->cfg->sleep(fe, 0); + return 0; + } + + static int dib0070_sleep(struct dvb_frontend *fe) + { + struct dib0070_state *st = fe->tuner_priv; + if (st->cfg->sleep) + st->cfg->sleep(fe, 1); + return 0; + } + + static u16 dib0070_p1f_defaults[] = + + { + 7, 0x02, + 0x0008, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0002, + 0x0100, + + 3, 0x0d, + 0x0d80, + 0x0001, + 0x0000, + + 4, 0x11, + 0x0000, + 0x0103, + 0x0000, + 0x0000, + + 3, 0x16, + 0x0004 | 0x0040, + 0x0030, + 0x07ff, + + 6, 0x1b, + 0x4112, + 0xff00, + 0xc07f, + 0x0000, + 0x0180, + 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, + + 0, + }; + + static void dib0070_wbd_calibration(struct dib0070_state *state) + { + u16 wbd_offs; + dib0070_write_reg(state, 0x0f, 0x6d81); + dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); + msleep(9); + wbd_offs = dib0070_read_reg(state, 0x19); + dib0070_write_reg(state, 0x20, 0); + state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2); + dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset); + } + + u16 dib0070_wbd_offset(struct dvb_frontend *fe) + { + struct dib0070_state *st = fe->tuner_priv; + return st->wbd_ff_offset; + } + + EXPORT_SYMBOL(dib0070_wbd_offset); + static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt) + { + struct dib0070_state *state = fe->tuner_priv; + u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); + dprintk( "CTRL_LO5: 0x%x", lo5); + return dib0070_write_reg(state, 0x15, lo5); + } + + #define pgm_read_word(w) (*w) + static int dib0070_reset(struct dib0070_state *state) + { + u16 l, r, *n; + + HARD_RESET(state); + + + #ifndef FORCE_SBAND_TUNER + if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) + state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; + else + #endif + state->revision = DIB0070S_P1A; + + /* P1F or not */ + dprintk( "Revision: %x", state->revision); + + if (state->revision == DIB0070_P1D) { + dprintk( "Error: this driver is not to be used meant for P1D or earlier"); + return -EINVAL; + } + + n = (u16 *) dib0070_p1f_defaults; + l = pgm_read_word(n++); + while (l) { + r = pgm_read_word(n++); + do { + dib0070_write_reg(state, (u8)r, pgm_read_word(n++)); + r++; + } while (--l); + l = pgm_read_word(n++); + } + + if (state->cfg->force_crystal_mode != 0) + r = state->cfg->force_crystal_mode; + else if (state->cfg->clock_khz >= 24000) + r = 1; + else + r = 2; + + r |= state->cfg->osc_buffer_state << 3; + + dib0070_write_reg(state, 0x10, r); + dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4)); + + if (state->cfg->invert_iq) { + r = dib0070_read_reg(state, 0x02) & 0xffdf; + dib0070_write_reg(state, 0x02, r | (1 << 5)); + } + + + if (state->revision == DIB0070S_P1A) + dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1); + else + dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0); + + dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); + return 0; + } + + + static int dib0070_release(struct dvb_frontend *fe) + { + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; + } + + static struct dvb_tuner_ops dib0070_ops = { + .info = { + .name = "DiBcom DiB0070", + .frequency_min = 45000000, + .frequency_max = 860000000, + .frequency_step = 1000, + }, + .release = dib0070_release, + + .init = dib0070_wakeup, + .sleep = dib0070_sleep, + .set_params = dib0070_tune_digital, + // .get_frequency = dib0070_get_frequency, + // .get_bandwidth = dib0070_get_bandwidth + }; + + struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) + { + struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); + if (state == NULL) + return NULL; + + state->cfg = cfg; + state->i2c = i2c; + state->fe = fe; + fe->tuner_priv = state; + + if (dib0070_reset(state) != 0) + goto free_mem; + + dib0070_wbd_calibration(state); + + printk(KERN_INFO "DiB0070: successfully identified\n"); + memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = state; + return fe; + + free_mem: + kfree(state); + fe->tuner_priv = NULL; + return NULL; + } + EXPORT_SYMBOL(dib0070_attach); + + MODULE_AUTHOR("Patrick Boettcher <pboettcher@xxxxxxxxx>"); + MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner"); + MODULE_LICENSE("GPL"); diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib0070.h linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib0070.h *** linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib0070.h Thu Jan 1 08:00:00 1970 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib0070.h Wed Oct 31 10:25:34 2007 *************** *** 0 **** --- 1,44 ---- + /* + * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. + * + * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) + * + * 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. + */ + #ifndef DIB0070_H + #define DIB0070_H + + struct dvb_frontend; + struct i2c_adapter; + + #define DEFAULT_DIB0070_I2C_ADDRESS 0x60 + + struct dib0070_config { + u8 i2c_address; + + /* tuner pins controlled externally */ + int (*reset) (struct dvb_frontend *, int); + int (*sleep) (struct dvb_frontend *, int); + + /* offset in kHz */ + int freq_offset_khz_uhf; + int freq_offset_khz_vhf; + + u8 osc_buffer_state; /* 0= normal, 1= tri-state */ + u32 clock_khz; + u8 clock_pad_drive; /* (Drive + 1) * 2mA */ + + u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */ + + u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */ + + u8 flip_chip; + }; + + extern struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); + extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); + extern u16 dib0070_wbd_offset(struct dvb_frontend *); + + #endif diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib7000m.c linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib7000m.c *** linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib7000m.c Wed Oct 31 15:53:43 2007 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib7000m.c Wed Nov 14 11:32:49 2007 *************** struct dib7000m_state { *** 40,46 **** --- 40,51 ---- struct dibx000_agc_config *current_agc; u32 timf; + u16 gpio_dir; + u16 gpio_val; + u16 revision; + struct dvb_frontend *next_fe; + int output_mode; }; enum dib7000m_power_mode { *************** static int dib7000m_reset_gpio(struct di *** 358,363 **** --- 363,390 ---- return 0; } + static int dib7000m_cfg_gpio(struct dib7000m_state *st, u8 num, u8 dir, u8 val) + { + st->gpio_dir = dib7000m_read_word(st, 773); + st->gpio_dir &= ~(1 << num); /* reset the direction bit */ + st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */ + dib7000m_write_word(st, 773, st->gpio_dir); + + st->gpio_val = dib7000m_read_word(st, 781); + st->gpio_val &= ~(1 << num); /* reset the direction bit */ + st->gpio_val |= (val & 0x01) << num; /* set the new value */ + dib7000m_write_word(st, 774, st->gpio_val); + + return 0; + } + + int dib7000m_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val) + { + struct dib7000m_state *state = demod->demodulator_priv; + return dib7000m_cfg_gpio(state, num, dir, val); + } + EXPORT_SYMBOL(dib7000m_set_gpio); + static int dib7000m_demod_reset(struct dib7000m_state *state) { dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); *************** static void dib7000m_set_channel(struct *** 579,584 **** --- 606,618 ---- else value |= 0; dib7000m_write_word(state, 266 + state->reg_offs, value); + if (state->output_mode == OUTMODE_MPEG2_FIFO) { + dib7000m_write_word(state, 263 + state->reg_offs, 6); + dib7000m_write_word(state, 264 + state->reg_offs, 6); + } else if (state->output_mode == OUTMODE_DIVERSITY) { + dib7000m_write_word(state, 263 + state->reg_offs, 1); + dib7000m_write_word(state, 264 + state->reg_offs, 0); + } /* channel estimation fine configuration */ switch (ch->nqam) { *************** static int dib7000m_init(struct dvb_fron *** 863,868 **** --- 897,912 ---- return ret; } + static int dib7000m_init_links(struct dvb_frontend *demod) + { + int ret; + + do { + ret = dib7000m_init(demod); + } while ((demod = dib7000m_get_next_frontend(demod)) != NULL); + return ret; + } + static int dib7000m_sleep(struct dvb_frontend *demod) { struct dib7000m_state *st = demod->demodulator_priv; *************** static int dib7000m_sleep(struct dvb_fro *** 872,877 **** --- 916,931 ---- dib7000m_set_adc_state(st, DIBX000_ADC_OFF); } + static int dib7000m_sleep_links(struct dvb_frontend *demod) + { + int ret; + + do { + ret = dib7000m_sleep(demod); + } while ((demod = dib7000m_get_next_frontend(demod)) != NULL); + return ret; + } + static int dib7000m_identify(struct dib7000m_state *state) { u16 value; *************** static int dib7000m_get_frontend(struct *** 962,967 **** --- 1016,1032 ---- return 0; } + static int dib7000m_get_frontend_links(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) + { + int ret; + + do { + ret = dib7000m_get_frontend(fe, fep); + } while ((fe = dib7000m_get_next_frontend(fe)) != NULL); + return ret; + } + static int dib7000m_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { *************** static int dib7000m_set_frontend(struct *** 998,1008 **** } /* make this a config parameter */ ! dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO); return dib7000m_tune(fe, &ch); } static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat) { struct dib7000m_state *state = fe->demodulator_priv; --- 1063,1084 ---- } /* make this a config parameter */ ! dib7000m_set_output_mode(state, state->output_mode); return dib7000m_tune(fe, &ch); } + static int dib7000m_set_frontend_links(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) + { + int ret; + + do { + ret = dib7000m_set_frontend(fe, fep); + } while ((fe = dib7000m_get_next_frontend(fe)) != NULL); + return ret; + } + static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat) { struct dib7000m_state *state = fe->demodulator_priv; *************** static int dib7000m_read_status(struct d *** 1018,1024 **** *stat |= FE_HAS_VITERBI; if (lock & 0x0010) *stat |= FE_HAS_SYNC; ! if (lock & 0x0008) *stat |= FE_HAS_LOCK; return 0; --- 1094,1100 ---- *stat |= FE_HAS_VITERBI; if (lock & 0x0010) *stat |= FE_HAS_SYNC; ! if (lock & 0x0008 || lock & 0x0001) *stat |= FE_HAS_LOCK; return 0; *************** static void dib7000m_release(struct dvb_ *** 1065,1070 **** --- 1141,1153 ---- kfree(st); } + static void dib7000m_release_links(struct dvb_frontend *demod) + { + do { + dib7000m_release(demod); + } while ((demod = dib7000m_get_next_frontend(demod)) != NULL); + } + struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) { struct dib7000m_state *st = demod->demodulator_priv; *************** int dib7000m_i2c_enumeration(struct i2c_ *** 1118,1125 **** } EXPORT_SYMBOL(dib7000m_i2c_enumeration); static struct dvb_frontend_ops dib7000m_ops; ! struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg) { struct dvb_frontend *demod; struct dib7000m_state *st; --- 1201,1214 ---- } EXPORT_SYMBOL(dib7000m_i2c_enumeration); + struct dvb_frontend * dib7000m_get_next_frontend(struct dvb_frontend *fe) { + struct dib7000m_state *st = (struct dib7000m_state *)fe->demodulator_priv; + return st->next_fe; + } + EXPORT_SYMBOL(dib7000m_get_next_frontend); + static struct dvb_frontend_ops dib7000m_ops; ! struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg, struct dvb_frontend *fe, int mode) { struct dvb_frontend *demod; struct dib7000m_state *st; *************** struct dvb_frontend * dib7000m_attach(st *** 1130,1135 **** --- 1219,1226 ---- memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config)); st->i2c_adap = i2c_adap; st->i2c_addr = i2c_addr; + st->next_fe = fe; + st->output_mode = mode; demod = &st->demod; demod->demodulator_priv = st; *************** static struct dvb_frontend_ops dib7000m_ *** 1170,1183 **** FE_CAN_HIERARCHY_AUTO, }, ! .release = dib7000m_release, ! .init = dib7000m_init, ! .sleep = dib7000m_sleep, ! .set_frontend = dib7000m_set_frontend, .get_tune_settings = dib7000m_fe_get_tune_settings, ! .get_frontend = dib7000m_get_frontend, .read_status = dib7000m_read_status, .read_ber = dib7000m_read_ber, --- 1261,1274 ---- FE_CAN_HIERARCHY_AUTO, }, ! .release = dib7000m_release_links, ! .init = dib7000m_init_links, ! .sleep = dib7000m_sleep_links, ! .set_frontend = dib7000m_set_frontend_links, .get_tune_settings = dib7000m_fe_get_tune_settings, ! .get_frontend = dib7000m_get_frontend_links, .read_status = dib7000m_read_status, .read_ber = dib7000m_read_ber, diff -rpN linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib7000m.h linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib7000m.h *** linux-2.6.22.1.vallina/drivers/media/dvb/frontends/dib7000m.h Wed Jul 11 02:56:30 2007 --- linux-2.6.22.1.nim7070md/drivers/media/dvb/frontends/dib7000m.h Thu Nov 1 19:41:07 2007 *************** struct dib7000m_config { *** 38,48 **** #define DEFAULT_DIB7000M_I2C_ADDRESS 18 ! extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg); extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); /* TODO - extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val); extern INT dib7000m_enable_vbg_voltage(struct dibDemod *demod); extern void dib7000m_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff); extern USHORT dib7000m_get_current_agc_global(struct dibDemod *demod); --- 38,52 ---- #define DEFAULT_DIB7000M_I2C_ADDRESS 18 ! extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg, struct dvb_frontend *fe, int mode); ! extern int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000m_config cfg[]); ! extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); + extern int dib7000m_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); + + extern struct dvb_frontend * dib7000m_get_next_frontend(struct dvb_frontend *fe); /* TODO extern INT dib7000m_enable_vbg_voltage(struct dibDemod *demod); extern void dib7000m_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff); extern USHORT dib7000m_get_current_agc_global(struct dibDemod *demod);
_______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb