diff options
author | Patrick Boettcher <pboettcher@dibcom.fr> | 2006-10-18 07:34:16 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-10 05:51:03 -0500 |
commit | a75763ffff4175bd8c115c217a39fbf445612aae (patch) | |
tree | d3d77ecc41fd8ad1b9dcad81805a171da06f8496 /drivers/media/dvb/dvb-usb | |
parent | 8364681766cc18b948cf9d7bd46d1b92f343743b (diff) |
V4L/DVB (4772): Add support for DiBcom DiB7000PC
This patch contains support for the DiB7000PC-driver.
Signed-off-by: Francois KANOUNNIKOFF <fkanounnikoff@dibcom.fr>
Signed-off-by: Patrick Boettcher <pboettcher@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700.h | 5 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_core.c | 40 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_devices.c | 96 |
4 files changed, 129 insertions, 13 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index a0aeaf4bbb3..dfd53d5e792 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -69,6 +69,7 @@ config DVB_USB_DIBUSB_MC | |||
69 | config DVB_USB_DIB0700 | 69 | config DVB_USB_DIB0700 |
70 | tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" | 70 | tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" |
71 | depends on DVB_USB | 71 | depends on DVB_USB |
72 | select DVB_DIB7000P | ||
72 | select DVB_DIB7000M | 73 | select DVB_DIB7000M |
73 | select DVB_DIB3000MC | 74 | select DVB_DIB3000MC |
74 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | 75 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index ac84347f9d4..cda3adea24f 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
@@ -24,18 +24,23 @@ extern int dvb_usb_dib0700_debug; | |||
24 | #define REQUEST_I2C_WRITE 0x3 | 24 | #define REQUEST_I2C_WRITE 0x3 |
25 | #define REQUEST_POLL_RC 0x4 | 25 | #define REQUEST_POLL_RC 0x4 |
26 | #define REQUEST_JUMPRAM 0x8 | 26 | #define REQUEST_JUMPRAM 0x8 |
27 | #define REQUEST_SET_CLOCK 0xB | ||
27 | #define REQUEST_SET_GPIO 0xC | 28 | #define REQUEST_SET_GPIO 0xC |
28 | #define REQUEST_ENABLE_VIDEO 0xF | 29 | #define REQUEST_ENABLE_VIDEO 0xF |
29 | // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) | 30 | // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) |
30 | // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) | 31 | // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) |
31 | // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) | 32 | // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) |
33 | #define REQUEST_GET_VERSION 0x15 | ||
32 | 34 | ||
33 | struct dib0700_state { | 35 | struct dib0700_state { |
34 | u8 channel_state; | 36 | u8 channel_state; |
35 | u16 mt2060_if1[2]; | 37 | u16 mt2060_if1[2]; |
38 | |||
39 | u8 is_dib7000pc; | ||
36 | }; | 40 | }; |
37 | 41 | ||
38 | extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); | 42 | extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); |
43 | extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); | ||
39 | extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); | 44 | extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); |
40 | extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); | 45 | extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); |
41 | extern struct i2c_algorithm dib0700_i2c_algo; | 46 | extern struct i2c_algorithm dib0700_i2c_algo; |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index dca6c698566..6a4d150784a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -135,14 +135,46 @@ struct i2c_algorithm dib0700_i2c_algo = { | |||
135 | int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, | 135 | int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, |
136 | struct dvb_usb_device_description **desc, int *cold) | 136 | struct dvb_usb_device_description **desc, int *cold) |
137 | { | 137 | { |
138 | u8 buf[3] = { REQUEST_SET_GPIO, 4, (GPIO_IN << 7) | (0 << 6) }; // GPIO4 is save - used for I2C | 138 | u8 b[16]; |
139 | *cold = usb_control_msg(udev, usb_sndctrlpipe(udev,0), | 139 | s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), |
140 | buf[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, buf, 3, USB_CTRL_GET_TIMEOUT) != 3; | 140 | REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT); |
141 | |||
142 | deb_info("FW GET_VERSION length: %d\n",ret); | ||
143 | |||
144 | *cold = ret <= 0; | ||
141 | 145 | ||
142 | deb_info("cold: %d\n", *cold); | 146 | deb_info("cold: %d\n", *cold); |
143 | return 0; | 147 | return 0; |
144 | } | 148 | } |
145 | 149 | ||
150 | static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, | ||
151 | u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv, | ||
152 | u16 pll_loopdiv, u16 free_div, u16 dsuScaler) | ||
153 | { | ||
154 | u8 b[10]; | ||
155 | b[0] = REQUEST_SET_CLOCK; | ||
156 | b[1] = (en_pll << 7) | (pll_src << 6) | (pll_range << 5) | (clock_gpio3 << 4); | ||
157 | b[2] = (pll_prediv >> 8) & 0xff; // MSB | ||
158 | b[3] = pll_prediv & 0xff; // LSB | ||
159 | b[4] = (pll_loopdiv >> 8) & 0xff; // MSB | ||
160 | b[5] = pll_loopdiv & 0xff; // LSB | ||
161 | b[6] = (free_div >> 8) & 0xff; // MSB | ||
162 | b[7] = free_div & 0xff; // LSB | ||
163 | b[8] = (dsuScaler >> 8) & 0xff; // MSB | ||
164 | b[9] = dsuScaler & 0xff; // LSB | ||
165 | |||
166 | return dib0700_ctrl_wr(d, b, 10); | ||
167 | } | ||
168 | |||
169 | int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) | ||
170 | { | ||
171 | switch (clk_MHz) { | ||
172 | case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break; | ||
173 | default: return -EINVAL; | ||
174 | } | ||
175 | return 0; | ||
176 | } | ||
177 | |||
146 | static int dib0700_jumpram(struct usb_device *udev, u32 address) | 178 | static int dib0700_jumpram(struct usb_device *udev, u32 address) |
147 | { | 179 | { |
148 | int ret, actlen; | 180 | int ret, actlen; |
@@ -197,7 +229,7 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw | |||
197 | /* start the firmware */ | 229 | /* start the firmware */ |
198 | if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) { | 230 | if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) { |
199 | info("firmware started successfully."); | 231 | info("firmware started successfully."); |
200 | msleep(100); | 232 | msleep(500); |
201 | } | 233 | } |
202 | } else | 234 | } else |
203 | ret = -EIO; | 235 | ret = -EIO; |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 305dd35a102..c231a1e5204 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include "dib3000mc.h" | 11 | #include "dib3000mc.h" |
12 | #include "dib7000m.h" | 12 | #include "dib7000m.h" |
13 | #include "dib7000p.h" | ||
13 | #include "mt2060.h" | 14 | #include "mt2060.h" |
14 | 15 | ||
15 | static int force_lna_activation; | 16 | static int force_lna_activation; |
@@ -96,7 +97,7 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap) | |||
96 | } | 97 | } |
97 | 98 | ||
98 | /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ | 99 | /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ |
99 | static struct dibx000_agc_config stk7700p_dib7000m_agc_config = { | 100 | static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = { |
100 | BAND_UHF | BAND_VHF, // band_caps | 101 | BAND_UHF | BAND_VHF, // band_caps |
101 | 102 | ||
102 | /* 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, | 103 | /* 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, |
@@ -141,7 +142,52 @@ static struct dibx000_agc_config stk7700p_dib7000m_agc_config = { | |||
141 | }, | 142 | }, |
142 | }; | 143 | }; |
143 | 144 | ||
144 | static struct dibx000_bandwidth_config stk7700p_dib7000m_mt2060_config = { | 145 | static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = { |
146 | BAND_UHF | BAND_VHF, | ||
147 | |||
148 | /* 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, | ||
149 | * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ | ||
150 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup | ||
151 | |||
152 | 712, // inv_gain | ||
153 | 41, // time_stabiliz | ||
154 | |||
155 | 0, // alpha_level | ||
156 | 118, // thlock | ||
157 | |||
158 | 0, // wbd_inv | ||
159 | 4095, // wbd_ref | ||
160 | 0, // wbd_sel | ||
161 | 0, // wbd_alpha | ||
162 | |||
163 | 42598, // agc1_max | ||
164 | 16384, // agc1_min | ||
165 | 42598, // agc2_max | ||
166 | 0, // agc2_min | ||
167 | |||
168 | 0, // agc1_pt1 | ||
169 | 137, // agc1_pt2 | ||
170 | 255, // agc1_pt3 | ||
171 | |||
172 | 0, // agc1_slope1 | ||
173 | 255, // agc1_slope2 | ||
174 | |||
175 | 0, // agc2_pt1 | ||
176 | 0, // agc2_pt2 | ||
177 | |||
178 | 0, // agc2_slope1 | ||
179 | 41, // agc2_slope2 | ||
180 | |||
181 | 15, // alpha_mant | ||
182 | 25, // alpha_exp | ||
183 | |||
184 | 28, // beta_mant | ||
185 | 48, // beta_exp | ||
186 | |||
187 | 0, // perform_agc_softsplit | ||
188 | }; | ||
189 | |||
190 | static struct dibx000_bandwidth_config stk7700p_pll_config = { | ||
145 | 60000, 30000, // internal, sampling | 191 | 60000, 30000, // internal, sampling |
146 | 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass | 192 | 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass |
147 | 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo | 193 | 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo |
@@ -156,8 +202,19 @@ static struct dib7000m_config stk7700p_dib7000m_config = { | |||
156 | .quartz_direct = 1, | 202 | .quartz_direct = 1, |
157 | 203 | ||
158 | .agc_config_count = 1, | 204 | .agc_config_count = 1, |
159 | .agc = &stk7700p_dib7000m_agc_config, | 205 | .agc = &stk7700p_7000m_mt2060_agc_config, |
160 | .bw = &stk7700p_dib7000m_mt2060_config, | 206 | .bw = &stk7700p_pll_config, |
207 | |||
208 | .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, | ||
209 | .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, | ||
210 | .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS, | ||
211 | }; | ||
212 | |||
213 | static struct dib7000p_config stk7700p_dib7000p_config = { | ||
214 | .output_mpeg2_in_188_bytes = 1, | ||
215 | |||
216 | .agc = &stk7700p_7000p_mt2060_agc_config, | ||
217 | .bw = &stk7700p_pll_config, | ||
161 | 218 | ||
162 | .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, | 219 | .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, |
163 | .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, | 220 | .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, |
@@ -168,13 +225,28 @@ static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap) | |||
168 | { | 225 | { |
169 | struct dib0700_state *st = adap->dev->priv; | 226 | struct dib0700_state *st = adap->dev->priv; |
170 | /* unless there is no real power management in DVB - we leave the device on GPIO6 */ | 227 | /* unless there is no real power management in DVB - we leave the device on GPIO6 */ |
171 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10); | 228 | |
229 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
230 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50); | ||
231 | |||
172 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); | 232 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); |
233 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
234 | |||
173 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10); | 235 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10); |
174 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); | 236 | dib0700_ctrl_clock(adap->dev, 72, 1); |
237 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100); | ||
238 | |||
239 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
175 | 240 | ||
176 | st->mt2060_if1[0] = 1220; | 241 | st->mt2060_if1[0] = 1220; |
177 | return (adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config)) == NULL ? -ENODEV : 0; | 242 | |
243 | if (dib7000pc_detection(&adap->dev->i2c_adap)) { | ||
244 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); | ||
245 | st->is_dib7000pc = 1; | ||
246 | } else | ||
247 | adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); | ||
248 | |||
249 | return adap->fe == NULL ? -ENODEV : 0; | ||
178 | } | 250 | } |
179 | 251 | ||
180 | static struct mt2060_config stk7700p_mt2060_config = { | 252 | static struct mt2060_config stk7700p_mt2060_config = { |
@@ -184,8 +256,14 @@ static struct mt2060_config stk7700p_mt2060_config = { | |||
184 | static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) | 256 | static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) |
185 | { | 257 | { |
186 | struct dib0700_state *st = adap->dev->priv; | 258 | struct dib0700_state *st = adap->dev->priv; |
187 | struct i2c_adapter *tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); | 259 | struct i2c_adapter *tun_i2c; |
188 | return dvb_attach(mt2060_attach,adap->fe, tun_i2c, &stk7700p_mt2060_config, | 260 | |
261 | if (st->is_dib7000pc) | ||
262 | tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); | ||
263 | else | ||
264 | tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); | ||
265 | |||
266 | return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config, | ||
189 | st->mt2060_if1[0]) == NULL ? -ENODEV : 0; | 267 | st->mt2060_if1[0]) == NULL ? -ENODEV : 0; |
190 | } | 268 | } |
191 | 269 | ||