aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dib0070.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/dib0070.c')
-rw-r--r--drivers/media/dvb/frontends/dib0070.c654
1 files changed, 338 insertions, 316 deletions
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index 2be17b93e0bd..81860b2cfe98 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -49,21 +49,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
49#define DIB0070_P1G 0x03 49#define DIB0070_P1G 0x03
50#define DIB0070S_P1A 0x02 50#define DIB0070S_P1A 0x02
51 51
52enum frontend_tune_state {
53 CT_TUNER_START = 10,
54 CT_TUNER_STEP_0,
55 CT_TUNER_STEP_1,
56 CT_TUNER_STEP_2,
57 CT_TUNER_STEP_3,
58 CT_TUNER_STEP_4,
59 CT_TUNER_STEP_5,
60 CT_TUNER_STEP_6,
61 CT_TUNER_STEP_7,
62 CT_TUNER_STOP,
63};
64
65#define FE_CALLBACK_TIME_NEVER 0xffffffff
66
67struct dib0070_state { 52struct dib0070_state {
68 struct i2c_adapter *i2c; 53 struct i2c_adapter *i2c;
69 struct dvb_frontend *fe; 54 struct dvb_frontend *fe;
@@ -71,10 +56,10 @@ struct dib0070_state {
71 u16 wbd_ff_offset; 56 u16 wbd_ff_offset;
72 u8 revision; 57 u8 revision;
73 58
74 enum frontend_tune_state tune_state; 59 enum frontend_tune_state tune_state;
75 u32 current_rf; 60 u32 current_rf;
76 61
77 /* for the captrim binary search */ 62 /* for the captrim binary search */
78 s8 step; 63 s8 step;
79 u16 adc_diff; 64 u16 adc_diff;
80 65
@@ -85,7 +70,7 @@ struct dib0070_state {
85 const struct dib0070_tuning *current_tune_table_index; 70 const struct dib0070_tuning *current_tune_table_index;
86 const struct dib0070_lna_match *lna_match; 71 const struct dib0070_lna_match *lna_match;
87 72
88 u8 wbd_gain_current; 73 u8 wbd_gain_current;
89 u16 wbd_offset_3_3[2]; 74 u16 wbd_offset_3_3[2];
90}; 75};
91 76
@@ -93,8 +78,8 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
93{ 78{
94 u8 b[2]; 79 u8 b[2];
95 struct i2c_msg msg[2] = { 80 struct i2c_msg msg[2] = {
96 {.addr = state->cfg->i2c_address,.flags = 0,.buf = &reg,.len = 1}, 81 { .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
97 {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2}, 82 { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 },
98 }; 83 };
99 if (i2c_transfer(state->i2c, msg, 2) != 2) { 84 if (i2c_transfer(state->i2c, msg, 2) != 2) {
100 printk(KERN_WARNING "DiB0070 I2C read failed\n"); 85 printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -106,7 +91,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
106static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) 91static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
107{ 92{
108 u8 b[3] = { reg, val >> 8, val & 0xff }; 93 u8 b[3] = { reg, val >> 8, val & 0xff };
109 struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 }; 94 struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
110 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 95 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
111 printk(KERN_WARNING "DiB0070 I2C write failed\n"); 96 printk(KERN_WARNING "DiB0070 I2C write failed\n");
112 return -EREMOTEIO; 97 return -EREMOTEIO;
@@ -124,30 +109,30 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
124 109
125static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) 110static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
126{ 111{
127 struct dib0070_state *state = fe->tuner_priv; 112 struct dib0070_state *state = fe->tuner_priv;
128 u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; 113 u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
129 114
130 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000) 115 if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
131 tmp |= (0 << 14); 116 tmp |= (0 << 14);
132 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000) 117 else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
133 tmp |= (1 << 14); 118 tmp |= (1 << 14);
134 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000) 119 else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
135 tmp |= (2 << 14); 120 tmp |= (2 << 14);
136 else 121 else
137 tmp |= (3 << 14); 122 tmp |= (3 << 14);
138 123
139 dib0070_write_reg(state, 0x02, tmp); 124 dib0070_write_reg(state, 0x02, tmp);
140 125
141 /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */ 126 /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
142 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) { 127 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
143 u16 value = dib0070_read_reg(state, 0x17); 128 u16 value = dib0070_read_reg(state, 0x17);
144 129
145 dib0070_write_reg(state, 0x17, value & 0xfffc); 130 dib0070_write_reg(state, 0x17, value & 0xfffc);
146 tmp = dib0070_read_reg(state, 0x01) & 0x01ff; 131 tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
147 dib0070_write_reg(state, 0x01, tmp | (60 << 9)); 132 dib0070_write_reg(state, 0x01, tmp | (60 << 9));
148 133
149 dib0070_write_reg(state, 0x17, value); 134 dib0070_write_reg(state, 0x17, value);
150 } 135 }
151 return 0; 136 return 0;
152} 137}
153 138
@@ -160,14 +145,14 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
160 if (*tune_state == CT_TUNER_STEP_0) { 145 if (*tune_state == CT_TUNER_STEP_0) {
161 146
162 dib0070_write_reg(state, 0x0f, 0xed10); 147 dib0070_write_reg(state, 0x0f, 0xed10);
163 dib0070_write_reg(state, 0x17, 0x0034); 148 dib0070_write_reg(state, 0x17, 0x0034);
164 149
165 dib0070_write_reg(state, 0x18, 0x0032); 150 dib0070_write_reg(state, 0x18, 0x0032);
166 state->step = state->captrim = state->fcaptrim = 64; 151 state->step = state->captrim = state->fcaptrim = 64;
167 state->adc_diff = 3000; 152 state->adc_diff = 3000;
168 ret = 20; 153 ret = 20;
169 154
170 *tune_state = CT_TUNER_STEP_1; 155 *tune_state = CT_TUNER_STEP_1;
171 } else if (*tune_state == CT_TUNER_STEP_1) { 156 } else if (*tune_state == CT_TUNER_STEP_1) {
172 state->step /= 2; 157 state->step /= 2;
173 dib0070_write_reg(state, 0x14, state->lo4 | state->captrim); 158 dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
@@ -178,7 +163,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
178 163
179 adc = dib0070_read_reg(state, 0x19); 164 adc = dib0070_read_reg(state, 0x19);
180 165
181 dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024); 166 dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
182 167
183 if (adc >= 400) { 168 if (adc >= 400) {
184 adc -= 400; 169 adc -= 400;
@@ -189,10 +174,12 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
189 } 174 }
190 175
191 if (adc < state->adc_diff) { 176 if (adc < state->adc_diff) {
192 dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff); 177 dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
193 state->adc_diff = adc; 178 state->adc_diff = adc;
194 state->fcaptrim = state->captrim; 179 state->fcaptrim = state->captrim;
195 180
181
182
196 } 183 }
197 state->captrim += (step_sign * state->step); 184 state->captrim += (step_sign * state->step);
198 185
@@ -213,8 +200,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
213static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt) 200static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
214{ 201{
215 struct dib0070_state *state = fe->tuner_priv; 202 struct dib0070_state *state = fe->tuner_priv;
216 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); 203 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
217 dprintk("CTRL_LO5: 0x%x", lo5); 204 dprintk( "CTRL_LO5: 0x%x", lo5);
218 return dib0070_write_reg(state, 0x15, lo5); 205 return dib0070_write_reg(state, 0x15, lo5);
219} 206}
220 207
@@ -227,171 +214,175 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
227 dib0070_write_reg(state, 0x1a, 0x0000); 214 dib0070_write_reg(state, 0x1a, 0x0000);
228 } else { 215 } else {
229 dib0070_write_reg(state, 0x1b, 0x4112); 216 dib0070_write_reg(state, 0x1b, 0x4112);
230 if (state->cfg->vga_filter != 0) { 217 if (state->cfg->vga_filter != 0) {
231 dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); 218 dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
232 dprintk("vga filter register is set to %x", state->cfg->vga_filter); 219 dprintk( "vga filter register is set to %x", state->cfg->vga_filter);
233 } else 220 } else
234 dib0070_write_reg(state, 0x1a, 0x0009); 221 dib0070_write_reg(state, 0x1a, 0x0009);
235 } 222 }
236} 223}
237 224
238EXPORT_SYMBOL(dib0070_ctrl_agc_filter); 225EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
239struct dib0070_tuning { 226struct dib0070_tuning {
240 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 227 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
241 u8 switch_trim; 228 u8 switch_trim;
242 u8 vco_band; 229 u8 vco_band;
243 u8 hfdiv; 230 u8 hfdiv;
244 u8 vco_multi; 231 u8 vco_multi;
245 u8 presc; 232 u8 presc;
246 u8 wbdmux; 233 u8 wbdmux;
247 u16 tuner_enable; 234 u16 tuner_enable;
248}; 235};
249 236
250struct dib0070_lna_match { 237struct dib0070_lna_match {
251 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 238 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
252 u8 lna_band; 239 u8 lna_band;
253}; 240};
254 241
255static const struct dib0070_tuning dib0070s_tuning_table[] = { 242static const struct dib0070_tuning dib0070s_tuning_table[] = {
256 {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */ 243 { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
257 {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800}, 244 { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
258 {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800}, 245 { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
259 {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */ 246 { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
260 {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, 247 { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
261 {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, 248 { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
262 {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */ 249 { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
263}; 250};
264 251
265static const struct dib0070_tuning dib0070_tuning_table[] = { 252static const struct dib0070_tuning dib0070_tuning_table[] = {
266 {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */ 253 { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
267 {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */ 254 { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
268 {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000}, 255 { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
269 {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000}, 256 { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
270 {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */ 257 { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
271 {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800}, 258 { 699999, 2, 0 ,1, 4, 2, 2, 0x4000 | 0x0800 },
272 {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800}, 259 { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 },
273 {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */ 260 { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
274}; 261};
275 262
276static const struct dib0070_lna_match dib0070_lna_flip_chip[] = { 263static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
277 {180000, 0}, /* VHF */ 264 { 180000, 0 }, /* VHF */
278 {188000, 1}, 265 { 188000, 1 },
279 {196400, 2}, 266 { 196400, 2 },
280 {250000, 3}, 267 { 250000, 3 },
281 {550000, 0}, /* UHF */ 268 { 550000, 0 }, /* UHF */
282 {590000, 1}, 269 { 590000, 1 },
283 {666000, 3}, 270 { 666000, 3 },
284 {864000, 5}, 271 { 864000, 5 },
285 {1500000, 0}, /* LBAND or everything higher than UHF */ 272 { 1500000, 0 }, /* LBAND or everything higher than UHF */
286 {1600000, 1}, 273 { 1600000, 1 },
287 {2000000, 3}, 274 { 2000000, 3 },
288 {0xffffffff, 7}, 275 { 0xffffffff, 7 },
289}; 276};
290 277
291static const struct dib0070_lna_match dib0070_lna[] = { 278static const struct dib0070_lna_match dib0070_lna[] = {
292 {180000, 0}, /* VHF */ 279 { 180000, 0 }, /* VHF */
293 {188000, 1}, 280 { 188000, 1 },
294 {196400, 2}, 281 { 196400, 2 },
295 {250000, 3}, 282 { 250000, 3 },
296 {550000, 2}, /* UHF */ 283 { 550000, 2 }, /* UHF */
297 {650000, 3}, 284 { 650000, 3 },
298 {750000, 5}, 285 { 750000, 5 },
299 {850000, 6}, 286 { 850000, 6 },
300 {864000, 7}, 287 { 864000, 7 },
301 {1500000, 0}, /* LBAND or everything higher than UHF */ 288 { 1500000, 0 }, /* LBAND or everything higher than UHF */
302 {1600000, 1}, 289 { 1600000, 1 },
303 {2000000, 3}, 290 { 2000000, 3 },
304 {0xffffffff, 7}, 291 { 0xffffffff, 7 },
305}; 292};
306 293
307#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 294#define LPF 100 // define for the loop filter 100kHz by default 16-07-06
308static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) 295static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
309{ 296{
310 struct dib0070_state *state = fe->tuner_priv; 297 struct dib0070_state *state = fe->tuner_priv;
311 298
312 const struct dib0070_tuning *tune; 299 const struct dib0070_tuning *tune;
313 const struct dib0070_lna_match *lna_match; 300 const struct dib0070_lna_match *lna_match;
314 301
315 enum frontend_tune_state *tune_state = &state->tune_state; 302 enum frontend_tune_state *tune_state = &state->tune_state;
316 int ret = 10; /* 1ms is the default delay most of the time */ 303 int ret = 10; /* 1ms is the default delay most of the time */
317 304
318 u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); 305 u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
319 u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf); 306 u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
320 307
321#ifdef CONFIG_SYS_ISDBT 308#ifdef CONFIG_SYS_ISDBT
322 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) 309 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
323 if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) 310 if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
324 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) 311 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
325 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 312 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
326 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2))) 313 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
327 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 314 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
328 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))) 315 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
329 freq += 850; 316 freq += 850;
330#endif 317#endif
318 if (state->current_rf != freq) {
319
320 switch (state->revision) {
321 case DIB0070S_P1A:
322 tune = dib0070s_tuning_table;
323 lna_match = dib0070_lna;
324 break;
325 default:
326 tune = dib0070_tuning_table;
327 if (state->cfg->flip_chip)
328 lna_match = dib0070_lna_flip_chip;
329 else
330 lna_match = dib0070_lna;
331 break;
332 }
333 while (freq > tune->max_freq) /* find the right one */
334 tune++;
335 while (freq > lna_match->max_freq) /* find the right one */
336 lna_match++;
337
338 state->current_tune_table_index = tune;
339 state->lna_match = lna_match;
340 }
341
342 if (*tune_state == CT_TUNER_START) {
343 dprintk( "Tuning for Band: %hd (%d kHz)", band, freq);
331 if (state->current_rf != freq) { 344 if (state->current_rf != freq) {
345 u8 REFDIV;
346 u32 FBDiv, Rest, FREF, VCOF_kHz;
347 u8 Den;
332 348
333 switch (state->revision) { 349 state->current_rf = freq;
334 case DIB0070S_P1A: 350 state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
335 tune = dib0070s_tuning_table;
336 lna_match = dib0070_lna;
337 break;
338 default:
339 tune = dib0070_tuning_table;
340 if (state->cfg->flip_chip)
341 lna_match = dib0070_lna_flip_chip;
342 else
343 lna_match = dib0070_lna;
344 break;
345 }
346 while (freq > tune->max_freq) /* find the right one */
347 tune++;
348 while (freq > lna_match->max_freq) /* find the right one */
349 lna_match++;
350 351
351 state->current_tune_table_index = tune;
352 state->lna_match = lna_match;
353 }
354 352
355 if (*tune_state == CT_TUNER_START) { 353 dib0070_write_reg(state, 0x17, 0x30);
356 dprintk("Tuning for Band: %hd (%d kHz)", band, freq); 354
357 if (state->current_rf != freq) { 355
358 u8 REFDIV; 356 VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
359 u32 FBDiv, Rest, FREF, VCOF_kHz; 357
360 u8 Den; 358 switch (band) {
361 359 case BAND_VHF:
362 state->current_rf = freq; 360 REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
363 state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); 361 break;
364 362 case BAND_FM:
365 dib0070_write_reg(state, 0x17, 0x30); 363 REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
366 364 break;
367 VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; 365 default:
368 366 REFDIV = (u8) ( state->cfg->clock_khz / 10000);
369 switch (band) { 367 break;
370 case BAND_VHF: 368 }
371 REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); 369 FREF = state->cfg->clock_khz / REFDIV;
372 break; 370
373 case BAND_FM: 371
374 REFDIV = (u8) ((state->cfg->clock_khz) / 1000); 372
375 break; 373 switch (state->revision) {
376 default: 374 case DIB0070S_P1A:
377 REFDIV = (u8) (state->cfg->clock_khz / 10000); 375 FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
378 break; 376 Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
379 } 377 break;
380 FREF = state->cfg->clock_khz / REFDIV; 378
381 379 case DIB0070_P1G:
382 switch (state->revision) { 380 case DIB0070_P1F:
383 case DIB0070S_P1A: 381 default:
384 FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); 382 FBDiv = (freq / (FREF / 2));
385 Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; 383 Rest = 2 * freq - FBDiv * FREF;
386 break; 384 break;
387 385 }
388 case DIB0070_P1G:
389 case DIB0070_P1F:
390 default:
391 FBDiv = (freq / (FREF / 2));
392 Rest = 2 * freq - FBDiv * FREF;
393 break;
394 }
395 386
396 if (Rest < LPF) 387 if (Rest < LPF)
397 Rest = 0; 388 Rest = 0;
@@ -402,98 +393,102 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par
402 FBDiv += 1; 393 FBDiv += 1;
403 } else if (Rest > (FREF - 2 * LPF)) 394 } else if (Rest > (FREF - 2 * LPF))
404 Rest = FREF - 2 * LPF; 395 Rest = FREF - 2 * LPF;
405 Rest = (Rest * 6528) / (FREF / 10); 396 Rest = (Rest * 6528) / (FREF / 10);
406 397
407 Den = 1; 398 Den = 1;
408 if (Rest > 0) { 399 if (Rest > 0) {
409 state->lo4 |= (1 << 14) | (1 << 12); 400 state->lo4 |= (1 << 14) | (1 << 12);
410 Den = 255; 401 Den = 255;
411 } 402 }
412 403
413 dib0070_write_reg(state, 0x11, (u16) FBDiv);
414 dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
415 dib0070_write_reg(state, 0x13, (u16) Rest);
416 404
417 if (state->revision == DIB0070S_P1A) { 405 dib0070_write_reg(state, 0x11, (u16)FBDiv);
406 dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
407 dib0070_write_reg(state, 0x13, (u16) Rest);
418 408
419 if (band == BAND_SBAND) { 409 if (state->revision == DIB0070S_P1A) {
420 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); 410
421 dib0070_write_reg(state, 0x1d, 0xFFFF); 411 if (band == BAND_SBAND) {
422 } else 412 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
423 dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); 413 dib0070_write_reg(state, 0x1d,0xFFFF);
424 } 414 } else
415 dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
416 }
425 417
426 dib0070_write_reg(state, 0x20, 418 dib0070_write_reg(state, 0x20,
427 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); 419 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
428 420
429 dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); 421 dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF);
430 dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); 422 dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest);
431 dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); 423 dprintk( "Num: %hd, Den: %hd, SD: %hd",(u16) Rest, Den, (state->lo4 >> 12) & 0x1);
432 dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); 424 dprintk( "HFDIV code: %hd", state->current_tune_table_index->hfdiv);
433 dprintk("VCO = %hd", state->current_tune_table_index->vco_band); 425 dprintk( "VCO = %hd", state->current_tune_table_index->vco_band);
434 dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); 426 dprintk( "VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
435 427
436 *tune_state = CT_TUNER_STEP_0; 428 *tune_state = CT_TUNER_STEP_0;
437 } else { /* we are already tuned to this frequency - the configuration is correct */ 429 } else { /* we are already tuned to this frequency - the configuration is correct */
438 ret = 50; /* wakeup time */ 430 ret = 50; /* wakeup time */
439 *tune_state = CT_TUNER_STEP_5; 431 *tune_state = CT_TUNER_STEP_5;
440 } 432 }
441 } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { 433 } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
442 434
443 ret = dib0070_captrim(state, tune_state); 435 ret = dib0070_captrim(state, tune_state);
444 436
445 } else if (*tune_state == CT_TUNER_STEP_4) { 437 } else if (*tune_state == CT_TUNER_STEP_4) {
446 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; 438 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
447 if (tmp != NULL) { 439 if (tmp != NULL) {
448 while (freq / 1000 > tmp->freq) /* find the right one */ 440 while (freq/1000 > tmp->freq) /* find the right one */
449 tmp++; 441 tmp++;
450 dib0070_write_reg(state, 0x0f, 442 dib0070_write_reg(state, 0x0f,
451 (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state-> 443 (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
452 current_tune_table_index-> 444 current_tune_table_index->
453 wbdmux << 0)); 445 wbdmux << 0));
454 state->wbd_gain_current = tmp->wbd_gain_val; 446 state->wbd_gain_current = tmp->wbd_gain_val;
455 } else { 447 } else {
456 dib0070_write_reg(state, 0x0f, 448 dib0070_write_reg(state, 0x0f,
457 (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index-> 449 (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
458 wbdmux << 0)); 450 wbdmux << 0));
459 state->wbd_gain_current = 6; 451 state->wbd_gain_current = 6;
460 } 452 }
461 453
462 dib0070_write_reg(state, 0x06, 0x3fff); 454 dib0070_write_reg(state, 0x06, 0x3fff);
463 dib0070_write_reg(state, 0x07, 455 dib0070_write_reg(state, 0x07,
464 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0)); 456 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
465 dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127)); 457 dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
466 dib0070_write_reg(state, 0x0d, 0x0d80); 458 dib0070_write_reg(state, 0x0d, 0x0d80);
467 459
468 dib0070_write_reg(state, 0x18, 0x07ff);
469 dib0070_write_reg(state, 0x17, 0x0033);
470 460
471 *tune_state = CT_TUNER_STEP_5; 461 dib0070_write_reg(state, 0x18, 0x07ff);
472 } else if (*tune_state == CT_TUNER_STEP_5) { 462 dib0070_write_reg(state, 0x17, 0x0033);
473 dib0070_set_bandwidth(fe, ch); 463
474 *tune_state = CT_TUNER_STOP; 464
475 } else { 465 *tune_state = CT_TUNER_STEP_5;
476 ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ 466 } else if (*tune_state == CT_TUNER_STEP_5) {
477 } 467 dib0070_set_bandwidth(fe, ch);
478 return ret; 468 *tune_state = CT_TUNER_STOP;
469 } else {
470 ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
471 }
472 return ret;
479} 473}
480 474
475
481static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) 476static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
482{ 477{
483 struct dib0070_state *state = fe->tuner_priv; 478 struct dib0070_state *state = fe->tuner_priv;
484 uint32_t ret; 479 uint32_t ret;
485 480
486 state->tune_state = CT_TUNER_START; 481 state->tune_state = CT_TUNER_START;
487 482
488 do { 483 do {
489 ret = dib0070_tune_digital(fe, p); 484 ret = dib0070_tune_digital(fe, p);
490 if (ret != FE_CALLBACK_TIME_NEVER) 485 if (ret != FE_CALLBACK_TIME_NEVER)
491 msleep(ret / 10); 486 msleep(ret/10);
492 else 487 else
493 break; 488 break;
494 } while (state->tune_state != CT_TUNER_STOP); 489 } while (state->tune_state != CT_TUNER_STOP);
495 490
496 return 0; 491 return 0;
497} 492}
498 493
499static int dib0070_wakeup(struct dvb_frontend *fe) 494static int dib0070_wakeup(struct dvb_frontend *fe)
@@ -512,92 +507,111 @@ static int dib0070_sleep(struct dvb_frontend *fe)
512 return 0; 507 return 0;
513} 508}
514 509
515static const u16 dib0070_p1f_defaults[] = { 510u8 dib0070_get_rf_output(struct dvb_frontend *fe)
511{
512 struct dib0070_state *state = fe->tuner_priv;
513 return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
514}
515
516EXPORT_SYMBOL(dib0070_get_rf_output);
517int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
518{
519 struct dib0070_state *state = fe->tuner_priv;
520 u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
521 if (no > 3) no = 3;
522 if (no < 1) no = 1;
523 return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
524}
525
526EXPORT_SYMBOL(dib0070_set_rf_output);
527static const u16 dib0070_p1f_defaults[] =
528
529{
516 7, 0x02, 530 7, 0x02,
517 0x0008, 531 0x0008,
518 0x0000, 532 0x0000,
519 0x0000, 533 0x0000,
520 0x0000, 534 0x0000,
521 0x0000, 535 0x0000,
522 0x0002, 536 0x0002,
523 0x0100, 537 0x0100,
524 538
525 3, 0x0d, 539 3, 0x0d,
526 0x0d80, 540 0x0d80,
527 0x0001, 541 0x0001,
528 0x0000, 542 0x0000,
529 543
530 4, 0x11, 544 4, 0x11,
531 0x0000, 545 0x0000,
532 0x0103, 546 0x0103,
533 0x0000, 547 0x0000,
534 0x0000, 548 0x0000,
535 549
536 3, 0x16, 550 3, 0x16,
537 0x0004 | 0x0040, 551 0x0004 | 0x0040,
538 0x0030, 552 0x0030,
539 0x07ff, 553 0x07ff,
540 554
541 6, 0x1b, 555 6, 0x1b,
542 0x4112, 556 0x4112,
543 0xff00, 557 0xff00,
544 0xc07f, 558 0xc07f,
545 0x0000, 559 0x0000,
546 0x0180, 560 0x0180,
547 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, 561 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
548 562
549 0, 563 0,
550}; 564};
551 565
552static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain) 566static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
553{ 567{
554 u16 tuner_en = dib0070_read_reg(state, 0x20); 568 u16 tuner_en = dib0070_read_reg(state, 0x20);
555 u16 offset; 569 u16 offset;
556 570
557 dib0070_write_reg(state, 0x18, 0x07ff); 571 dib0070_write_reg(state, 0x18, 0x07ff);
558 dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); 572 dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
559 dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0)); 573 dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
560 msleep(9); 574 msleep(9);
561 offset = dib0070_read_reg(state, 0x19); 575 offset = dib0070_read_reg(state, 0x19);
562 dib0070_write_reg(state, 0x20, tuner_en); 576 dib0070_write_reg(state, 0x20, tuner_en);
563 return offset; 577 return offset;
564} 578}
565 579
566static void dib0070_wbd_offset_calibration(struct dib0070_state *state) 580static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
567{ 581{
568 u8 gain; 582 u8 gain;
569 for (gain = 6; gain < 8; gain++) { 583 for (gain = 6; gain < 8; gain++) {
570 state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); 584 state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
571 dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]); 585 dprintk( "Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
572 } 586 }
573} 587}
574 588
575u16 dib0070_wbd_offset(struct dvb_frontend *fe) 589u16 dib0070_wbd_offset(struct dvb_frontend *fe)
576{ 590{
577 struct dib0070_state *state = fe->tuner_priv; 591 struct dib0070_state *state = fe->tuner_priv;
578 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; 592 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
579 u32 freq = fe->dtv_property_cache.frequency / 1000; 593 u32 freq = fe->dtv_property_cache.frequency/1000;
580 594
581 if (tmp != NULL) { 595 if (tmp != NULL) {
582 while (freq / 1000 > tmp->freq) /* find the right one */ 596 while (freq/1000 > tmp->freq) /* find the right one */
583 tmp++; 597 tmp++;
584 state->wbd_gain_current = tmp->wbd_gain_val; 598 state->wbd_gain_current = tmp->wbd_gain_val;
585 } else 599 } else
586 state->wbd_gain_current = 6; 600 state->wbd_gain_current = 6;
587 601
588 return state->wbd_offset_3_3[state->wbd_gain_current - 6]; 602 return state->wbd_offset_3_3[state->wbd_gain_current - 6];
589} 603}
590
591EXPORT_SYMBOL(dib0070_wbd_offset); 604EXPORT_SYMBOL(dib0070_wbd_offset);
592 605
593#define pgm_read_word(w) (*w) 606#define pgm_read_word(w) (*w)
594static int dib0070_reset(struct dvb_frontend *fe) 607static int dib0070_reset(struct dvb_frontend *fe)
595{ 608{
596 struct dib0070_state *state = fe->tuner_priv; 609 struct dib0070_state *state = fe->tuner_priv;
597 u16 l, r, *n; 610 u16 l, r, *n;
598 611
599 HARD_RESET(state); 612 HARD_RESET(state);
600 613
614
601#ifndef FORCE_SBAND_TUNER 615#ifndef FORCE_SBAND_TUNER
602 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) 616 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
603 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; 617 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
@@ -605,13 +619,13 @@ static int dib0070_reset(struct dvb_frontend *fe)
605#else 619#else
606#warning forcing SBAND 620#warning forcing SBAND
607#endif 621#endif
608 state->revision = DIB0070S_P1A; 622 state->revision = DIB0070S_P1A;
609 623
610 /* P1F or not */ 624 /* P1F or not */
611 dprintk("Revision: %x", state->revision); 625 dprintk( "Revision: %x", state->revision);
612 626
613 if (state->revision == DIB0070_P1D) { 627 if (state->revision == DIB0070_P1D) {
614 dprintk("Error: this driver is not to be used meant for P1D or earlier"); 628 dprintk( "Error: this driver is not to be used meant for P1D or earlier");
615 return -EINVAL; 629 return -EINVAL;
616 } 630 }
617 631
@@ -620,7 +634,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
620 while (l) { 634 while (l) {
621 r = pgm_read_word(n++); 635 r = pgm_read_word(n++);
622 do { 636 do {
623 dib0070_write_reg(state, (u8) r, pgm_read_word(n++)); 637 dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
624 r++; 638 r++;
625 } while (--l); 639 } while (--l);
626 l = pgm_read_word(n++); 640 l = pgm_read_word(n++);
@@ -633,6 +647,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
633 else 647 else
634 r = 2; 648 r = 2;
635 649
650
636 r |= state->cfg->osc_buffer_state << 3; 651 r |= state->cfg->osc_buffer_state << 3;
637 652
638 dib0070_write_reg(state, 0x10, r); 653 dib0070_write_reg(state, 0x10, r);
@@ -643,16 +658,24 @@ static int dib0070_reset(struct dvb_frontend *fe)
643 dib0070_write_reg(state, 0x02, r | (1 << 5)); 658 dib0070_write_reg(state, 0x02, r | (1 << 5));
644 } 659 }
645 660
646 if (state->revision == DIB0070S_P1A) 661 if (state->revision == DIB0070S_P1A)
647 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); 662 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
648 else 663 else
649 dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter); 664 dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
650 665
651 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); 666 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
652 667
653 dib0070_wbd_offset_calibration(state); 668 dib0070_wbd_offset_calibration(state);
654 669
655 return 0; 670 return 0;
671}
672
673static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
674{
675 struct dib0070_state *state = fe->tuner_priv;
676
677 *frequency = 1000 * state->current_rf;
678 return 0;
656} 679}
657 680
658static int dib0070_release(struct dvb_frontend *fe) 681static int dib0070_release(struct dvb_frontend *fe)
@@ -664,22 +687,22 @@ static int dib0070_release(struct dvb_frontend *fe)
664 687
665static const struct dvb_tuner_ops dib0070_ops = { 688static const struct dvb_tuner_ops dib0070_ops = {
666 .info = { 689 .info = {
667 .name = "DiBcom DiB0070", 690 .name = "DiBcom DiB0070",
668 .frequency_min = 45000000, 691 .frequency_min = 45000000,
669 .frequency_max = 860000000, 692 .frequency_max = 860000000,
670 .frequency_step = 1000, 693 .frequency_step = 1000,
671 }, 694 },
672 .release = dib0070_release, 695 .release = dib0070_release,
673 696
674 .init = dib0070_wakeup, 697 .init = dib0070_wakeup,
675 .sleep = dib0070_sleep, 698 .sleep = dib0070_sleep,
676 .set_params = dib0070_tune, 699 .set_params = dib0070_tune,
677 700
678// .get_frequency = dib0070_get_frequency, 701 .get_frequency = dib0070_get_frequency,
679// .get_bandwidth = dib0070_get_bandwidth 702// .get_bandwidth = dib0070_get_bandwidth
680}; 703};
681 704
682struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) 705struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
683{ 706{
684 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); 707 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
685 if (state == NULL) 708 if (state == NULL)
@@ -687,7 +710,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
687 710
688 state->cfg = cfg; 711 state->cfg = cfg;
689 state->i2c = i2c; 712 state->i2c = i2c;
690 state->fe = fe; 713 state->fe = fe;
691 fe->tuner_priv = state; 714 fe->tuner_priv = state;
692 715
693 if (dib0070_reset(fe) != 0) 716 if (dib0070_reset(fe) != 0)
@@ -699,12 +722,11 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
699 fe->tuner_priv = state; 722 fe->tuner_priv = state;
700 return fe; 723 return fe;
701 724
702 free_mem: 725free_mem:
703 kfree(state); 726 kfree(state);
704 fe->tuner_priv = NULL; 727 fe->tuner_priv = NULL;
705 return NULL; 728 return NULL;
706} 729}
707
708EXPORT_SYMBOL(dib0070_attach); 730EXPORT_SYMBOL(dib0070_attach);
709 731
710MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 732MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");